From b9aad1f15dc600e4dbe4c62d3fcced6363188ba3 Mon Sep 17 00:00:00 2001 From: zautrix Date: Sat, 26 Jun 2004 19:01:18 +0000 Subject: Initial revision --- (limited to 'microkde/kdeui/klistview.cpp') diff --git a/microkde/kdeui/klistview.cpp b/microkde/kdeui/klistview.cpp new file mode 100644 index 0000000..b53a88a --- a/dev/null +++ b/microkde/kdeui/klistview.cpp @@ -0,0 +1,2191 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 Reginald Stadlbauer + Copyright (C) 2000 Charles Samuels + Copyright (C) 2000 Peter Putzer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +//US #include +#include +//US #include +#include +#ifdef _WIN32_ +#define Q_WS_QWS +#endif +#ifndef _WIN32_ +#define private public +#include +#undef private +#endif +#include "klistview.h" +//US #include "klistviewlineedit.h" +#ifndef DESKTOP_VERSION +#include +#endif + +// /*US +class KListView::Tooltip : public QToolTip +{ +public: + Tooltip (KListView* parent, QToolTipGroup* group = 0L); + virtual ~Tooltip () {} + +protected: + // */ + /** + * Reimplemented from QToolTip for internal reasons. + */ + // /*US + virtual void maybeTip (const QPoint&); + +private: + KListView* mParent; +}; + +KListView::Tooltip::Tooltip (KListView* parent, QToolTipGroup* group) + : QToolTip (parent, group), + mParent (parent) +{ +} + +void KListView::Tooltip::maybeTip (const QPoint&) +{ + // FIXME +} +// */ + +class KListView::KListViewPrivate +{ +public: + KListViewPrivate (KListView* listview) + : pCurrentItem (0L), + autoSelectDelay(1), +//US dragDelay (KGlobalSettings::dndEventDelay()), + + dragDelay (10), +//US editor (new KListViewLineEdit (listview)), + cursorInExecuteArea(false), + bUseSingle(false), + bChangeCursorOverItem(false), + itemsMovable (true), + selectedBySimpleMove(false), + selectedUsingMouse(false), + showContextMenusOnPress(true), + itemsRenameable (false), + validDrag (false), + dragEnabled (false), + autoOpen (true), + dropVisualizer (true), + dropHighlighter (false), + createChildren (true), + pressedOnSelected (false), + wasShiftEvent (false), + fullWidth (false), + sortAscending(true), + tabRename(true), + sortColumn(0), + selectionDirection(0), + tooltipColumn (0), + selectionMode (Single), +//US contextMenuKey (KGlobalSettings::contextMenuKey()), +//US showContextMenusOnPress (KGlobalSettings::showContextMenusOnPress()), + mDropVisualizerWidth (4) + { + renameable += 0; +//US connect(editor, SIGNAL(done(QListViewItem*,int)), listview, SLOT(doneEditing(QListViewItem*,int))); + } + + ~KListViewPrivate () + { +//US delete editor; + } + + QListViewItem* pCurrentItem; + + QTimer autoSelect; + int autoSelectDelay; + + QTimer dragExpand; + QListViewItem* dragOverItem; + QPoint dragOverPoint; + + QPoint startDragPos; + int dragDelay; + +//US KListViewLineEdit *editor; + QValueList renameable; + + bool cursorInExecuteArea:1; + bool bUseSingle:1; + bool bChangeCursorOverItem:1; + bool itemsMovable:1; + bool selectedBySimpleMove : 1; + bool selectedUsingMouse:1; + bool itemsRenameable:1; + bool validDrag:1; + bool dragEnabled:1; + bool autoOpen:1; + bool dropVisualizer:1; + bool dropHighlighter:1; + bool createChildren:1; + bool pressedOnSelected:1; + bool wasShiftEvent:1; + bool fullWidth:1; + bool sortAscending:1; + bool tabRename:1; + + int sortColumn; + + //+1 means downwards (y increases, -1 means upwards, 0 means not selected), aleXXX + int selectionDirection; + int tooltipColumn; + + SelectionModeExt selectionMode; + int contextMenuKey; + bool showContextMenusOnPress; + + QRect mOldDropVisualizer; + int mDropVisualizerWidth; + QRect mOldDropHighlighter; + QListViewItem *afterItemDrop; + QListViewItem *parentItemDrop; + + QColor alternateBackground; +}; + +/*US +KListViewLineEdit::KListViewLineEdit(KListView *parent) + : KLineEdit(parent->viewport()), item(0), col(0), p(parent) +{ + setFrame( false ); + hide(); + connect( parent, SIGNAL( selectionChanged() ), SLOT( slotSelectionChanged() )); +} + +KListViewLineEdit::~KListViewLineEdit() +{ +} + +void KListViewLineEdit::load(QListViewItem *i, int c) +{ + item=i; + col=c; + + QRect rect(p->itemRect(i)); + setText(item->text(c)); + + int fieldX = rect.x() - 1; + int fieldW = p->columnWidth(col) + 2; + + int pos = p->header()->mapToIndex(col); + for ( int index = 0; index < pos; index++ ) + fieldX += p->columnWidth( p->header()->mapToSection( index )); + + if ( col == 0 ) { + int d = i->depth() + (p->rootIsDecorated() ? 1 : 0); + d *= p->treeStepSize(); + fieldX += d; + fieldW -= d; + } + + if ( i->pixmap( col ) ) {// add width of pixmap + int d = i->pixmap( col )->width(); + fieldX += d; + fieldW -= d; + } + + setGeometry(fieldX, rect.y() - 1, fieldW, rect.height() + 2); + show(); + setFocus(); +} +*/ +/* Helper functions to for + * tabOrderedRename functionality. + */ + +static int nextCol (KListView *pl, QListViewItem *pi, int start, int dir) +{ + if (pi) + { + // Find the next renameable column in the current row + for (; ((dir == +1) ? (start < pl->columns()) : (start >= 0)); start += dir) + if (pl->isRenameable(start)) + return start; + } + + return -1; +} + +static QListViewItem *prevItem (QListViewItem *pi) +{ + QListViewItem *pa = pi->itemAbove(); + + /* Does what the QListViewItem::previousSibling() + * of my dreams would do. + */ + if (pa && pa->parent() == pi->parent()) + return pa; + + return NULL; +} + +static QListViewItem *lastQChild (QListViewItem *pi) +{ + if (pi) + { + /* Since there's no QListViewItem::lastChild(). + * This finds the last sibling for the given + * item. + */ + for (QListViewItem *pt = pi->nextSibling(); pt; pt = pt->nextSibling()) + pi = pt; + } + + return pi; +} +/*US +void KListViewLineEdit::selectNextCell (QListViewItem *pitem, int column, bool forward) +{ + const int ncols = p->columns(); + const int dir = forward ? +1 : -1; + const int restart = forward ? 0 : (ncols - 1); + QListViewItem *top = (pitem && pitem->parent()) + ? pitem->parent()->firstChild() + : p->firstChild(); + QListViewItem *pi = pitem; + + terminate(); // Save current changes + + do + { +*/ + /* Check the rest of the current row for an editable column, + * if that fails, check the entire next/previous row. The + * last case goes back to the first item in the current branch + * or the last item in the current branch depending on the + * direction. + */ +/*US + if ((column = nextCol(p, pi, column + dir, dir)) != -1 || + (column = nextCol(p, (pi = (forward ? pi->nextSibling() : prevItem(pi))), restart, dir)) != -1 || + (column = nextCol(p, (pi = (forward ? top : lastQChild(pitem))), restart, dir)) != -1) + { + if (pi) + { + p->setCurrentItem(pi); // Calls terminate + p->rename(pi, column); +*/ + /* Some listviews may override rename() to + * prevent certain items from being renamed, + * if this is done, [m_]item will be NULL + * after the rename() call... try again. + */ +/*US + if (!item) + continue; + + break; + } + } + } + while (pi && !item); +} +*/ + +/*US +#ifdef KeyPress +#undef KeyPress +#endif + +bool KListViewLineEdit::event (QEvent *pe) +{ + if (pe->type() == QEvent::KeyPress) + { + QKeyEvent *k = (QKeyEvent *) pe; + + if ((k->key() == Qt::Key_Backtab || k->key() == Qt::Key_Tab) && + p->tabOrderedRenaming() && p->itemsRenameable() && + !(k->state() & ControlButton || k->state() & AltButton)) + { + selectNextCell(item, col, + (k->key() == Key_Tab && !(k->state() & ShiftButton))); + return true; + } + } + + return KLineEdit::event(pe); +} + +void KListViewLineEdit::keyPressEvent(QKeyEvent *e) +{ + if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter ) + terminate(true); + else if(e->key() == Qt::Key_Escape) + terminate(false); + else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Up) + { + terminate(true); + KLineEdit::keyPressEvent(e); + } + else + KLineEdit::keyPressEvent(e); +} + +void KListViewLineEdit::terminate() +{ + terminate(true); +} + +void KListViewLineEdit::terminate(bool commit) +{ + if ( item ) + { + //kdDebug() << "KListViewLineEdit::terminate " << commit << endl; + if (commit) + item->setText(col, text()); + int c=col; + QListViewItem *i=item; + col=0; + item=0; + hide(); // will call focusOutEvent, that's why we set item=0 before + emit done(i,c); + } +} + +void KListViewLineEdit::focusOutEvent(QFocusEvent *ev) +{ + QFocusEvent * focusEv = static_cast(ev); + // Don't let a RMB close the editor + if (focusEv->reason() != QFocusEvent::Popup && focusEv->reason() != QFocusEvent::ActiveWindow) + terminate(true); +} + +void KListViewLineEdit::paintEvent( QPaintEvent *e ) +{ + KLineEdit::paintEvent( e ); + + if ( !frame() ) { + QPainter p( this ); + p.setClipRegion( e->region() ); + p.drawRect( rect() ); + } +} + +// selection changed -> terminate. As our "item" can be already deleted, +// we can't call terminate(false), because that would emit done() with +// a dangling pointer to "item". +void KListViewLineEdit::slotSelectionChanged() +{ + item = 0; + col = 0; + hide(); +} +*/ + +KListView::KListView( QWidget *parent, const char *name ) + : QListView( parent, name ), + d (new KListViewPrivate (this)) +{ +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold ); +#endif +//US setDragAutoScroll(true); + + connect( this, SIGNAL( onViewport() ), + this, SLOT( slotOnViewport() ) ); + connect( this, SIGNAL( onItem( QListViewItem * ) ), + this, SLOT( slotOnItem( QListViewItem * ) ) ); + + connect (this, SIGNAL(contentsMoving(int,int)), + this, SLOT(cleanDropVisualizer())); + connect (this, SIGNAL(contentsMoving(int,int)), + this, SLOT(cleanItemHighlighter())); + +/*US + slotSettingsChanged(KApplication::SETTINGS_MOUSE); + + if (kapp) + { + connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) ); + kapp->addKipcEventMask( KIPC::SettingsChanged ); + } +*/ + slotSettingsChanged(1); //US do this to initialize the connections + + + connect(&d->autoSelect, SIGNAL( timeout() ), + this, SLOT( slotAutoSelect() ) ); + connect(&d->dragExpand, SIGNAL( timeout() ), + this, SLOT( slotDragExpand() ) ); + + // context menu handling + if (d->showContextMenusOnPress) + { + connect (this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)), + this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); + } + else + { + connect (this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)), + this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); + } + + connect (this, SIGNAL (menuShortCutPressed (KListView*, QListViewItem*)), + this, SLOT (emitContextMenu (KListView*, QListViewItem*))); + + + //qDebug("KListView::KListView make alternate color configurable"); +//US d->alternateBackground = KGlobalSettings::alternateBackgroundColor(); + d->alternateBackground = QColor(240, 240, 240); +} + + + +KListView::~KListView() +{ + delete d; +} + +bool KListView::isExecuteArea( const QPoint& point ) +{ + if ( itemAt( point ) ) + return isExecuteArea( point.x() ); + + return false; +} + +bool KListView::isExecuteArea( int x ) +{ + if( allColumnsShowFocus() ) + return true; + else { + int offset = 0; + int width = columnWidth( 0 ); + int pos = header()->mapToIndex( 0 ); + + for ( int index = 0; index < pos; index++ ) + offset += columnWidth( header()->mapToSection( index ) ); + + x += contentsX(); // in case of a horizontal scrollbar + return ( x > offset && x < ( offset + width ) ); + } +} + +void KListView::slotOnItem( QListViewItem *item ) +{ + QPoint vp = viewport()->mapFromGlobal( QCursor::pos() ); + if ( item && isExecuteArea( vp.x() ) && (d->autoSelectDelay > -1) && d->bUseSingle ) { + d->autoSelect.start( d->autoSelectDelay, true ); + d->pCurrentItem = item; + } +} + +void KListView::slotOnViewport() +{ + if ( d->bChangeCursorOverItem ) + viewport()->unsetCursor(); + + d->autoSelect.stop(); + d->pCurrentItem = 0L; +} + +void KListView::slotSettingsChanged(int category) +{ +qDebug("KListView::slotSettingsChanged has to be verified"); +/*US + + switch (category) + { + case KApplication::SETTINGS_MOUSE: + d->dragDelay = KGlobalSettings::dndEventDelay(); + d->bUseSingle = KGlobalSettings::singleClick(); + + disconnect(this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)), + this, SLOT (slotMouseButtonClicked (int, QListViewItem*, const QPoint &, int))); + + if( d->bUseSingle ) + connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)), + this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int))); + + d->bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon(); + d->autoSelectDelay = KGlobalSettings::autoSelectDelay(); + + if( !d->bUseSingle || !d->bChangeCursorOverItem ) + viewport()->unsetCursor(); + + break; + + case KApplication::SETTINGS_POPUPMENU: + d->contextMenuKey = KGlobalSettings::contextMenuKey (); + d->showContextMenusOnPress = KGlobalSettings::showContextMenusOnPress (); + + if (d->showContextMenusOnPress) + { + disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); + + connect(this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)), + this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); + } + else + { + disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); + + connect(this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)), + this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int))); + } + break; + + default: + break; + } +*/ + + if( d->bUseSingle ) + connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)), + this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int))); + +} + +void KListView::slotAutoSelect() +{ + // check that the item still exists + if( itemIndex( d->pCurrentItem ) == -1 ) + return; + + if (!isActiveWindow()) + { + d->autoSelect.stop(); + return; + } + + //Give this widget the keyboard focus. + if( !hasFocus() ) + setFocus(); + + QListViewItem* previousItem = currentItem(); + setCurrentItem( d->pCurrentItem ); + +#if 0 +#ifndef Q_WS_QWS + // FIXME(E): Implement for Qt Embedded + if( d->pCurrentItem ) { + //Shift pressed? + if( (keybstate & ShiftMask) ) { + bool block = signalsBlocked(); + blockSignals( true ); + + //No Ctrl? Then clear before! + if( !(keybstate & ControlMask) ) + clearSelection(); + + bool select = !d->pCurrentItem->isSelected(); + bool update = viewport()->isUpdatesEnabled(); + viewport()->setUpdatesEnabled( false ); + + bool down = previousItem->itemPos() < d->pCurrentItem->itemPos(); + QListViewItemIterator lit( down ? previousItem : d->pCurrentItem ); + for ( ; lit.current(); ++lit ) { + if ( down && lit.current() == d->pCurrentItem ) { + d->pCurrentItem->setSelected( select ); + break; + } + if ( !down && lit.current() == previousItem ) { + previousItem->setSelected( select ); + break; + } + lit.current()->setSelected( select ); + } + + blockSignals( block ); + viewport()->setUpdatesEnabled( update ); + triggerUpdate(); + + emit selectionChanged(); + + if( selectionMode() == QListView::Single ) + emit selectionChanged( d->pCurrentItem ); + } + else if( (keybstate & ControlMask) ) + setSelected( d->pCurrentItem, !d->pCurrentItem->isSelected() ); + else { + bool block = signalsBlocked(); + blockSignals( true ); + + if( !d->pCurrentItem->isSelected() ) + clearSelection(); + + blockSignals( block ); + + setSelected( d->pCurrentItem, true ); + } + } + else + kdDebug() << "KListView::slotAutoSelect: Thats not supposed to happen!!!!" << endl; +#endif +#endif +} + +void KListView::slotHeaderChanged() +{ + if (d->fullWidth && columns()) + { + int w = 0; + for (int i = 0; i < columns() - 1; ++i) w += columnWidth(i); + setColumnWidth( columns() - 1, viewport()->width() - w - 1 ); + } +} + +void KListView::emitExecute( QListViewItem *item, const QPoint &pos, int c ) +{ + if( isExecuteArea( viewport()->mapFromGlobal(pos) ) ) { + + // Double click mode ? + if ( !d->bUseSingle ) + { + emit executed( item ); + emit executed( item, pos, c ); + } + else + { +#if 0 +#ifndef Q_WS_QWS + // FIXME(E): Implement for Qt Embedded + Window root; + Window child; + int root_x, root_y, win_x, win_y; + uint keybstate; + XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child, + &root_x, &root_y, &win_x, &win_y, &keybstate ); + + d->autoSelect.stop(); + + //Dont emit executed if in SC mode and Shift or Ctrl are pressed + if( !( ((keybstate & ShiftMask) || (keybstate & ControlMask)) ) ) { + emit executed( item ); + emit executed( item, pos, c ); + } +#endif +#endif + } + } +} + +void KListView::focusInEvent( QFocusEvent *fe ) +{ + // kdDebug()<<"KListView::focusInEvent()"<selectedBySimpleMove) + && (d->selectionMode == FileManager) + && (fe->reason()!=QFocusEvent::Popup) + && (fe->reason()!=QFocusEvent::ActiveWindow) + && (currentItem()!=0)) + { + currentItem()->setSelected(true); + currentItem()->repaint(); + emit selectionChanged(); + }; +} + +void KListView::focusOutEvent( QFocusEvent *fe ) +{ + cleanDropVisualizer(); + cleanItemHighlighter(); + + d->autoSelect.stop(); + + if ((d->selectedBySimpleMove) + && (d->selectionMode == FileManager) + && (fe->reason()!=QFocusEvent::Popup) + && (fe->reason()!=QFocusEvent::ActiveWindow) + && (currentItem()!=0) +/*US && (!d->editor->isVisible()) */ + ) + { + currentItem()->setSelected(false); + currentItem()->repaint(); + emit selectionChanged(); + }; + + QListView::focusOutEvent( fe ); +} + +void KListView::leaveEvent( QEvent *e ) +{ + d->autoSelect.stop(); + + QListView::leaveEvent( e ); +} + +bool KListView::event( QEvent *e ) +{ + if (e->type() == QEvent::ApplicationPaletteChange) { +qDebug("KListView::event make alternate color configurable"); +//US d->alternateBackground=KGlobalSettings::alternateBackgroundColor(); + d->alternateBackground = QColor(240, 240, 240); + } + + return QListView::event(e); +} + +void KListView::contentsMousePressEvent( QMouseEvent *e ) +{ + if( (selectionModeExt() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) ) + { + bool block = signalsBlocked(); + blockSignals( true ); + + clearSelection(); + + blockSignals( block ); + } + else if ((selectionModeExt()==FileManager) && (d->selectedBySimpleMove)) + { + d->selectedBySimpleMove=false; + d->selectedUsingMouse=true; + if (currentItem()!=0) + { + currentItem()->setSelected(false); + currentItem()->repaint(); +// emit selectionChanged(); + }; + }; + + QPoint p( contentsToViewport( e->pos() ) ); + QListViewItem *at = itemAt (p); + + // true if the root decoration of the item "at" was clicked (i.e. the +/- sign) + bool rootDecoClicked = at + && ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) + + treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ) + && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) ); + + if (e->button() == LeftButton && !rootDecoClicked) + { + //Start a drag + d->startDragPos = e->pos(); + + if (at) + { + d->validDrag = true; + d->pressedOnSelected = at->isSelected(); + } + } + + QListView::contentsMousePressEvent( e ); +} + +void KListView::contentsMouseMoveEvent( QMouseEvent *e ) +{ + if (!dragEnabled() || d->startDragPos.isNull() || !d->validDrag) { + QListView::contentsMouseMoveEvent (e); + return; + } + + QPoint vp = contentsToViewport(e->pos()); + QListViewItem *item = itemAt( vp ); + + //do we process cursor changes at all? + if ( item && d->bChangeCursorOverItem && d->bUseSingle ) + { + //Cursor moved on a new item or in/out the execute area + if( (item != d->pCurrentItem) || + (isExecuteArea(vp) != d->cursorInExecuteArea) ) + { + d->cursorInExecuteArea = isExecuteArea(vp); +qDebug("KListView::contentsMouseMoveEvent drag&drop not supported yet"); +/*US + if( d->cursorInExecuteArea ) //cursor moved in execute area + viewport()->setCursor( KCursor::handCursor() ); + else //cursor moved out of execute area + viewport()->unsetCursor(); +*/ + } + } + + bool dragOn = dragEnabled(); + QPoint newPos = e->pos(); + if (dragOn && d->validDrag && + (newPos.x() > d->startDragPos.x()+d->dragDelay || + newPos.x() < d->startDragPos.x()-d->dragDelay || + newPos.y() > d->startDragPos.y()+d->dragDelay || + newPos.y() < d->startDragPos.y()-d->dragDelay)) + //(d->startDragPos - e->pos()).manhattanLength() > QApplication::startDragDistance()) + { + QListView::contentsMouseReleaseEvent( 0 ); + startDrag(); + d->startDragPos = QPoint(); + d->validDrag = false; + } +} + +void KListView::contentsMouseReleaseEvent( QMouseEvent *e ) +{ + if (e->button() == LeftButton) + { + // If the row was already selected, maybe we want to start an in-place editing + if ( d->pressedOnSelected && itemsRenameable() ) + { + QPoint p( contentsToViewport( e->pos() ) ); + QListViewItem *at = itemAt (p); + if ( at ) + { + // true if the root decoration of the item "at" was clicked (i.e. the +/- sign) + bool rootDecoClicked = + ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) + + treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ) + && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) ); + + if (!rootDecoClicked) + { + int col = header()->mapToLogical( header()->cellAt( p.x() ) ); + if ( d->renameable.contains(col) ) + rename(at, col); + } + } + } + + d->pressedOnSelected = false; + d->validDrag = false; + d->startDragPos = QPoint(); + } + QListView::contentsMouseReleaseEvent( e ); +} + +void KListView::contentsMouseDoubleClickEvent ( QMouseEvent *e ) +{ + // We don't want to call the parent method because it does setOpen, + // whereas we don't do it in single click mode... (David) + //QListView::contentsMouseDoubleClickEvent( e ); + + QPoint vp = contentsToViewport(e->pos()); + QListViewItem *item = itemAt( vp ); + emit QListView::doubleClicked( item ); // we do it now + + int col = item ? header()->mapToLogical( header()->cellAt( vp.x() ) ) : -1; + + if( item ) { + emit doubleClicked( item, e->globalPos(), col ); + + if( (e->button() == LeftButton) && !d->bUseSingle ) + emitExecute( item, e->globalPos(), col ); + } +} + +void KListView::slotMouseButtonClicked( int btn, QListViewItem *item, const QPoint &pos, int c ) +{ + if( (btn == LeftButton) && item ) + emitExecute(item, pos, c); +} + +void KListView::contentsDropEvent(QDropEvent* e) +{ +qDebug("KListView::contentsDropEvent drag&drop not supported yet"); +/*US + cleanDropVisualizer(); + cleanItemHighlighter(); + d->dragExpand.stop(); + + if (acceptDrag (e)) + { + e->acceptAction(); + QListViewItem *afterme; + QListViewItem *parent; + findDrop(e->pos(), parent, afterme); + + if (e->source() == viewport() && itemsMovable()) + movableDropEvent(parent, afterme); + else + { + + emit dropped(e, afterme); + emit dropped(this, e, afterme); + emit dropped(e, parent, afterme); + emit dropped(this, e, parent, afterme); + + } + } +*/ + +} + +void KListView::movableDropEvent (QListViewItem* parent, QListViewItem* afterme) +{ + QPtrList items, afterFirsts, afterNows; + QListViewItem *current=currentItem(); + bool hasMoved=false; + for (QListViewItem *i = firstChild(), *iNext=0; i != 0; i = iNext) + { + iNext=i->itemBelow(); + if (!i->isSelected()) + continue; + + // don't drop an item after itself, or else + // it moves to the top of the list + if (i==afterme) + continue; + + i->setSelected(false); + + QListViewItem *afterFirst = i->itemAbove(); + + if (!hasMoved) + { + emit aboutToMove(); + hasMoved=true; + } + + moveItem(i, parent, afterme); + + // ###### This should include the new parent !!! -> KDE 3.0 + // If you need this right now, have a look at keditbookmarks. + emit moved(i, afterFirst, afterme); + + items.append (i); + afterFirsts.append (afterFirst); + afterNows.append (afterme); + + afterme = i; + } + clearSelection(); + for (QListViewItem *i=items.first(); i != 0; i=items.next() ) + i->setSelected(true); + if (current) + setCurrentItem(current); + + emit moved(items,afterFirsts,afterNows); + + if (firstChild()) + emit moved(); +} + +void KListView::contentsDragMoveEvent(QDragMoveEvent *event) +{ +qDebug("KListView::contentsDropEvent drag&drop not supported yet"); +/*US + if (acceptDrag(event)) + { + event->acceptAction(); + //Clean up the view + + findDrop(event->pos(), d->parentItemDrop, d->afterItemDrop); + QPoint vp = contentsToViewport( event->pos() ); + QListViewItem *item = isExecuteArea( vp ) ? itemAt( vp ) : 0L; + + if ( item != d->dragOverItem ) + { + d->dragExpand.stop(); + d->dragOverItem = item; + d->dragOverPoint = vp; + if ( d->dragOverItem && d->dragOverItem->isExpandable() && !d->dragOverItem->isOpen() ) + d->dragExpand.start( QApplication::startDragTime(), true ); + } + if (dropVisualizer()) + { + QRect tmpRect = drawDropVisualizer(0, d->parentItemDrop, d->afterItemDrop); + if (tmpRect != d->mOldDropVisualizer) + { + cleanDropVisualizer(); + d->mOldDropVisualizer=tmpRect; + viewport()->repaint(tmpRect); + } + } + if (dropHighlighter()) + { + QRect tmpRect = drawItemHighlighter(0, d->afterItemDrop); + if (tmpRect != d->mOldDropHighlighter) + { + cleanItemHighlighter(); + d->mOldDropHighlighter=tmpRect; + viewport()->repaint(tmpRect); + } + } + } + else + event->ignore(); +*/ +} + +void KListView::slotDragExpand() +{ + if ( itemAt( d->dragOverPoint ) == d->dragOverItem ) + d->dragOverItem->setOpen( true ); +} + +void KListView::contentsDragLeaveEvent (QDragLeaveEvent*) +{ + d->dragExpand.stop(); + cleanDropVisualizer(); + cleanItemHighlighter(); +} + +void KListView::cleanDropVisualizer() +{ + if (d->mOldDropVisualizer.isValid()) + { + QRect rect=d->mOldDropVisualizer; + d->mOldDropVisualizer = QRect(); + viewport()->repaint(rect, true); + } +} + +int KListView::depthToPixels( int depth ) +{ + return treeStepSize() * ( depth + (rootIsDecorated() ? 1 : 0) ) + itemMargin(); +} + +void KListView::findDrop(const QPoint &pos, QListViewItem *&parent, QListViewItem *&after) +{ + QPoint p (contentsToViewport(pos)); + + // Get the position to put it in + QListViewItem *atpos = itemAt(p); + + QListViewItem *above; + if (!atpos) // put it at the end + above = lastItem(); + else + { + // Get the closest item before us ('atpos' or the one above, if any) + if (p.y() - itemRect(atpos).topLeft().y() < (atpos->height()/2)) + above = atpos->itemAbove(); + else + above = atpos; + } + + if (above) + { + // Now, we know we want to go after "above". But as a child or as a sibling ? + // We have to ask the "above" item if it accepts children. + if (above->isExpandable()) + { + // The mouse is sufficiently on the right ? - doesn't matter if 'above' has visible children + if (p.x() >= depthToPixels( above->depth() + 1 ) || + (above->isOpen() && above->childCount() > 0) ) + { + parent = above; + after = 0L; + return; + } + } + + // Ok, there's one more level of complexity. We may want to become a new + // sibling, but of an upper-level group, rather than the "above" item + QListViewItem * betterAbove = above->parent(); + QListViewItem * last = above; + while ( betterAbove ) + { + // We are allowed to become a sibling of "betterAbove" only if we are + // after its last child + if ( last->nextSibling() == 0 ) + { + if (p.x() < depthToPixels ( betterAbove->depth() + 1 )) + above = betterAbove; // store this one, but don't stop yet, there may be a better one + else + break; // not enough on the left, so stop + last = betterAbove; + betterAbove = betterAbove->parent(); // up one level + } else + break; // we're among the child of betterAbove, not after the last one + } + } + // set as sibling + after = above; + parent = after ? after->parent() : 0L ; +} + +QListViewItem* KListView::lastChild () const +{ + QListViewItem* lastchild = firstChild(); + + if (lastchild) + for (; lastchild->nextSibling(); lastchild = lastchild->nextSibling()); + + return lastchild; +} + +QListViewItem *KListView::lastItem() const +{ + QListViewItem* last = lastChild(); + + for (QListViewItemIterator it (last); it.current(); ++it) + last = it.current(); + + return last; +} + +KLineEdit *KListView::renameLineEdit() const +{ +//US return d->editor; +qDebug("KListView::renameLineEdit returns 0. Might crash"); +return 0; +} + +void KListView::startDrag() +{ +qDebug("KListView::startDrag drag&drop not supported yet."); +/*US + QDragObject *drag = dragObject(); + + if (!drag) + return; + + if (drag->drag() && drag->target() != viewport()) + emit moved(); +*/ +} + +QDragObject *KListView::dragObject() +{ + if (!currentItem()) + return 0; + + return new QStoredDrag("application/x-qlistviewitem", viewport()); +} + +void KListView::setItemsMovable(bool b) +{ + d->itemsMovable=b; +} + +bool KListView::itemsMovable() const +{ + return d->itemsMovable; +} + +void KListView::setItemsRenameable(bool b) +{ + d->itemsRenameable=b; +} + +bool KListView::itemsRenameable() const +{ + return d->itemsRenameable; +} + + +void KListView::setDragEnabled(bool b) +{ + d->dragEnabled=b; +} + +bool KListView::dragEnabled() const +{ + return d->dragEnabled; +} + +void KListView::setAutoOpen(bool b) +{ + d->autoOpen=b; +} + +bool KListView::autoOpen() const +{ + return d->autoOpen; +} + +bool KListView::dropVisualizer() const +{ + return d->dropVisualizer; +} + +void KListView::setDropVisualizer(bool b) +{ + d->dropVisualizer=b; +} + +QPtrList KListView::selectedItems() const +{ + QPtrList list; + for (QListViewItem *i=firstChild(); i!=0; i=i->itemBelow()) + if (i->isSelected()) list.append(i); + return list; +} + + +void KListView::moveItem(QListViewItem *item, QListViewItem *parent, QListViewItem *after) +{ + // sanity check - don't move a item into it's own child structure + QListViewItem *i = parent; + while(i) + { + if(i == item) + return; + i = i->parent(); + } + + // Basically reimplementing the QListViewItem(QListViewItem*, QListViewItem*) constructor + // in here, without ever deleting the item. + if (item->parent()) + item->parent()->takeItem(item); + else + takeItem(item); + + if (parent) + parent->insertItem(item); + else + insertItem(item); + + if (after) + ;//item->moveToJustAfter(after); +} + +void KListView::contentsDragEnterEvent(QDragEnterEvent *event) +{ +qDebug("KListView::contentsDragEnterEvent drag&drop not supported yet."); +/*US + if (acceptDrag (event)) + event->accept(); +*/ +} + +void KListView::setDropVisualizerWidth (int w) +{ + d->mDropVisualizerWidth = w > 0 ? w : 1; +} + +QRect KListView::drawDropVisualizer(QPainter *p, QListViewItem *parent, + QListViewItem *after) +{ + QRect insertmarker; + + if (!after && !parent) + insertmarker = QRect (0, 0, viewport()->width(), d->mDropVisualizerWidth/2); + else + { + int level = 0; + if (after) + { + QListViewItem* it = 0L; + if (after->isOpen()) + { + // Look for the last child (recursively) + it = after->firstChild(); + if (it) + while (it->nextSibling() || it->firstChild()) + if ( it->nextSibling() ) + it = it->nextSibling(); + else + it = it->firstChild(); + } + + insertmarker = itemRect (it ? it : after); + level = after->depth(); + } + else if (parent) + { + insertmarker = itemRect (parent); + level = parent->depth() + 1; + } + insertmarker.setLeft( treeStepSize() * ( level + (rootIsDecorated() ? 1 : 0) ) + itemMargin() ); + insertmarker.setRight (viewport()->width()); + insertmarker.setTop (insertmarker.bottom() - d->mDropVisualizerWidth/2 + 1); + insertmarker.setBottom (insertmarker.bottom() + d->mDropVisualizerWidth/2); + } + + // This is not used anymore, at least by KListView itself (see viewportPaintEvent) + // Remove for KDE 3.0. + if (p) + p->fillRect(insertmarker, Dense4Pattern); + + return insertmarker; +} + +QRect KListView::drawItemHighlighter(QPainter *painter, QListViewItem *item) +{ + QRect r; + + if (item) + { + r = itemRect(item); + r.setLeft(r.left()+(item->depth()+1)*treeStepSize()); + if (painter) { +//US style().drawPrimitive(QStyle::PE_FocusRect, painter, r, colorGroup(), +//US QStyle::Style_FocusAtBorder, colorGroup().highlight()); + const QColor* pHighl = &(colorGroup().highlight()); + //LR style().drawFocusRect(painter, r, colorGroup(), pHighl, true); + +qDebug("KListView::drawItemHighlighter has to be verified"); + + } + + } + + return r; +} + +void KListView::cleanItemHighlighter () +{ + if (d->mOldDropHighlighter.isValid()) + { + QRect rect=d->mOldDropHighlighter; + d->mOldDropHighlighter = QRect(); + viewport()->repaint(rect, true); + } +} + +void KListView::rename(QListViewItem *item, int c) +{ + if (d->renameable.contains(c)) + { + ensureItemVisible(item); +//US d->editor->load(item,c); +qDebug("KListView::rename has to be verified"); + + } +} + +bool KListView::isRenameable (int col) const +{ + return d->renameable.contains(col); +} + +void KListView::setRenameable (int col, bool yesno) +{ + if (col>=header()->count()) return; + + d->renameable.remove(col); + if (yesno && d->renameable.find(col)==d->renameable.end()) + d->renameable+=col; + else if (!yesno && d->renameable.find(col)!=d->renameable.end()) + d->renameable.remove(col); +} + +void KListView::doneEditing(QListViewItem *item, int row) +{ + emit itemRenamed(item, item->text(row), row); + emit itemRenamed(item); +} + +bool KListView::acceptDrag(QDropEvent* e) const +{ +qDebug("KListView::acceptDrag drag&drop not supported yet"); +//US return acceptDrops() && itemsMovable() && (e->source()==viewport()); +return false; +} + +void KListView::setCreateChildren(bool b) +{ + d->createChildren=b; +} + +bool KListView::createChildren() const +{ + return d->createChildren; +} + + +int KListView::tooltipColumn() const +{ + return d->tooltipColumn; +} + +void KListView::setTooltipColumn(int column) +{ + d->tooltipColumn=column; +} + +void KListView::setDropHighlighter(bool b) +{ + d->dropHighlighter=b; +} + +bool KListView::dropHighlighter() const +{ + return d->dropHighlighter; +} + +bool KListView::showTooltip(QListViewItem *item, const QPoint &, int column) const +{ + return ((tooltip(item, column).length()>0) && (column==tooltipColumn())); +} + +QString KListView::tooltip(QListViewItem *item, int column) const +{ + return item->text(column); +} + +void KListView::setTabOrderedRenaming(bool b) +{ + d->tabRename = b; +} + +bool KListView::tabOrderedRenaming() const +{ + return d->tabRename; +} + +void KListView::keyPressEvent (QKeyEvent* e) +{ + //don't we need a contextMenuModifier too ? (aleXXX) + if (e->key() == d->contextMenuKey) + { + emit menuShortCutPressed (this, currentItem()); + return; + } + if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace) + { + emit signalDelete ( ); + return; + } + + if (d->selectionMode != FileManager) + QListView::keyPressEvent (e); + else + fileManagerKeyPressEvent (e); +} + +void KListView::activateAutomaticSelection() +{ + d->selectedBySimpleMove=true; + d->selectedUsingMouse=false; + if (currentItem()!=0) + { + selectAll(false); + currentItem()->setSelected(true); + currentItem()->repaint(); + emit selectionChanged(); + }; +} + +void KListView::deactivateAutomaticSelection() +{ + d->selectedBySimpleMove=false; +} + +bool KListView::automaticSelection() const +{ + return d->selectedBySimpleMove; +} + +void KListView::fileManagerKeyPressEvent (QKeyEvent* e) +{ + //don't care whether it's on the keypad or not + int e_state=(e->state() & ~Keypad); + + int oldSelectionDirection(d->selectionDirection); + + if ((e->key()!=Key_Shift) && (e->key()!=Key_Control) + && (e->key()!=Key_Meta) && (e->key()!=Key_Alt)) + { + if ((e_state==ShiftButton) && (!d->wasShiftEvent) && (!d->selectedBySimpleMove)) + selectAll(FALSE); + d->selectionDirection=0; + d->wasShiftEvent = (e_state == ShiftButton); + }; + + //d->wasShiftEvent = (e_state == ShiftButton); + + + QListViewItem* item = currentItem(); + if (item==0) return; + + QListViewItem* repaintItem1 = item; + QListViewItem* repaintItem2 = 0L; + QListViewItem* visItem = 0L; + + QListViewItem* nextItem = 0L; + int items = 0; + + bool shiftOrCtrl((e_state==ControlButton) || (e_state==ShiftButton)); + int selectedItems(0); + for (QListViewItem *tmpItem=firstChild(); tmpItem!=0; tmpItem=tmpItem->nextSibling()) + if (tmpItem->isSelected()) selectedItems++; + + if (((selectedItems==0) || ((selectedItems==1) && (d->selectedUsingMouse))) + && (e_state==NoButton) + && ((e->key()==Key_Down) + || (e->key()==Key_Up) + || (e->key()==Key_Next) + || (e->key()==Key_Prior) + || (e->key()==Key_Home) + || (e->key()==Key_End))) + { + d->selectedBySimpleMove=true; + d->selectedUsingMouse=false; + } + else if (selectedItems>1) + d->selectedBySimpleMove=false; + + bool emitSelectionChanged(false); + + switch (e->key()) + { + case Key_Escape: + selectAll(FALSE); + emitSelectionChanged=TRUE; + break; + + case Key_Space: + //toggle selection of current item + if (d->selectedBySimpleMove) + d->selectedBySimpleMove=false; + item->setSelected(!item->isSelected()); + emitSelectionChanged=TRUE; + break; + + case Key_Insert: + //toggle selection of current item and move to the next item + if (d->selectedBySimpleMove) + { + d->selectedBySimpleMove=false; + if (!item->isSelected()) item->setSelected(TRUE); + } + else + { + item->setSelected(!item->isSelected()); + }; + + nextItem=item->itemBelow(); + + if (nextItem!=0) + { + repaintItem2=nextItem; + visItem=nextItem; + setCurrentItem(nextItem); + }; + d->selectionDirection=1; + emitSelectionChanged=TRUE; + break; + + case Key_Down: + nextItem=item->itemBelow(); + //toggle selection of current item and move to the next item + if (shiftOrCtrl) + { + d->selectionDirection=1; + if (d->selectedBySimpleMove) + d->selectedBySimpleMove=false; + else + { + if (oldSelectionDirection!=-1) + { + item->setSelected(!item->isSelected()); + emitSelectionChanged=TRUE; + }; + }; + } + else if ((d->selectedBySimpleMove) && (nextItem!=0)) + { + item->setSelected(false); + emitSelectionChanged=TRUE; + }; + + if (nextItem!=0) + { + if (d->selectedBySimpleMove) + nextItem->setSelected(true); + repaintItem2=nextItem; + visItem=nextItem; + setCurrentItem(nextItem); + }; + break; + + case Key_Up: + nextItem=item->itemAbove(); + d->selectionDirection=-1; + //move to the prev. item and toggle selection of this one + // => No, can't select the last item, with this. For symmetry, let's + // toggle selection and THEN move up, just like we do in down (David) + if (shiftOrCtrl) + { + if (d->selectedBySimpleMove) + d->selectedBySimpleMove=false; + else + { + if (oldSelectionDirection!=1) + { + item->setSelected(!item->isSelected()); + emitSelectionChanged=TRUE; + }; + } + } + else if ((d->selectedBySimpleMove) && (nextItem!=0)) + { + item->setSelected(false); + emitSelectionChanged=TRUE; + }; + + if (nextItem!=0) + { + if (d->selectedBySimpleMove) + nextItem->setSelected(true); + repaintItem2=nextItem; + visItem=nextItem; + setCurrentItem(nextItem); + }; + break; + + case Key_End: + //move to the last item and toggle selection of all items inbetween + nextItem=item; + if (d->selectedBySimpleMove) + item->setSelected(false); + if (shiftOrCtrl) + d->selectedBySimpleMove=false; + + while(nextItem!=0) + { + if (shiftOrCtrl) + nextItem->setSelected(!nextItem->isSelected()); + if (nextItem->itemBelow()==0) + { + if (d->selectedBySimpleMove) + nextItem->setSelected(true); + repaintItem2=nextItem; + visItem=nextItem; + setCurrentItem(nextItem); + } + nextItem=nextItem->itemBelow(); + } + emitSelectionChanged=TRUE; + break; + + case Key_Home: + // move to the first item and toggle selection of all items inbetween + nextItem = firstChild(); + visItem = nextItem; + repaintItem2 = visItem; + if (d->selectedBySimpleMove) + item->setSelected(false); + if (shiftOrCtrl) + { + d->selectedBySimpleMove=false; + + while ( nextItem != item ) + { + nextItem->setSelected( !nextItem->isSelected() ); + nextItem = nextItem->itemBelow(); + } + item->setSelected( !item->isSelected() ); + } + setCurrentItem( firstChild() ); + emitSelectionChanged=TRUE; + break; + + case Key_Next: + items=visibleHeight()/item->height(); + nextItem=item; + if (d->selectedBySimpleMove) + item->setSelected(false); + if (shiftOrCtrl) + { + d->selectedBySimpleMove=false; + d->selectionDirection=1; + }; + + for (int i=0; isetSelected(!nextItem->isSelected()); + //the end + if ((i==items-1) || (nextItem->itemBelow()==0)) + + { + if (shiftOrCtrl) + nextItem->setSelected(!nextItem->isSelected()); + if (d->selectedBySimpleMove) + nextItem->setSelected(true); + ensureItemVisible(nextItem); + setCurrentItem(nextItem); + update(); + if ((shiftOrCtrl) || (d->selectedBySimpleMove)) + { + emit selectionChanged(); + } + return; + } + nextItem=nextItem->itemBelow(); + } + break; + + case Key_Prior: + items=visibleHeight()/item->height(); + nextItem=item; + if (d->selectedBySimpleMove) + item->setSelected(false); + if (shiftOrCtrl) + { + d->selectionDirection=-1; + d->selectedBySimpleMove=false; + }; + + for (int i=0; isetSelected(!nextItem->isSelected()); + //the end + if ((i==items-1) || (nextItem->itemAbove()==0)) + + { + if (d->selectedBySimpleMove) + nextItem->setSelected(true); + ensureItemVisible(nextItem); + setCurrentItem(nextItem); + update(); + if ((shiftOrCtrl) || (d->selectedBySimpleMove)) + { + emit selectionChanged(); + } + return; + } + nextItem=nextItem->itemAbove(); + } + break; + + case Key_Minus: + if ( item->isOpen() ) + setOpen( item, FALSE ); + break; + case Key_Plus: + if ( !item->isOpen() && (item->isExpandable() || item->childCount()) ) + setOpen( item, TRUE ); + break; + default: + bool realKey = ((e->key()!=Key_Shift) && (e->key()!=Key_Control) + && (e->key()!=Key_Meta) && (e->key()!=Key_Alt)); + + bool selectCurrentItem = (d->selectedBySimpleMove) && (item->isSelected()); + if (realKey && selectCurrentItem) + item->setSelected(false); + //this is mainly for the "goto filename beginning with pressed char" feature (aleXXX) + QListView::SelectionMode oldSelectionMode = selectionMode(); + setSelectionMode (QListView::Multi); + QListView::keyPressEvent (e); + setSelectionMode (oldSelectionMode); + if (realKey && selectCurrentItem) + { + currentItem()->setSelected(true); + emitSelectionChanged=TRUE; + } + repaintItem2=currentItem(); + if (realKey) + visItem=currentItem(); + break; + } + + if (visItem) + ensureItemVisible(visItem); + + QRect ir; + if (repaintItem1) + ir = ir.unite( itemRect(repaintItem1) ); + if (repaintItem2) + ir = ir.unite( itemRect(repaintItem2) ); + + if ( !ir.isEmpty() ) + { // rectangle to be repainted + if ( ir.x() < 0 ) + ir.moveBy( -ir.x(), 0 ); + viewport()->repaint( ir, FALSE ); + } + /*if (repaintItem1) + repaintItem1->repaint(); + if (repaintItem2) + repaintItem2->repaint();*/ + update(); + if (emitSelectionChanged) + emit selectionChanged(); +} + +void KListView::setSelectionModeExt (SelectionModeExt mode) +{ + d->selectionMode = mode; + + switch (mode) + { + case Single: + case Multi: + case Extended: + case NoSelection: + setSelectionMode (static_cast(static_cast(mode))); + break; + + case FileManager: + setSelectionMode (QListView::Extended); + break; + + default: + kdWarning () << "Warning: illegal selection mode " << int(mode) << " set!" << endl; + break; + } +} + +KListView::SelectionModeExt KListView::selectionModeExt () const +{ + return d->selectionMode; +} + +int KListView::itemIndex( const QListViewItem *item ) const +{ + if ( !item ) + return -1; + + if ( item == firstChild() ) + return 0; + else { + QListViewItemIterator it(firstChild()); + uint j = 0; + for (; it.current() && it.current() != item; ++it, ++j ); + + if( !it.current() ) + return -1; + + return j; + } +} + +QListViewItem* KListView::itemAtIndex(int index) +{ + if (index<0) + return 0; + + int j(0); + for (QListViewItemIterator it=firstChild(); it.current(); it++) + { + if (j==index) + return it.current(); + j++; + }; + return 0; +} + + +void KListView::emitContextMenu (KListView*, QListViewItem* i) +{ + QPoint p; + qDebug("KListView::emitContextMenu "); + + if (i) + p = viewport()->mapToGlobal(itemRect(i).center()); + else + p = mapToGlobal(rect().center()); + + emit contextMenu (this, i, p); +} + +void KListView::emitContextMenu (QListViewItem* i, const QPoint& p, int) +{ + qDebug("KListView::emitContextMenu "); + emit contextMenu (this, i, p); +} + +void KListView::setAcceptDrops (bool val) +{ + QListView::setAcceptDrops (val); + viewport()->setAcceptDrops (val); +} + +int KListView::dropVisualizerWidth () const +{ + return d->mDropVisualizerWidth; +} + + +void KListView::viewportPaintEvent(QPaintEvent *e) +{ + QListView::viewportPaintEvent(e); + + if (d->mOldDropVisualizer.isValid() && e->rect().intersects(d->mOldDropVisualizer)) + { + QPainter painter(viewport()); + + // This is where we actually draw the drop-visualizer + painter.fillRect(d->mOldDropVisualizer, Dense4Pattern); + } + if (d->mOldDropHighlighter.isValid() && e->rect().intersects(d->mOldDropHighlighter)) + { + QPainter painter(viewport()); + +qDebug("KListView::viewportPaintEvent has to be verified"); + + // This is where we actually draw the drop-highlighter +//US style().drawPrimitive(QStyle::PE_FocusRect, &painter, d->mOldDropHighlighter, colorGroup(), +//US QStyle::Style_FocusAtBorder); + +//LR style().drawFocusRect(&painter, d->mOldDropHighlighter, colorGroup(), (const QColor*)0, true); + + + } +} + +void KListView::setFullWidth() +{ + setFullWidth(true); +} + +void KListView::setFullWidth(bool fullWidth) +{ + d->fullWidth = fullWidth; +//US header()->setStretchEnabled(fullWidth, columns()-1); +} + +bool KListView::fullWidth() const +{ + return d->fullWidth; +} + +int KListView::addColumn(const QString& label, int width) +{ + int result = QListView::addColumn(label, width); + if (d->fullWidth) { +//US header()->setStretchEnabled(false, columns()-2); +//US header()->setStretchEnabled(true, columns()-1); + } + return result; +} + +int KListView::addColumn(const QIconSet& iconset, const QString& label, int width) +{ + int result = QListView::addColumn(iconset, label, width); + if (d->fullWidth) { +//US header()->setStretchEnabled(false, columns()-2); +//US header()->setStretchEnabled(true, columns()-1); + } + return result; +} + +void KListView::removeColumn(int index) +{ + QListView::removeColumn(index); +//US if (d->fullWidth && index == columns()) header()->setStretchEnabled(true, columns()-1); +} + +void KListView::viewportResizeEvent(QResizeEvent* e) +{ + QListView::viewportResizeEvent(e); +} + +const QColor &KListView::alternateBackground() const +{ + return d->alternateBackground; +} + +void KListView::setAlternateBackground(const QColor &c) +{ + d->alternateBackground = c; + repaint(); +} + +void KListView::saveLayout(KConfig *config, const QString &group) const +{ + KConfigGroupSaver saver(config, group); + QStringList widths, order; + for (int i = 0; i < columns(); ++i) + { + widths << QString::number(columnWidth(i)); + order << QString::number(header()->mapToIndex(i)); + } + config->writeEntry("ColumnWidths", widths); + config->writeEntry("ColumnOrder", order); + config->writeEntry("SortColumn", d->sortColumn); + config->writeEntry("SortAscending", d->sortAscending); +} + +void KListView::restoreLayout(KConfig *config, const QString &group) +{ + KConfigGroupSaver saver(config, group); + QStringList cols = config->readListEntry("ColumnWidths"); + int i = 0; + for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it) + setColumnWidth(i++, (*it).toInt()); + + cols = config->readListEntry("ColumnOrder"); + i = 0; + for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it) + header()->moveSection(i++, (*it).toInt()); + +/*US I changed the following code, because hasKey is not available. +!!! check if my version is correct + if (config->hasKey("SortColumn")) + setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true)); +*/ + QStringList langLst = config->readListEntry( "SortColumn" ); + if (!langLst.isEmpty()) + setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true)); +} + +void KListView::setSorting(int column, bool ascending) +{ + d->sortColumn = column; + d->sortAscending = ascending; + QListView::setSorting(column, ascending); +} + +int KListView::columnSorted(void) const +{ + return d->sortColumn; +} + +bool KListView::ascendingSort(void) const +{ + return d->sortAscending; +} + +KListViewItem::KListViewItem(QListView *parent) + : QListViewItem(parent) +{ + init(); +} + +KListViewItem::KListViewItem(QListViewItem *parent) + : QListViewItem(parent) +{ + init(); +} + +KListViewItem::KListViewItem(QListView *parent, QListViewItem *after) + : QListViewItem(parent, after) +{ + init(); +} + +KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after) + : QListViewItem(parent, after) +{ + init(); +} + +KListViewItem::KListViewItem(QListView *parent, + QString label1, QString label2, QString label3, QString label4, + QString label5, QString label6, QString label7, QString label8) + : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8) +{ + init(); +} + +KListViewItem::KListViewItem(QListViewItem *parent, + QString label1, QString label2, QString label3, QString label4, + QString label5, QString label6, QString label7, QString label8) + : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8) +{ + init(); +} + +KListViewItem::KListViewItem(QListView *parent, QListViewItem *after, + QString label1, QString label2, QString label3, QString label4, + QString label5, QString label6, QString label7, QString label8) + : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8) +{ + init(); +} + +KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after, + QString label1, QString label2, QString label3, QString label4, + QString label5, QString label6, QString label7, QString label8) + : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8) +{ + init(); +} + +KListViewItem::~KListViewItem() +{ +} + +void KListViewItem::init() +{ + m_known = false; +} + +const QColor &KListViewItem::backgroundColor() +{ + if (isAlternate()) + return static_cast< KListView* >(listView())->alternateBackground(); + return listView()->viewport()->colorGroup().base(); +} + +bool KListViewItem::isAlternate() +{ + KListView *lv = static_cast(listView()); + if (lv && lv->alternateBackground().isValid()) + { + KListViewItem *above = 0; +//US above = dynamic_cast(itemAbove()); + above = (KListViewItem *)(itemAbove()); + m_known = above ? above->m_known : true; + if (m_known) + { + m_odd = above ? !above->m_odd : false; + } + else + { + KListViewItem *item; + bool previous = true; + if (parent()) + { +//US item = dynamic_cast(parent()); + item = (KListViewItem *)(parent()); + if (item) + previous = item->m_odd; +//US item = dynamic_cast(parent()->firstChild()); + item = (KListViewItem *)(parent()->firstChild()); + } + else + { +//US item = dynamic_cast(lv->firstChild()); + item = (KListViewItem *)(lv->firstChild()); + } + + while(item) + { + item->m_odd = previous = !previous; + item->m_known = true; +//US item = dynamic_cast(item->nextSibling()); + item = (KListViewItem *)(item->nextSibling()); + } + } + return m_odd; + } + return false; +} + +void KListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment) +{ + QColorGroup _cg = cg; + const QPixmap *pm = listView()->viewport()->backgroundPixmap(); + if (pm && !pm->isNull()) + { + _cg.setBrush(QColorGroup::Base, QBrush(backgroundColor(), *pm)); + QPoint o = p->brushOrigin(); + p->setBrushOrigin( o.x()-listView()->contentsX(), o.y()-listView()->contentsY() ); + } + else if (isAlternate()) { +//US if (listView()->viewport()->backgroundMode()==Qt::FixedColor) + if (listView()->viewport()->backgroundMode()==QWidget::PaletteBackground) + _cg.setColor(QColorGroup::Background, static_cast< KListView* >(listView())->alternateBackground()); + else + _cg.setColor(QColorGroup::Base, static_cast< KListView* >(listView())->alternateBackground()); + } + QListViewItem::paintCell(p, _cg, column, width, alignment); +} + +void KListView::virtual_hook( int, void* ) +{ /*BASE::virtual_hook( id, data );*/ } + +//US #include "klistview.moc" +//US #include "klistviewlineedit.moc" + +// vim: ts=2 sw=2 et -- cgit v0.9.0.2