kdeui Library API Documentation

klistview.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
00003    Copyright (C) 2000,2003 Charles Samuels <charles@kde.org>
00004    Copyright (C) 2000 Peter Putzer
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License version 2 as published by the Free Software Foundation.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 #include "config.h"
00021 
00022 #include <qdragobject.h>
00023 #include <qtimer.h>
00024 #include <qheader.h>
00025 #include <qcursor.h>
00026 #include <qtooltip.h>
00027 #include <qstyle.h>
00028 #include <qpainter.h>
00029 
00030 #include <kglobalsettings.h>
00031 #include <kconfig.h>
00032 #include <kcursor.h>
00033 #include <kapplication.h>
00034 
00035 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00036 #include <kipc.h> 
00037 #endif
00038 
00039 #include <kdebug.h>
00040 
00041 #include "klistview.h"
00042 #include "klistviewlineedit.h"
00043 
00044 class KListView::Tooltip : public QToolTip
00045 {
00046 public:
00047   Tooltip (KListView* parent, QToolTipGroup* group = 0L);
00048   virtual ~Tooltip () {}
00049 
00050 protected:
00054   virtual void maybeTip (const QPoint&);
00055 
00056 private:
00057   KListView* mParent;
00058 };
00059 
00060 KListView::Tooltip::Tooltip (KListView* parent, QToolTipGroup* group)
00061   : QToolTip (parent, group),
00062         mParent (parent)
00063 {
00064 }
00065 
00066 void KListView::Tooltip::maybeTip (const QPoint&)
00067 {
00068   // FIXME
00069 }
00070 
00071 class KListView::KListViewPrivate
00072 {
00073 public:
00074   KListViewPrivate (KListView* listview)
00075     : pCurrentItem (0L),
00076       dragDelay (KGlobalSettings::dndEventDelay()),
00077       editor (new KListViewLineEdit (listview)),
00078       cursorInExecuteArea(false),
00079       itemsMovable (true),
00080       selectedBySimpleMove(false),
00081       selectedUsingMouse(false),
00082       itemsRenameable (false),
00083       validDrag (false),
00084       dragEnabled (false),
00085       autoOpen (true),
00086       disableAutoSelection (false),
00087       dropVisualizer (true),
00088       dropHighlighter (false),
00089       createChildren (true),
00090       pressedOnSelected (false),
00091       wasShiftEvent (false),
00092       fullWidth (false),
00093       sortAscending(true),
00094         tabRename(true),
00095       sortColumn(0),
00096       selectionDirection(0),
00097       tooltipColumn (0),
00098       selectionMode (Single),
00099       contextMenuKey (KGlobalSettings::contextMenuKey()),
00100       showContextMenusOnPress (KGlobalSettings::showContextMenusOnPress()),
00101       mDropVisualizerWidth (4),
00102       paintAbove (0),
00103       paintCurrent (0),
00104       paintBelow (0),
00105       painting (false)
00106   {
00107       renameable.append(0);
00108       connect(editor, SIGNAL(done(QListViewItem*,int)), listview, SLOT(doneEditing(QListViewItem*,int)));
00109   }
00110 
00111   ~KListViewPrivate ()
00112   {
00113     delete editor;
00114   }
00115 
00116   QListViewItem* pCurrentItem;
00117 
00118   QTimer autoSelect;
00119   int autoSelectDelay;
00120 
00121   QTimer dragExpand;
00122   QListViewItem* dragOverItem;
00123   QPoint dragOverPoint;
00124 
00125   QPoint startDragPos;
00126   int dragDelay;
00127 
00128   KListViewLineEdit *editor;
00129   QValueList<int> renameable;
00130 
00131   bool cursorInExecuteArea:1;
00132   bool bUseSingle:1;
00133   bool bChangeCursorOverItem:1;
00134   bool itemsMovable:1;
00135   bool selectedBySimpleMove : 1;
00136   bool selectedUsingMouse:1;
00137   bool itemsRenameable:1;
00138   bool validDrag:1;
00139   bool dragEnabled:1;
00140   bool autoOpen:1;
00141   bool disableAutoSelection:1;
00142   bool dropVisualizer:1;
00143   bool dropHighlighter:1;
00144   bool createChildren:1;
00145   bool pressedOnSelected:1;
00146   bool wasShiftEvent:1;
00147   bool fullWidth:1;
00148   bool sortAscending:1;
00149   bool tabRename:1;
00150 
00151   int sortColumn;
00152 
00153   //+1 means downwards (y increases, -1 means upwards, 0 means not selected), aleXXX
00154   int selectionDirection;
00155   int tooltipColumn;
00156 
00157   SelectionModeExt selectionMode;
00158   int contextMenuKey;
00159   bool showContextMenusOnPress;
00160 
00161   QRect mOldDropVisualizer;
00162   int mDropVisualizerWidth;
00163   QRect mOldDropHighlighter;
00164   QListViewItem *afterItemDrop;
00165   QListViewItem *parentItemDrop;
00166 
00167   QListViewItem *paintAbove;
00168   QListViewItem *paintCurrent;
00169   QListViewItem *paintBelow;
00170   bool painting;
00171 
00172   QColor alternateBackground;
00173 };
00174 
00175 
00176 KListViewLineEdit::KListViewLineEdit(KListView *parent)
00177         : KLineEdit(parent->viewport()), item(0), col(0), p(parent)
00178 {
00179         setFrame( false );
00180         hide();
00181         connect( parent, SIGNAL( selectionChanged() ), SLOT( slotSelectionChanged() ));
00182 }
00183 
00184 KListViewLineEdit::~KListViewLineEdit()
00185 {
00186 }
00187 
00188 QListViewItem *KListViewLineEdit::currentItem() const
00189 {
00190     return item;
00191 }
00192 
00193 void KListViewLineEdit::load(QListViewItem *i, int c)
00194 {
00195         item=i;
00196         col=c;
00197 
00198         QRect rect(p->itemRect(i));
00199         setText(item->text(c));
00200         home( true );
00201 
00202         int fieldX = rect.x() - 1;
00203         int fieldW = p->columnWidth(col) + 2;
00204 
00205         int pos = p->header()->mapToIndex(col);
00206         for ( int index = 0; index < pos; index++ )
00207             fieldX += p->columnWidth( p->header()->mapToSection( index ));
00208 
00209         if ( col == 0 ) {
00210             int d = i->depth() + (p->rootIsDecorated() ? 1 : 0);
00211             d *= p->treeStepSize();
00212             fieldX += d;
00213             fieldW -= d;
00214         }
00215 
00216         if ( i->pixmap( col ) ) {// add width of pixmap
00217             int d = i->pixmap( col )->width();
00218             fieldX += d;
00219             fieldW -= d;
00220         }
00221 
00222         setGeometry(fieldX, rect.y() - 1, fieldW, rect.height() + 2);
00223         show();
00224         setFocus();
00225 }
00226 
00227 /*  Helper functions to for
00228  *  tabOrderedRename functionality.
00229  */
00230 
00231 static int nextCol (KListView *pl, QListViewItem *pi, int start, int dir)
00232 {
00233     if (pi)
00234     {
00235         //  Find the next renameable column in the current row
00236         for (; ((dir == +1) ? (start < pl->columns()) : (start >= 0)); start += dir)
00237             if (pl->isRenameable(start))
00238                 return start;
00239     }
00240 
00241     return -1;
00242 }
00243 
00244 static QListViewItem *prevItem (QListViewItem *pi)
00245 {
00246     QListViewItem *pa = pi->itemAbove();
00247 
00248     /*  Does what the QListViewItem::previousSibling()
00249      *  of my dreams would do.
00250      */
00251     if (pa && pa->parent() == pi->parent())
00252         return pa;
00253 
00254     return 0;
00255 }
00256 
00257 static QListViewItem *lastQChild (QListViewItem *pi)
00258 {
00259     if (pi)
00260     {
00261         /*  Since there's no QListViewItem::lastChild().
00262          *  This finds the last sibling for the given
00263          *  item.
00264          */
00265         for (QListViewItem *pt = pi->nextSibling(); pt; pt = pt->nextSibling())
00266             pi = pt;
00267     }
00268 
00269     return pi;
00270 }
00271 
00272 void KListViewLineEdit::selectNextCell (QListViewItem *pitem, int column, bool forward)
00273 {
00274     const int ncols = p->columns();
00275     const int dir = forward ? +1 : -1;
00276     const int restart = forward ? 0 : (ncols - 1);
00277     QListViewItem *top = (pitem && pitem->parent())
00278         ? pitem->parent()->firstChild()
00279         : p->firstChild();
00280     QListViewItem *pi = pitem;
00281 
00282     terminate();        //  Save current changes
00283 
00284     do
00285     {
00286         /*  Check the rest of the current row for an editable column,
00287          *  if that fails, check the entire next/previous row. The
00288          *  last case goes back to the first item in the current branch
00289          *  or the last item in the current branch depending on the
00290          *  direction.
00291          */
00292         if ((column = nextCol(p, pi, column + dir, dir)) != -1 ||
00293             (column = nextCol(p, (pi = (forward ? pi->nextSibling() : prevItem(pi))), restart, dir)) != -1 ||
00294             (column = nextCol(p, (pi = (forward ? top : lastQChild(pitem))), restart, dir)) != -1)
00295         {
00296             if (pi)
00297             {
00298                 p->setCurrentItem(pi);      //  Calls terminate
00299                 p->rename(pi, column);
00300 
00301                 /*  Some listviews may override rename() to
00302                  *  prevent certain items from being renamed,
00303                  *  if this is done, [m_]item will be NULL
00304                  *  after the rename() call... try again.
00305                  */
00306                 if (!item)
00307                     continue;
00308 
00309                 break;
00310             }
00311         }
00312     }
00313     while (pi && !item);
00314 }
00315 
00316 #ifdef KeyPress
00317 #undef KeyPress
00318 #endif
00319 
00320 bool KListViewLineEdit::event (QEvent *pe)
00321 {
00322     if (pe->type() == QEvent::KeyPress)
00323     {
00324         QKeyEvent *k = (QKeyEvent *) pe;
00325 
00326         if ((k->key() == Qt::Key_Backtab || k->key() == Qt::Key_Tab) &&
00327             p->tabOrderedRenaming() && p->itemsRenameable() &&
00328             !(k->state() & ControlButton || k->state() & AltButton))
00329         {
00330             selectNextCell(item, col,
00331                 (k->key() == Key_Tab && !(k->state() & ShiftButton)));
00332             return true;
00333         }
00334     }
00335 
00336     return KLineEdit::event(pe);
00337 }
00338 
00339 void KListViewLineEdit::keyPressEvent(QKeyEvent *e)
00340 {
00341     if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )
00342         terminate(true);
00343     else if(e->key() == Qt::Key_Escape)
00344         terminate(false);
00345         else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Up)
00346         {
00347         terminate(true);
00348                 KLineEdit::keyPressEvent(e);
00349         }
00350     else
00351         KLineEdit::keyPressEvent(e);
00352 }
00353 
00354 void KListViewLineEdit::terminate()
00355 {
00356     terminate(true);
00357 }
00358 
00359 void KListViewLineEdit::terminate(bool commit)
00360 {
00361     if ( item )
00362     {
00363         //kdDebug() << "KListViewLineEdit::terminate " << commit << endl;
00364         if (commit)
00365             item->setText(col, text());
00366         int c=col;
00367         QListViewItem *i=item;
00368         col=0;
00369         item=0;
00370         hide(); // will call focusOutEvent, that's why we set item=0 before
00371         if (commit)
00372             emit done(i,c);
00373     }
00374 }
00375 
00376 void KListViewLineEdit::focusOutEvent(QFocusEvent *ev)
00377 {
00378     QFocusEvent * focusEv = static_cast<QFocusEvent*>(ev);
00379     // Don't let a RMB close the editor
00380     if (focusEv->reason() != QFocusEvent::Popup && focusEv->reason() != QFocusEvent::ActiveWindow)
00381         terminate(true);
00382     else
00383         KLineEdit::focusOutEvent(ev);
00384 }
00385 
00386 void KListViewLineEdit::paintEvent( QPaintEvent *e )
00387 {
00388     KLineEdit::paintEvent( e );
00389 
00390     if ( !frame() ) {
00391         QPainter p( this );
00392         p.setClipRegion( e->region() );
00393         p.drawRect( rect() );
00394     }
00395 }
00396 
00397 // selection changed -> terminate. As our "item" can be already deleted,
00398 // we can't call terminate(false), because that would emit done() with
00399 // a dangling pointer to "item".
00400 void KListViewLineEdit::slotSelectionChanged()
00401 {
00402     item = 0;
00403     col = 0;
00404     hide();
00405 }
00406 
00407 
00408 KListView::KListView( QWidget *parent, const char *name )
00409   : QListView( parent, name ),
00410         d (new KListViewPrivate (this))
00411 {
00412   setDragAutoScroll(true);
00413 
00414   connect( this, SIGNAL( onViewport() ),
00415                    this, SLOT( slotOnViewport() ) );
00416   connect( this, SIGNAL( onItem( QListViewItem * ) ),
00417                    this, SLOT( slotOnItem( QListViewItem * ) ) );
00418 
00419   connect (this, SIGNAL(contentsMoving(int,int)),
00420                    this, SLOT(cleanDropVisualizer()));
00421   connect (this, SIGNAL(contentsMoving(int,int)),
00422                    this, SLOT(cleanItemHighlighter()));
00423 
00424   slotSettingsChanged(KApplication::SETTINGS_MOUSE);
00425   if (kapp)
00426   {
00427     connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) );
00428 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00429     kapp->addKipcEventMask( KIPC::SettingsChanged );
00430 #endif
00431   }
00432 
00433   connect(&d->autoSelect, SIGNAL( timeout() ),
00434                   this, SLOT( slotAutoSelect() ) );
00435   connect(&d->dragExpand, SIGNAL( timeout() ),
00436                   this, SLOT( slotDragExpand() ) );
00437 
00438   // context menu handling
00439   if (d->showContextMenusOnPress)
00440         {
00441           connect (this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)),
00442                            this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00443         }
00444   else
00445         {
00446           connect (this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)),
00447                            this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00448         }
00449 
00450   connect (this, SIGNAL (menuShortCutPressed (KListView*, QListViewItem*)),
00451                    this, SLOT (emitContextMenu (KListView*, QListViewItem*)));
00452   d->alternateBackground = KGlobalSettings::alternateBackgroundColor();
00453 }
00454 
00455 KListView::~KListView()
00456 {
00457   delete d;
00458 }
00459 
00460 bool KListView::isExecuteArea( const QPoint& point )
00461 {
00462   QListViewItem* item = itemAt( point );
00463   if ( item ) {
00464     return isExecuteArea( point.x(), item );
00465   }
00466 
00467   return false;
00468 }
00469 
00470 bool KListView::isExecuteArea( int x )
00471 {
00472   return isExecuteArea( x, 0 );
00473 }
00474 
00475 bool KListView::isExecuteArea( int x, QListViewItem* item )
00476 {
00477   if( allColumnsShowFocus() )
00478     return true;
00479   else {
00480     int offset = 0;
00481     int width = columnWidth( 0 );
00482     int pos = header()->mapToIndex( 0 );
00483 
00484     for ( int index = 0; index < pos; index++ )
00485       offset += columnWidth( header()->mapToSection( index ) );
00486 
00487     x += contentsX(); // in case of a horizontal scrollbar
00488 
00489     if ( item )
00490     {
00491     width = treeStepSize()*( item->depth() + ( rootIsDecorated() ? 1 : 0 ) );
00492     width += itemMargin();
00493     int ca = AlignHorizontal_Mask & columnAlignment( 0 );
00494     if ( ca == AlignLeft || ca == AlignAuto ) {
00495         width += item->width( fontMetrics(), this, 0 );
00496         if ( width > columnWidth( 0 ) )
00497         width = columnWidth( 0 );
00498     }
00499     }
00500 
00501     return ( x > offset && x < ( offset + width ) );
00502   }
00503 }
00504 
00505 void KListView::slotOnItem( QListViewItem *item )
00506 {
00507   QPoint vp = viewport()->mapFromGlobal( QCursor::pos() );
00508   if ( item && isExecuteArea( vp.x() ) && (d->autoSelectDelay > -1) && d->bUseSingle ) {
00509     d->autoSelect.start( d->autoSelectDelay, true );
00510     d->pCurrentItem = item;
00511   }
00512 }
00513 
00514 void KListView::slotOnViewport()
00515 {
00516   if ( d->bChangeCursorOverItem )
00517     viewport()->unsetCursor();
00518 
00519   d->autoSelect.stop();
00520   d->pCurrentItem = 0L;
00521 }
00522 
00523 void KListView::slotSettingsChanged(int category)
00524 {
00525   switch (category)
00526   {
00527   case KApplication::SETTINGS_MOUSE:
00528     d->dragDelay =  KGlobalSettings::dndEventDelay();
00529     d->bUseSingle = KGlobalSettings::singleClick();
00530 
00531     disconnect(this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
00532                this, SLOT (slotMouseButtonClicked (int, QListViewItem*, const QPoint &, int)));
00533 
00534     if( d->bUseSingle )
00535       connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
00536                this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int)));
00537 
00538     d->bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon();
00539     if ( !d->disableAutoSelection )
00540       d->autoSelectDelay = KGlobalSettings::autoSelectDelay();
00541 
00542     if( !d->bUseSingle || !d->bChangeCursorOverItem )
00543        viewport()->unsetCursor();
00544 
00545     break;
00546 
00547   case KApplication::SETTINGS_POPUPMENU:
00548     d->contextMenuKey = KGlobalSettings::contextMenuKey ();
00549     d->showContextMenusOnPress = KGlobalSettings::showContextMenusOnPress ();
00550 
00551     if (d->showContextMenusOnPress)
00552     {
00553       disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00554 
00555       connect(this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)),
00556               this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00557     }
00558     else
00559     {
00560       disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00561 
00562       connect(this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)),
00563               this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00564     }
00565     break;
00566 
00567   default:
00568     break;
00569   }
00570 }
00571 
00572 void KListView::slotAutoSelect()
00573 {
00574   // check that the item still exists
00575   if( itemIndex( d->pCurrentItem ) == -1 )
00576     return;
00577 
00578   if (!isActiveWindow())
00579         {
00580           d->autoSelect.stop();
00581           return;
00582         }
00583 
00584   //Give this widget the keyboard focus.
00585   if( !hasFocus() )
00586     setFocus();
00587 
00588 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00589   // FIXME(E): Implement for Qt Embedded
00590   uint keybstate = KApplication::keyboardModifiers();
00591 #endif
00592 
00593   QListViewItem* previousItem = currentItem();
00594   setCurrentItem( d->pCurrentItem );
00595 
00596 //#ifndef Q_WS_QWS
00597 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00598   // FIXME(E): Implement for Qt Embedded
00599   if( d->pCurrentItem ) {
00600     //Shift pressed?
00601     if( (keybstate & KApplication::ShiftModifier) ) {
00602       bool block = signalsBlocked();
00603       blockSignals( true );
00604 
00605       //No Ctrl? Then clear before!
00606       if( !(keybstate & KApplication::ControlModifier) )
00607                 clearSelection();
00608 
00609       bool select = !d->pCurrentItem->isSelected();
00610       bool update = viewport()->isUpdatesEnabled();
00611       viewport()->setUpdatesEnabled( false );
00612 
00613       bool down = previousItem->itemPos() < d->pCurrentItem->itemPos();
00614       QListViewItemIterator lit( down ? previousItem : d->pCurrentItem );
00615       for ( ; lit.current(); ++lit ) {
00616                 if ( down && lit.current() == d->pCurrentItem ) {
00617                   d->pCurrentItem->setSelected( select );
00618                   break;
00619                 }
00620                 if ( !down && lit.current() == previousItem ) {
00621                   previousItem->setSelected( select );
00622                   break;
00623                 }
00624                 lit.current()->setSelected( select );
00625       }
00626 
00627       blockSignals( block );
00628       viewport()->setUpdatesEnabled( update );
00629       triggerUpdate();
00630 
00631       emit selectionChanged();
00632 
00633       if( selectionMode() == QListView::Single )
00634                 emit selectionChanged( d->pCurrentItem );
00635     }
00636     else if( (keybstate & KApplication::ControlModifier) )
00637       setSelected( d->pCurrentItem, !d->pCurrentItem->isSelected() );
00638     else {
00639       bool block = signalsBlocked();
00640       blockSignals( true );
00641 
00642       if( !d->pCurrentItem->isSelected() )
00643                 clearSelection();
00644 
00645       blockSignals( block );
00646 
00647       setSelected( d->pCurrentItem, true );
00648     }
00649   }
00650   else
00651     kdDebug() << "KListView::slotAutoSelect: Thatīs not supposed to happen!!!!" << endl;
00652 #endif
00653 }
00654 
00655 void KListView::slotHeaderChanged()
00656 {
00657   if (d->fullWidth && columns())
00658   {
00659     int w = 0;
00660     for (int i = 0; i < columns() - 1; ++i) w += columnWidth(i);
00661     setColumnWidth( columns() - 1, viewport()->width() - w - 1 );
00662   }
00663 }
00664 
00665 void KListView::emitExecute( QListViewItem *item, const QPoint &pos, int c )
00666 {
00667     if( isExecuteArea( viewport()->mapFromGlobal(pos) ) ) {
00668 
00669         // Double click mode ?
00670         if ( !d->bUseSingle )
00671         {
00672             viewport()->unsetCursor();
00673             emit executed( item );
00674             emit executed( item, pos, c );
00675         }
00676         else
00677         {
00678 //#ifndef Q_WS_QWS
00679 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00680         // FIXME(E): Implement for Qt Embedded
00681             uint keybstate = KApplication::keyboardModifiers();
00682 
00683             d->autoSelect.stop();
00684 
00685             //Donīt emit executed if in SC mode and Shift or Ctrl are pressed
00686             if( !( ((keybstate & KApplication::ShiftModifier) || (keybstate & KApplication::ControlModifier)) ) ) {
00687                 viewport()->unsetCursor();
00688                 emit executed( item );
00689                 emit executed( item, pos, c );
00690             }
00691 #endif
00692         }
00693     }
00694 }
00695 
00696 void KListView::focusInEvent( QFocusEvent *fe )
00697 {
00698  //   kdDebug()<<"KListView::focusInEvent()"<<endl;
00699   QListView::focusInEvent( fe );
00700   if ((d->selectedBySimpleMove)
00701       && (d->selectionMode == FileManager)
00702       && (fe->reason()!=QFocusEvent::Popup)
00703       && (fe->reason()!=QFocusEvent::ActiveWindow)
00704       && (currentItem()!=0))
00705   {
00706       currentItem()->setSelected(true);
00707       currentItem()->repaint();
00708       emit selectionChanged();
00709   };
00710 }
00711 
00712 void KListView::focusOutEvent( QFocusEvent *fe )
00713 {
00714   cleanDropVisualizer();
00715   cleanItemHighlighter();
00716 
00717   d->autoSelect.stop();
00718 
00719   if ((d->selectedBySimpleMove)
00720       && (d->selectionMode == FileManager)
00721       && (fe->reason()!=QFocusEvent::Popup)
00722       && (fe->reason()!=QFocusEvent::ActiveWindow)
00723       && (currentItem()!=0)
00724       && (!d->editor->isVisible()))
00725   {
00726       currentItem()->setSelected(false);
00727       currentItem()->repaint();
00728       emit selectionChanged();
00729   };
00730 
00731   QListView::focusOutEvent( fe );
00732 }
00733 
00734 void KListView::leaveEvent( QEvent *e )
00735 {
00736   d->autoSelect.stop();
00737 
00738   QListView::leaveEvent( e );
00739 }
00740 
00741 bool KListView::event( QEvent *e )
00742 {
00743   if (e->type() == QEvent::ApplicationPaletteChange)
00744     d->alternateBackground=KGlobalSettings::alternateBackgroundColor();
00745 
00746   return QListView::event(e);
00747 }
00748 
00749 void KListView::contentsMousePressEvent( QMouseEvent *e )
00750 {
00751   if( (selectionModeExt() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) )
00752   {
00753     bool block = signalsBlocked();
00754     blockSignals( true );
00755 
00756     clearSelection();
00757 
00758     blockSignals( block );
00759   }
00760   else if ((selectionModeExt()==FileManager) && (d->selectedBySimpleMove))
00761   {
00762      d->selectedBySimpleMove=false;
00763      d->selectedUsingMouse=true;
00764      if (currentItem()!=0)
00765      {
00766         currentItem()->setSelected(false);
00767         currentItem()->repaint();
00768 //        emit selectionChanged();
00769      }
00770   }
00771 
00772   QPoint p( contentsToViewport( e->pos() ) );
00773   QListViewItem *at = itemAt (p);
00774 
00775   // true if the root decoration of the item "at" was clicked (i.e. the +/- sign)
00776   bool rootDecoClicked = at
00777            && ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
00778                 treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() )
00779            && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
00780 
00781   if (e->button() == LeftButton && !rootDecoClicked)
00782   {
00783     //Start a drag
00784     d->startDragPos = e->pos();
00785 
00786     if (at)
00787     {
00788       d->validDrag = true;
00789       d->pressedOnSelected = at->isSelected();
00790     }
00791   }
00792 
00793   QListView::contentsMousePressEvent( e );
00794 }
00795 
00796 void KListView::contentsMouseMoveEvent( QMouseEvent *e )
00797 {
00798   if (!dragEnabled() || d->startDragPos.isNull() || !d->validDrag)
00799       QListView::contentsMouseMoveEvent (e);
00800 
00801   QPoint vp = contentsToViewport(e->pos());
00802   QListViewItem *item = itemAt( vp );
00803 
00804   //do we process cursor changes at all?
00805   if ( item && d->bChangeCursorOverItem && d->bUseSingle )
00806     {
00807       //Cursor moved on a new item or in/out the execute area
00808       if( (item != d->pCurrentItem) ||
00809           (isExecuteArea(vp) != d->cursorInExecuteArea) )
00810         {
00811           d->cursorInExecuteArea = isExecuteArea(vp);
00812 
00813           if( d->cursorInExecuteArea ) //cursor moved in execute area
00814             viewport()->setCursor( KCursor::handCursor() );
00815           else //cursor moved out of execute area
00816             viewport()->unsetCursor();
00817         }
00818     }
00819 
00820   bool dragOn = dragEnabled();
00821   QPoint newPos = e->pos();
00822   if (dragOn && d->validDrag &&
00823       (newPos.x() > d->startDragPos.x()+d->dragDelay ||
00824        newPos.x() < d->startDragPos.x()-d->dragDelay ||
00825        newPos.y() > d->startDragPos.y()+d->dragDelay ||
00826        newPos.y() < d->startDragPos.y()-d->dragDelay))
00827     //(d->startDragPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
00828     {
00829       QListView::contentsMouseReleaseEvent( 0 );
00830       startDrag();
00831       d->startDragPos = QPoint();
00832       d->validDrag = false;
00833     }
00834 }
00835 
00836 void KListView::contentsMouseReleaseEvent( QMouseEvent *e )
00837 {
00838   if (e->button() == LeftButton)
00839   {
00840     // If the row was already selected, maybe we want to start an in-place editing
00841     if ( d->pressedOnSelected && itemsRenameable() )
00842     {
00843       QPoint p( contentsToViewport( e->pos() ) );
00844       QListViewItem *at = itemAt (p);
00845       if ( at )
00846       {
00847         // true if the root decoration of the item "at" was clicked (i.e. the +/- sign)
00848         bool rootDecoClicked =
00849                   ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
00850                     treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() )
00851                && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
00852 
00853         if (!rootDecoClicked)
00854         {
00855           int col = header()->mapToLogical( header()->cellAt( p.x() ) );
00856           if ( d->renameable.contains(col) )
00857             rename(at, col);
00858         }
00859       }
00860     }
00861 
00862     d->pressedOnSelected = false;
00863     d->validDrag = false;
00864     d->startDragPos = QPoint();
00865   }
00866   QListView::contentsMouseReleaseEvent( e );
00867 }
00868 
00869 void KListView::contentsMouseDoubleClickEvent ( QMouseEvent *e )
00870 {
00871   // We don't want to call the parent method because it does setOpen,
00872   // whereas we don't do it in single click mode... (David)
00873   //QListView::contentsMouseDoubleClickEvent( e );
00874 
00875   QPoint vp = contentsToViewport(e->pos());
00876   QListViewItem *item = itemAt( vp );
00877   emit QListView::doubleClicked( item ); // we do it now
00878 
00879   int col = item ? header()->mapToLogical( header()->cellAt( vp.x() ) ) : -1;
00880 
00881   if( item ) {
00882     emit doubleClicked( item, e->globalPos(), col );
00883 
00884     if( (e->button() == LeftButton) && !d->bUseSingle )
00885       emitExecute( item, e->globalPos(), col );
00886   }
00887 }
00888 
00889 void KListView::slotMouseButtonClicked( int btn, QListViewItem *item, const QPoint &pos, int c )
00890 {
00891   if( (btn == LeftButton) && item )
00892     emitExecute(item, pos, c);
00893 }
00894 
00895 void KListView::contentsDropEvent(QDropEvent* e)
00896 {
00897   cleanDropVisualizer();
00898   cleanItemHighlighter();
00899   d->dragExpand.stop();
00900 
00901   if (acceptDrag (e))
00902   {
00903     e->acceptAction();
00904     QListViewItem *afterme;
00905     QListViewItem *parent;
00906     findDrop(e->pos(), parent, afterme);
00907 
00908     if (e->source() == viewport() && itemsMovable())
00909         movableDropEvent(parent, afterme);
00910     else
00911     {
00912         emit dropped(e, afterme);
00913         emit dropped(this, e, afterme);
00914         emit dropped(e, parent, afterme);
00915         emit dropped(this, e, parent, afterme);
00916     }
00917   }
00918 }
00919 
00920 void KListView::movableDropEvent (QListViewItem* parent, QListViewItem* afterme)
00921 {
00922   QPtrList<QListViewItem> items, afterFirsts, afterNows;
00923   QListViewItem *current=currentItem();
00924   bool hasMoved=false;
00925   for (QListViewItem *i = firstChild(), *iNext=0; i != 0; i = iNext)
00926   {
00927     iNext=i->itemBelow();
00928     if (!i->isSelected())
00929       continue;
00930 
00931     // don't drop an item after itself, or else
00932     // it moves to the top of the list
00933     if (i==afterme)
00934       continue;
00935 
00936     i->setSelected(false);
00937 
00938     QListViewItem *afterFirst = i->itemAbove();
00939 
00940         if (!hasMoved)
00941         {
00942                 emit aboutToMove();
00943                 hasMoved=true;
00944         }
00945 
00946     moveItem(i, parent, afterme);
00947 
00948     // ###### This should include the new parent !!! -> KDE 3.0
00949     // If you need this right now, have a look at keditbookmarks.
00950     emit moved(i, afterFirst, afterme);
00951 
00952     items.append (i);
00953     afterFirsts.append (afterFirst);
00954     afterNows.append (afterme);
00955 
00956     afterme = i;
00957   }
00958   clearSelection();
00959   for (QListViewItem *i=items.first(); i != 0; i=items.next() )
00960     i->setSelected(true);
00961   if (current)
00962     setCurrentItem(current);
00963 
00964   emit moved(items,afterFirsts,afterNows);
00965 
00966   if (firstChild())
00967     emit moved();
00968 }
00969 
00970 void KListView::contentsDragMoveEvent(QDragMoveEvent *event)
00971 {
00972   if (acceptDrag(event))
00973   {
00974     event->acceptAction();
00975     //Clean up the view
00976 
00977     findDrop(event->pos(), d->parentItemDrop, d->afterItemDrop);
00978     QPoint vp = contentsToViewport( event->pos() );
00979     QListViewItem *item = isExecuteArea( vp ) ? itemAt( vp ) : 0L;
00980 
00981     if ( item != d->dragOverItem )
00982     {
00983       d->dragExpand.stop();
00984       d->dragOverItem = item;
00985       d->dragOverPoint = vp;
00986       if ( d->dragOverItem && d->dragOverItem->isExpandable() && !d->dragOverItem->isOpen() )
00987         d->dragExpand.start( QApplication::startDragTime(), true );
00988     }
00989     if (dropVisualizer())
00990     {
00991       QRect tmpRect = drawDropVisualizer(0, d->parentItemDrop, d->afterItemDrop);
00992       if (tmpRect != d->mOldDropVisualizer)
00993       {
00994         cleanDropVisualizer();
00995         d->mOldDropVisualizer=tmpRect;
00996         viewport()->repaint(tmpRect);
00997       }
00998     }
00999     if (dropHighlighter())
01000     {
01001       QRect tmpRect = drawItemHighlighter(0, d->afterItemDrop);
01002       if (tmpRect != d->mOldDropHighlighter)
01003       {
01004         cleanItemHighlighter();
01005         d->mOldDropHighlighter=tmpRect;
01006         viewport()->repaint(tmpRect);
01007       }
01008     }
01009   }
01010   else
01011       event->ignore();
01012 }
01013 
01014 void KListView::slotDragExpand()
01015 {
01016   if ( itemAt( d->dragOverPoint ) == d->dragOverItem )
01017     d->dragOverItem->setOpen( true );
01018 }
01019 
01020 void KListView::contentsDragLeaveEvent (QDragLeaveEvent*)
01021 {
01022   d->dragExpand.stop();
01023   cleanDropVisualizer();
01024   cleanItemHighlighter();
01025 }
01026 
01027 void KListView::cleanDropVisualizer()
01028 {
01029   if (d->mOldDropVisualizer.isValid())
01030   {
01031     QRect rect=d->mOldDropVisualizer;
01032     d->mOldDropVisualizer = QRect();
01033     viewport()->repaint(rect, true);
01034   }
01035 }
01036 
01037 int KListView::depthToPixels( int depth )
01038 {
01039     return treeStepSize() * ( depth + (rootIsDecorated() ? 1 : 0) ) + itemMargin();
01040 }
01041 
01042 void KListView::findDrop(const QPoint &pos, QListViewItem *&parent, QListViewItem *&after)
01043 {
01044     QPoint p (contentsToViewport(pos));
01045 
01046     // Get the position to put it in
01047     QListViewItem *atpos = itemAt(p);
01048 
01049     QListViewItem *above;
01050     if (!atpos) // put it at the end
01051         above = lastItem();
01052     else
01053     {
01054         // Get the closest item before us ('atpos' or the one above, if any)
01055         if (p.y() - itemRect(atpos).topLeft().y() < (atpos->height()/2))
01056             above = atpos->itemAbove();
01057         else
01058             above = atpos;
01059     }
01060 
01061     if (above)
01062     {
01063         // if above has children, I might need to drop it as the first item there
01064 
01065         if (above->firstChild() && above->isOpen())
01066         {
01067             parent = above;
01068             after = 0;
01069             return;
01070         }
01071 
01072       // Now, we know we want to go after "above". But as a child or as a sibling ?
01073       // We have to ask the "above" item if it accepts children.
01074       if (above->isExpandable())
01075       {
01076           // The mouse is sufficiently on the right ? - doesn't matter if 'above' has visible children
01077           if (p.x() >= depthToPixels( above->depth() + 1 ) ||
01078               (above->isOpen() && above->childCount() > 0) )
01079           {
01080               parent = above;
01081               after = 0L;
01082               return;
01083           }
01084       }
01085 
01086       // Ok, there's one more level of complexity. We may want to become a new
01087       // sibling, but of an upper-level group, rather than the "above" item
01088       QListViewItem * betterAbove = above->parent();
01089       QListViewItem * last = above;
01090       while ( betterAbove )
01091       {
01092           // We are allowed to become a sibling of "betterAbove" only if we are
01093           // after its last child
01094           if ( last->nextSibling() == 0 )
01095           {
01096               if (p.x() < depthToPixels ( betterAbove->depth() + 1 ))
01097                   above = betterAbove; // store this one, but don't stop yet, there may be a better one
01098               else
01099                   break; // not enough on the left, so stop
01100               last = betterAbove;
01101               betterAbove = betterAbove->parent(); // up one level
01102           } else
01103               break; // we're among the child of betterAbove, not after the last one
01104       }
01105   }
01106   // set as sibling
01107   after = above;
01108   parent = after ? after->parent() : 0L ;
01109 }
01110 
01111 QListViewItem* KListView::lastChild () const
01112 {
01113   QListViewItem* lastchild = firstChild();
01114 
01115   if (lastchild)
01116         for (; lastchild->nextSibling(); lastchild = lastchild->nextSibling());
01117 
01118   return lastchild;
01119 }
01120 
01121 QListViewItem *KListView::lastItem() const
01122 {
01123   QListViewItem* last = lastChild();
01124 
01125   for (QListViewItemIterator it (last); it.current(); ++it)
01126     last = it.current();
01127 
01128   return last;
01129 }
01130 
01131 KLineEdit *KListView::renameLineEdit() const
01132 {
01133   return d->editor;
01134 }
01135 
01136 void KListView::startDrag()
01137 {
01138   QDragObject *drag = dragObject();
01139 
01140   if (!drag)
01141         return;
01142 
01143   if (drag->drag() && drag->target() != viewport())
01144     emit moved();
01145 }
01146 
01147 QDragObject *KListView::dragObject()
01148 {
01149   if (!currentItem())
01150         return 0;
01151 
01152   return new QStoredDrag("application/x-qlistviewitem", viewport());
01153 }
01154 
01155 void KListView::setItemsMovable(bool b)
01156 {
01157   d->itemsMovable=b;
01158 }
01159 
01160 bool KListView::itemsMovable() const
01161 {
01162   return d->itemsMovable;
01163 }
01164 
01165 void KListView::setItemsRenameable(bool b)
01166 {
01167   d->itemsRenameable=b;
01168 }
01169 
01170 bool KListView::itemsRenameable() const
01171 {
01172   return d->itemsRenameable;
01173 }
01174 
01175 
01176 void KListView::setDragEnabled(bool b)
01177 {
01178   d->dragEnabled=b;
01179 }
01180 
01181 bool KListView::dragEnabled() const
01182 {
01183   return d->dragEnabled;
01184 }
01185 
01186 void KListView::setAutoOpen(bool b)
01187 {
01188   d->autoOpen=b;
01189 }
01190 
01191 bool KListView::autoOpen() const
01192 {
01193   return d->autoOpen;
01194 }
01195 
01196 bool KListView::dropVisualizer() const
01197 {
01198   return d->dropVisualizer;
01199 }
01200 
01201 void KListView::setDropVisualizer(bool b)
01202 {
01203   d->dropVisualizer=b;
01204 }
01205 
01206 QPtrList<QListViewItem> KListView::selectedItems() const
01207 {
01208   QPtrList<QListViewItem> list;
01209 
01210   // Using selectionMode() instead of selectionModeExt() since for the cases that
01211   // we're interested in selectionMode() should work for either variety of the
01212   // setSelectionMode().
01213 
01214   switch(selectionMode())
01215   {
01216   case NoSelection:
01217       break;
01218   case Single:
01219       if(selectedItem())
01220           list.append(selectedItem());
01221       break;
01222   default:
01223   {
01224       QListViewItemIterator it(const_cast<KListView *>(this), QListViewItemIterator::Selected);
01225 
01226       for(; it.current(); ++it)
01227           list.append(it.current());
01228 
01229       break;
01230   }
01231   }
01232 
01233   return list;
01234 }
01235 
01236 
01237 void KListView::moveItem(QListViewItem *item, QListViewItem *parent, QListViewItem *after)
01238 {
01239   // sanity check - don't move a item into its own child structure
01240   QListViewItem *i = parent;
01241   while(i)
01242     {
01243       if(i == item)
01244         return;
01245       i = i->parent();
01246     }
01247 
01248   if (after)
01249   {
01250       item->moveItem(after);
01251       return;
01252   }
01253 
01254   // NOTE: This code shouldn't ever be reached if this method is used proprely,
01255   // QListVIew::moveItem() handles the same cases.  However, to avoid changing the (albeit
01256   // undocumented behavior) it's being left in for the moment.
01257 
01258   // Basically reimplementing the QListViewItem(QListViewItem*, QListViewItem*) constructor
01259   // in here, without ever deleting the item.
01260   if (item->parent())
01261         item->parent()->takeItem(item);
01262   else
01263         takeItem(item);
01264 
01265   if (parent)
01266         parent->insertItem(item);
01267   else
01268         insertItem(item);
01269 }
01270 
01271 void KListView::contentsDragEnterEvent(QDragEnterEvent *event)
01272 {
01273   if (acceptDrag (event))
01274     event->accept();
01275 }
01276 
01277 void KListView::setDropVisualizerWidth (int w)
01278 {
01279   d->mDropVisualizerWidth = w > 0 ? w : 1;
01280 }
01281 
01282 QRect KListView::drawDropVisualizer(QPainter *p, QListViewItem *parent,
01283                                     QListViewItem *after)
01284 {
01285     QRect insertmarker;
01286 
01287     if (!after && !parent)
01288         insertmarker = QRect (0, 0, viewport()->width(), d->mDropVisualizerWidth/2);
01289     else
01290     {
01291         int level = 0;
01292         if (after)
01293         {
01294             QListViewItem* it = 0L;
01295             if (after->isOpen())
01296             {
01297                 // Look for the last child (recursively)
01298                 it = after->firstChild();
01299                 if (it)
01300                     while (it->nextSibling() || it->firstChild())
01301                         if ( it->nextSibling() )
01302                             it = it->nextSibling();
01303                         else
01304                             it = it->firstChild();
01305             }
01306 
01307             insertmarker = itemRect (it ? it : after);
01308             level = after->depth();
01309         }
01310         else if (parent)
01311         {
01312             insertmarker = itemRect (parent);
01313             level = parent->depth() + 1;
01314         }
01315         insertmarker.setLeft( treeStepSize() * ( level + (rootIsDecorated() ? 1 : 0) ) + itemMargin() );
01316         insertmarker.setRight (viewport()->width());
01317         insertmarker.setTop (insertmarker.bottom() - d->mDropVisualizerWidth/2 + 1);
01318         insertmarker.setBottom (insertmarker.bottom() + d->mDropVisualizerWidth/2);
01319     }
01320 
01321     // This is not used anymore, at least by KListView itself (see viewportPaintEvent)
01322     // Remove for KDE 3.0.
01323     if (p)
01324         p->fillRect(insertmarker, Dense4Pattern);
01325 
01326     return insertmarker;
01327 }
01328 
01329 QRect KListView::drawItemHighlighter(QPainter *painter, QListViewItem *item)
01330 {
01331   QRect r;
01332 
01333   if (item)
01334   {
01335     r = itemRect(item);
01336     r.setLeft(r.left()+(item->depth()+1)*treeStepSize());
01337     if (painter)
01338       style().drawPrimitive(QStyle::PE_FocusRect, painter, r, colorGroup(),
01339                             QStyle::Style_FocusAtBorder, colorGroup().highlight());
01340   }
01341 
01342   return r;
01343 }
01344 
01345 void KListView::cleanItemHighlighter ()
01346 {
01347   if (d->mOldDropHighlighter.isValid())
01348   {
01349     QRect rect=d->mOldDropHighlighter;
01350     d->mOldDropHighlighter = QRect();
01351     viewport()->repaint(rect, true);
01352   }
01353 }
01354 
01355 void KListView::rename(QListViewItem *item, int c)
01356 {
01357   if (d->renameable.contains(c))
01358   {
01359     ensureItemVisible(item);
01360     d->editor->load(item,c);
01361   }
01362 }
01363 
01364 bool KListView::isRenameable (int col) const
01365 {
01366   return d->renameable.contains(col);
01367 }
01368 
01369 void KListView::setRenameable (int col, bool yesno)
01370 {
01371   if (col>=header()->count()) return;
01372 
01373   d->renameable.remove(col);
01374   if (yesno && d->renameable.find(col)==d->renameable.end())
01375     d->renameable+=col;
01376   else if (!yesno && d->renameable.find(col)!=d->renameable.end())
01377     d->renameable.remove(col);
01378 }
01379 
01380 void KListView::doneEditing(QListViewItem *item, int row)
01381 {
01382   emit itemRenamed(item, item->text(row), row);
01383   emit itemRenamed(item);
01384 }
01385 
01386 bool KListView::acceptDrag(QDropEvent* e) const
01387 {
01388   return acceptDrops() && itemsMovable() && (e->source()==viewport());
01389 }
01390 
01391 void KListView::setCreateChildren(bool b)
01392 {
01393         d->createChildren=b;
01394 }
01395 
01396 bool KListView::createChildren() const
01397 {
01398         return d->createChildren;
01399 }
01400 
01401 
01402 int KListView::tooltipColumn() const
01403 {
01404         return d->tooltipColumn;
01405 }
01406 
01407 void KListView::setTooltipColumn(int column)
01408 {
01409         d->tooltipColumn=column;
01410 }
01411 
01412 void KListView::setDropHighlighter(bool b)
01413 {
01414         d->dropHighlighter=b;
01415 }
01416 
01417 bool KListView::dropHighlighter() const
01418 {
01419         return d->dropHighlighter;
01420 }
01421 
01422 bool KListView::showTooltip(QListViewItem *item, const QPoint &, int column) const
01423 {
01424         return ((tooltip(item, column).length()>0) && (column==tooltipColumn()));
01425 }
01426 
01427 QString KListView::tooltip(QListViewItem *item, int column) const
01428 {
01429         return item->text(column);
01430 }
01431 
01432 void KListView::setTabOrderedRenaming(bool b)
01433 {
01434     d->tabRename = b;
01435 }
01436 
01437 bool KListView::tabOrderedRenaming() const
01438 {
01439     return d->tabRename;
01440 }
01441 
01442 void KListView::keyPressEvent (QKeyEvent* e)
01443 {
01444   //don't we need a contextMenuModifier too ? (aleXXX)
01445   if (e->key() == d->contextMenuKey)
01446         {
01447           emit menuShortCutPressed (this, currentItem());
01448           return;
01449         }
01450 
01451   if (d->selectionMode != FileManager)
01452         QListView::keyPressEvent (e);
01453   else
01454         fileManagerKeyPressEvent (e);
01455 }
01456 
01457 void KListView::activateAutomaticSelection()
01458 {
01459    d->selectedBySimpleMove=true;
01460    d->selectedUsingMouse=false;
01461    if (currentItem()!=0)
01462    {
01463       currentItem()->setSelected(true);
01464       currentItem()->repaint();
01465       emit selectionChanged();
01466    };
01467 }
01468 
01469 void KListView::deactivateAutomaticSelection()
01470 {
01471    d->selectedBySimpleMove=false;
01472 }
01473 
01474 bool KListView::automaticSelection() const
01475 {
01476    return d->selectedBySimpleMove;
01477 }
01478 
01479 void KListView::fileManagerKeyPressEvent (QKeyEvent* e)
01480 {
01481    //don't care whether it's on the keypad or not
01482     int e_state=(e->state() & ~Keypad);
01483 
01484     int oldSelectionDirection(d->selectionDirection);
01485 
01486     if ((e->key()!=Key_Shift) && (e->key()!=Key_Control)
01487         && (e->key()!=Key_Meta) && (e->key()!=Key_Alt))
01488     {
01489        if ((e_state==ShiftButton) && (!d->wasShiftEvent) && (!d->selectedBySimpleMove))
01490           selectAll(false);
01491        d->selectionDirection=0;
01492        d->wasShiftEvent = (e_state == ShiftButton);
01493     };
01494 
01495     //d->wasShiftEvent = (e_state == ShiftButton);
01496 
01497 
01498     QListViewItem* item = currentItem();
01499     if (item==0) return;
01500 
01501     QListViewItem* repaintItem1 = item;
01502     QListViewItem* repaintItem2 = 0L;
01503     QListViewItem* visItem = 0L;
01504 
01505     QListViewItem* nextItem = 0L;
01506     int items = 0;
01507 
01508     bool shiftOrCtrl((e_state==ControlButton) || (e_state==ShiftButton));
01509     int selectedItems(0);
01510     for (QListViewItem *tmpItem=firstChild(); tmpItem!=0; tmpItem=tmpItem->nextSibling())
01511        if (tmpItem->isSelected()) selectedItems++;
01512 
01513     if (((selectedItems==0) || ((selectedItems==1) && (d->selectedUsingMouse)))
01514         && (e_state==NoButton)
01515         && ((e->key()==Key_Down)
01516         || (e->key()==Key_Up)
01517         || (e->key()==Key_Next)
01518         || (e->key()==Key_Prior)
01519         || (e->key()==Key_Home)
01520         || (e->key()==Key_End)))
01521     {
01522        d->selectedBySimpleMove=true;
01523        d->selectedUsingMouse=false;
01524     }
01525     else if (selectedItems>1)
01526        d->selectedBySimpleMove=false;
01527 
01528     bool emitSelectionChanged(false);
01529 
01530     switch (e->key())
01531     {
01532     case Key_Escape:
01533        selectAll(false);
01534        emitSelectionChanged=true;
01535        break;
01536 
01537     case Key_Space:
01538        //toggle selection of current item
01539        if (d->selectedBySimpleMove)
01540           d->selectedBySimpleMove=false;
01541        item->setSelected(!item->isSelected());
01542        emitSelectionChanged=true;
01543        break;
01544 
01545     case Key_Insert:
01546        //toggle selection of current item and move to the next item
01547        if (d->selectedBySimpleMove)
01548        {
01549           d->selectedBySimpleMove=false;
01550           if (!item->isSelected()) item->setSelected(true);
01551        }
01552        else
01553        {
01554           item->setSelected(!item->isSelected());
01555        };
01556 
01557        nextItem=item->itemBelow();
01558 
01559        if (nextItem!=0)
01560        {
01561           repaintItem2=nextItem;
01562           visItem=nextItem;
01563           setCurrentItem(nextItem);
01564        };
01565        d->selectionDirection=1;
01566        emitSelectionChanged=true;
01567        break;
01568 
01569     case Key_Down:
01570        nextItem=item->itemBelow();
01571        //toggle selection of current item and move to the next item
01572        if (shiftOrCtrl)
01573        {
01574           d->selectionDirection=1;
01575           if (d->selectedBySimpleMove)
01576              d->selectedBySimpleMove=false;
01577           else
01578           {
01579              if (oldSelectionDirection!=-1)
01580              {
01581                 item->setSelected(!item->isSelected());
01582                 emitSelectionChanged=true;
01583              };
01584           };
01585        }
01586        else if ((d->selectedBySimpleMove) && (nextItem!=0))
01587        {
01588           item->setSelected(false);
01589           emitSelectionChanged=true;
01590        };
01591 
01592        if (nextItem!=0)
01593        {
01594           if (d->selectedBySimpleMove)
01595              nextItem->setSelected(true);
01596           repaintItem2=nextItem;
01597           visItem=nextItem;
01598           setCurrentItem(nextItem);
01599        };
01600        break;
01601 
01602     case Key_Up:
01603        nextItem=item->itemAbove();
01604        d->selectionDirection=-1;
01605        //move to the prev. item and toggle selection of this one
01606        // => No, can't select the last item, with this. For symmetry, let's
01607        // toggle selection and THEN move up, just like we do in down (David)
01608        if (shiftOrCtrl)
01609        {
01610           if (d->selectedBySimpleMove)
01611              d->selectedBySimpleMove=false;
01612           else
01613           {
01614              if (oldSelectionDirection!=1)
01615              {
01616                 item->setSelected(!item->isSelected());
01617                 emitSelectionChanged=true;
01618              };
01619           }
01620        }
01621        else if ((d->selectedBySimpleMove) && (nextItem!=0))
01622        {
01623           item->setSelected(false);
01624           emitSelectionChanged=true;
01625        };
01626 
01627        if (nextItem!=0)
01628        {
01629           if (d->selectedBySimpleMove)
01630              nextItem->setSelected(true);
01631           repaintItem2=nextItem;
01632           visItem=nextItem;
01633           setCurrentItem(nextItem);
01634        };
01635        break;
01636 
01637     case Key_End:
01638        //move to the last item and toggle selection of all items inbetween
01639        nextItem=item;
01640        if (d->selectedBySimpleMove)
01641           item->setSelected(false);
01642        if (shiftOrCtrl)
01643           d->selectedBySimpleMove=false;
01644 
01645        while(nextItem!=0)
01646        {
01647           if (shiftOrCtrl)
01648              nextItem->setSelected(!nextItem->isSelected());
01649           if (nextItem->itemBelow()==0)
01650           {
01651              if (d->selectedBySimpleMove)
01652                 nextItem->setSelected(true);
01653              repaintItem2=nextItem;
01654              visItem=nextItem;
01655              setCurrentItem(nextItem);
01656           }
01657           nextItem=nextItem->itemBelow();
01658        }
01659        emitSelectionChanged=true;
01660        break;
01661 
01662     case Key_Home:
01663        // move to the first item and toggle selection of all items inbetween
01664        nextItem = firstChild();
01665        visItem = nextItem;
01666        repaintItem2 = visItem;
01667        if (d->selectedBySimpleMove)
01668           item->setSelected(false);
01669        if (shiftOrCtrl)
01670        {
01671           d->selectedBySimpleMove=false;
01672 
01673           while ( nextItem != item )
01674           {
01675              nextItem->setSelected( !nextItem->isSelected() );
01676              nextItem = nextItem->itemBelow();
01677           }
01678           item->setSelected( !item->isSelected() );
01679        }
01680        setCurrentItem( firstChild() );
01681        emitSelectionChanged=true;
01682        break;
01683 
01684     case Key_Next:
01685        items=visibleHeight()/item->height();
01686        nextItem=item;
01687        if (d->selectedBySimpleMove)
01688           item->setSelected(false);
01689        if (shiftOrCtrl)
01690        {
01691           d->selectedBySimpleMove=false;
01692           d->selectionDirection=1;
01693        };
01694 
01695        for (int i=0; i<items; i++)
01696        {
01697           if (shiftOrCtrl)
01698              nextItem->setSelected(!nextItem->isSelected());
01699           //the end
01700           if ((i==items-1) || (nextItem->itemBelow()==0))
01701 
01702           {
01703              if (shiftOrCtrl)
01704                 nextItem->setSelected(!nextItem->isSelected());
01705              if (d->selectedBySimpleMove)
01706                 nextItem->setSelected(true);
01707              ensureItemVisible(nextItem);
01708              setCurrentItem(nextItem);
01709              update();
01710              if ((shiftOrCtrl) || (d->selectedBySimpleMove))
01711              {
01712                 emit selectionChanged();
01713              }
01714              return;
01715           }
01716           nextItem=nextItem->itemBelow();
01717        }
01718        break;
01719 
01720     case Key_Prior:
01721        items=visibleHeight()/item->height();
01722        nextItem=item;
01723        if (d->selectedBySimpleMove)
01724           item->setSelected(false);
01725        if (shiftOrCtrl)
01726        {
01727           d->selectionDirection=-1;
01728           d->selectedBySimpleMove=false;
01729        };
01730 
01731        for (int i=0; i<items; i++)
01732        {
01733           if ((nextItem!=item) &&(shiftOrCtrl))
01734              nextItem->setSelected(!nextItem->isSelected());
01735           //the end
01736           if ((i==items-1) || (nextItem->itemAbove()==0))
01737 
01738           {
01739              if (d->selectedBySimpleMove)
01740                 nextItem->setSelected(true);
01741              ensureItemVisible(nextItem);
01742              setCurrentItem(nextItem);
01743              update();
01744              if ((shiftOrCtrl) || (d->selectedBySimpleMove))
01745              {
01746                 emit selectionChanged();
01747              }
01748              return;
01749           }
01750           nextItem=nextItem->itemAbove();
01751        }
01752        break;
01753 
01754     case Key_Minus:
01755        if ( item->isOpen() )
01756           setOpen( item, false );
01757        break;
01758     case Key_Plus:
01759        if (  !item->isOpen() && (item->isExpandable() || item->childCount()) )
01760           setOpen( item, true );
01761        break;
01762     default:
01763        bool realKey = ((e->key()!=Key_Shift) && (e->key()!=Key_Control)
01764                         && (e->key()!=Key_Meta) && (e->key()!=Key_Alt));
01765 
01766        bool selectCurrentItem = (d->selectedBySimpleMove) && (item->isSelected());
01767        if (realKey && selectCurrentItem)
01768           item->setSelected(false);
01769        //this is mainly for the "goto filename beginning with pressed char" feature (aleXXX)
01770        QListView::SelectionMode oldSelectionMode = selectionMode();
01771        setSelectionMode (QListView::Multi);
01772        QListView::keyPressEvent (e);
01773        setSelectionMode (oldSelectionMode);
01774        if (realKey && selectCurrentItem)
01775        {
01776           currentItem()->setSelected(true);
01777           emitSelectionChanged=true;
01778        }
01779        repaintItem2=currentItem();
01780        if (realKey)
01781           visItem=currentItem();
01782        break;
01783     }
01784 
01785     if (visItem)
01786        ensureItemVisible(visItem);
01787 
01788     QRect ir;
01789     if (repaintItem1)
01790        ir = ir.unite( itemRect(repaintItem1) );
01791     if (repaintItem2)
01792        ir = ir.unite( itemRect(repaintItem2) );
01793 
01794     if ( !ir.isEmpty() )
01795     {                 // rectangle to be repainted
01796        if ( ir.x() < 0 )
01797           ir.moveBy( -ir.x(), 0 );
01798        viewport()->repaint( ir, false );
01799     }
01800     /*if (repaintItem1)
01801        repaintItem1->repaint();
01802     if (repaintItem2)
01803        repaintItem2->repaint();*/
01804     update();
01805     if (emitSelectionChanged)
01806        emit selectionChanged();
01807 }
01808 
01809 void KListView::setSelectionModeExt (SelectionModeExt mode)
01810 {
01811     d->selectionMode = mode;
01812 
01813     switch (mode)
01814     {
01815     case Single:
01816     case Multi:
01817     case Extended:
01818     case NoSelection:
01819         setSelectionMode (static_cast<QListView::SelectionMode>(static_cast<int>(mode)));
01820         break;
01821 
01822     case FileManager:
01823         setSelectionMode (QListView::Extended);
01824         break;
01825 
01826     default:
01827         kdWarning () << "Warning: illegal selection mode " << int(mode) << " set!" << endl;
01828         break;
01829     }
01830 }
01831 
01832 KListView::SelectionModeExt KListView::selectionModeExt () const
01833 {
01834   return d->selectionMode;
01835 }
01836 
01837 int KListView::itemIndex( const QListViewItem *item ) const
01838 {
01839     if ( !item )
01840         return -1;
01841 
01842     if ( item == firstChild() )
01843         return 0;
01844     else {
01845         QListViewItemIterator it(firstChild());
01846         uint j = 0;
01847         for (; it.current() && it.current() != item; ++it, ++j );
01848 
01849         if( !it.current() )
01850           return -1;
01851 
01852         return j;
01853     }
01854 }
01855 
01856 QListViewItem* KListView::itemAtIndex(int index)
01857 {
01858    if (index<0)
01859       return 0;
01860 
01861    int j(0);
01862    for (QListViewItemIterator it=firstChild(); it.current(); it++)
01863    {
01864       if (j==index)
01865          return it.current();
01866       j++;
01867    };
01868    return 0;
01869 }
01870 
01871 
01872 void KListView::emitContextMenu (KListView*, QListViewItem* i)
01873 {
01874   QPoint p;
01875 
01876   if (i)
01877         p = viewport()->mapToGlobal(itemRect(i).center());
01878   else
01879         p = mapToGlobal(rect().center());
01880 
01881   emit contextMenu (this, i, p);
01882 }
01883 
01884 void KListView::emitContextMenu (QListViewItem* i, const QPoint& p, int)
01885 {
01886   emit contextMenu (this, i, p);
01887 }
01888 
01889 void KListView::setAcceptDrops (bool val)
01890 {
01891   QListView::setAcceptDrops (val);
01892   viewport()->setAcceptDrops (val);
01893 }
01894 
01895 int KListView::dropVisualizerWidth () const
01896 {
01897         return d->mDropVisualizerWidth;
01898 }
01899 
01900 
01901 void KListView::viewportPaintEvent(QPaintEvent *e)
01902 {
01903   d->paintAbove = 0;
01904   d->paintCurrent = 0;
01905   d->paintBelow = 0;
01906   d->painting = true;
01907 
01908   QListView::viewportPaintEvent(e);
01909 
01910   if (d->mOldDropVisualizer.isValid() && e->rect().intersects(d->mOldDropVisualizer))
01911     {
01912       QPainter painter(viewport());
01913 
01914       // This is where we actually draw the drop-visualizer
01915       painter.fillRect(d->mOldDropVisualizer, Dense4Pattern);
01916     }
01917   if (d->mOldDropHighlighter.isValid() && e->rect().intersects(d->mOldDropHighlighter))
01918     {
01919       QPainter painter(viewport());
01920 
01921       // This is where we actually draw the drop-highlighter
01922       style().drawPrimitive(QStyle::PE_FocusRect, &painter, d->mOldDropHighlighter, colorGroup(),
01923                             QStyle::Style_FocusAtBorder);
01924     }
01925   d->painting = false;
01926 }
01927 
01928 void KListView::setFullWidth()
01929 {
01930   setFullWidth(true);
01931 }
01932 
01933 void KListView::setFullWidth(bool fullWidth)
01934 {
01935   d->fullWidth = fullWidth;
01936   header()->setStretchEnabled(fullWidth, columns()-1);
01937 }
01938 
01939 bool KListView::fullWidth() const
01940 {
01941   return d->fullWidth;
01942 }
01943 
01944 int KListView::addColumn(const QString& label, int width)
01945 {
01946   int result = QListView::addColumn(label, width);
01947   if (d->fullWidth) {
01948     header()->setStretchEnabled(false, columns()-2);
01949     header()->setStretchEnabled(true, columns()-1);
01950   }
01951   return result;
01952 }
01953 
01954 int KListView::addColumn(const QIconSet& iconset, const QString& label, int width)
01955 {
01956   int result = QListView::addColumn(iconset, label, width);
01957   if (d->fullWidth) {
01958     header()->setStretchEnabled(false, columns()-2);
01959     header()->setStretchEnabled(true, columns()-1);
01960   }
01961   return result;
01962 }
01963 
01964 void KListView::removeColumn(int index)
01965 {
01966   QListView::removeColumn(index);
01967   if (d->fullWidth && index == columns()) header()->setStretchEnabled(true, columns()-1);
01968 }
01969 
01970 void KListView::viewportResizeEvent(QResizeEvent* e)
01971 {
01972   QListView::viewportResizeEvent(e);
01973 }
01974 
01975 const QColor &KListView::alternateBackground() const
01976 {
01977   return d->alternateBackground;
01978 }
01979 
01980 void KListView::setAlternateBackground(const QColor &c)
01981 {
01982   d->alternateBackground = c;
01983   repaint();
01984 }
01985 
01986 void KListView::saveLayout(KConfig *config, const QString &group) const
01987 {
01988   KConfigGroupSaver saver(config, group);
01989   QStringList widths, order;
01990   for (int i = 0; i < columns(); ++i)
01991   {
01992     widths << QString::number(columnWidth(i));
01993     order << QString::number(header()->mapToIndex(i));
01994   }
01995   config->writeEntry("ColumnWidths", widths);
01996   config->writeEntry("ColumnOrder", order);
01997   config->writeEntry("SortColumn", d->sortColumn);
01998   config->writeEntry("SortAscending", d->sortAscending);
01999 }
02000 
02001 void KListView::restoreLayout(KConfig *config, const QString &group)
02002 {
02003   KConfigGroupSaver saver(config, group);
02004   QStringList cols = config->readListEntry("ColumnWidths");
02005   int i = 0;
02006   for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it)
02007     setColumnWidth(i++, (*it).toInt());
02008 
02009   cols = config->readListEntry("ColumnOrder");
02010   i = 0;
02011   for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it)
02012     header()->moveSection(i++, (*it).toInt());
02013   if (config->hasKey("SortColumn"))
02014     setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true));
02015 }
02016 
02017 void KListView::setSorting(int column, bool ascending)
02018 {
02019   d->sortColumn = column;
02020   d->sortAscending = ascending;
02021   QListView::setSorting(column, ascending);
02022   
02023   QListViewItem* item = firstChild();
02024   while ( item ) {
02025     KListViewItem *kItem = dynamic_cast<KListViewItem*>(item);
02026     if (kItem) kItem->m_known = false;
02027     item = item->itemBelow();
02028   }
02029 }
02030 
02031 int KListView::columnSorted(void) const
02032 {
02033   return d->sortColumn;
02034 }
02035 
02036 bool KListView::ascendingSort(void) const
02037 {
02038   return d->sortAscending;
02039 }
02040 
02041 void KListView::takeItem(QListViewItem *item)
02042 {
02043   if(item && item == d->editor->currentItem())
02044     d->editor->terminate();
02045 
02046   QListView::takeItem(item);
02047 }
02048 
02049 void KListView::disableAutoSelection()
02050 {
02051   if ( d->disableAutoSelection )
02052     return;
02053 
02054   d->disableAutoSelection = true;
02055   d->autoSelect.stop();
02056   d->autoSelectDelay = -1;
02057 }
02058 
02059 void KListView::resetAutoSelection()
02060 {
02061   if ( !d->disableAutoSelection )
02062     return;
02063 
02064   d->disableAutoSelection = false;
02065   d->autoSelectDelay = KGlobalSettings::autoSelectDelay();
02066 }
02067 
02068 void KListView::doubleClicked( QListViewItem *item, const QPoint &pos, int c )
02069 {
02070   emit QListView::doubleClicked( item, pos, c );
02071 }
02072 
02073 KListViewItem::KListViewItem(QListView *parent)
02074   : QListViewItem(parent)
02075 {
02076   init();
02077 }
02078 
02079 KListViewItem::KListViewItem(QListViewItem *parent)
02080   : QListViewItem(parent)
02081 {
02082   init();
02083 }
02084 
02085 KListViewItem::KListViewItem(QListView *parent, QListViewItem *after)
02086   : QListViewItem(parent, after)
02087 {
02088   init();
02089 }
02090 
02091 KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after)
02092   : QListViewItem(parent, after)
02093 {
02094   init();
02095 }
02096 
02097 KListViewItem::KListViewItem(QListView *parent,
02098     QString label1, QString label2, QString label3, QString label4,
02099     QString label5, QString label6, QString label7, QString label8)
02100   : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8)
02101 {
02102   init();
02103 }
02104 
02105 KListViewItem::KListViewItem(QListViewItem *parent,
02106     QString label1, QString label2, QString label3, QString label4,
02107     QString label5, QString label6, QString label7, QString label8)
02108   : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8)
02109 {
02110   init();
02111 }
02112 
02113 KListViewItem::KListViewItem(QListView *parent, QListViewItem *after,
02114     QString label1, QString label2, QString label3, QString label4,
02115     QString label5, QString label6, QString label7, QString label8)
02116   : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8)
02117 {
02118   init();
02119 }
02120 
02121 KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after,
02122     QString label1, QString label2, QString label3, QString label4,
02123     QString label5, QString label6, QString label7, QString label8)
02124   : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8)
02125 {
02126   init();
02127 }
02128 
02129 KListViewItem::~KListViewItem()
02130 {
02131   if(listView())
02132     emit static_cast<KListView *>(listView())->itemRemoved(this);
02133 }
02134 
02135 void KListViewItem::init()
02136 {
02137   m_odd = m_known = false;
02138   KListView *lv = static_cast<KListView *>(listView());
02139   setDragEnabled( dragEnabled() || lv->dragEnabled() );
02140   emit lv->itemAdded(this);
02141 }
02142 
02143 void KListViewItem::insertItem(QListViewItem *item)
02144 {
02145   QListViewItem::insertItem(item);
02146   if(listView())
02147     emit static_cast<KListView *>(listView())->itemAdded(item);
02148 }
02149 
02150 void KListViewItem::takeItem(QListViewItem *item)
02151 {
02152   QListViewItem::takeItem(item);
02153   if(listView())
02154     emit static_cast<KListView *>(listView())->itemRemoved(item);
02155 }
02156 
02157 const QColor &KListViewItem::backgroundColor()
02158 {
02159   if (isAlternate())
02160     return static_cast< KListView* >(listView())->alternateBackground();
02161   return listView()->viewport()->colorGroup().base();
02162 }
02163 
02164 bool KListViewItem::isAlternate()
02165 {
02166   KListView *lv = static_cast<KListView *>(listView());
02167   if (lv && lv->alternateBackground().isValid())
02168   {
02169     KListViewItem *above;
02170 
02171     // Ok, there's some weirdness here that requires explanation as this is a
02172     // speed hack.  itemAbove() is a O(n) operation (though this isn't
02173     // immediately clear) so we want to call it as infrequently as possible --
02174     // especially in the case of painting a cell.
02175     //
02176     // So, in the case that we *are* painting a cell:  (1) we're assuming that
02177     // said painting is happening top to bottem -- this assumption is present
02178     // elsewhere in the implementation of this class, (2) itemBelow() is fast --
02179     // roughly constant time.
02180     //
02181     // Given these assumptions we can do a mixture of caching and telling the
02182     // next item that the when that item is the current item that the now
02183     // current item will be the item above it.
02184     //
02185     // Ideally this will make checking to see if the item above the current item
02186     // is the alternate color a constant time operation rather than 0(n).
02187 
02188     if (lv->d->painting) {
02189       if (lv->d->paintCurrent != this)
02190       {
02191         lv->d->paintAbove = lv->d->paintBelow == this ? lv->d->paintCurrent : itemAbove();
02192         lv->d->paintCurrent = this;
02193         lv->d->paintBelow = itemBelow();
02194       }
02195 
02196       above = dynamic_cast<KListViewItem *>(lv->d->paintAbove);
02197     }
02198     else
02199     {
02200       above = dynamic_cast<KListViewItem *>(itemAbove());
02201     }
02202 
02203     m_known = above ? above->m_known : true;
02204     if (m_known)
02205     {
02206        m_odd = above ? !above->m_odd : false;
02207     }
02208     else
02209     {
02210        KListViewItem *item;
02211        bool previous = true;
02212        if (parent())
02213        {
02214           item = dynamic_cast<KListViewItem *>(parent());
02215           if (item)
02216              previous = item->m_odd;
02217           item = dynamic_cast<KListViewItem *>(parent()->firstChild());
02218        }
02219        else
02220        {
02221           item = dynamic_cast<KListViewItem *>(lv->firstChild());
02222        }
02223 
02224        while(item)
02225        {
02226           item->m_odd = previous = !previous;
02227           item->m_known = true;
02228           item = dynamic_cast<KListViewItem *>(item->nextSibling());
02229        }
02230     }
02231     return m_odd;
02232   }
02233   return false;
02234 }
02235 
02236 void KListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
02237 {
02238   QColorGroup _cg = cg;
02239   const QPixmap *pm = listView()->viewport()->backgroundPixmap();
02240   if (pm && !pm->isNull())
02241   {
02242         _cg.setBrush(QColorGroup::Base, QBrush(backgroundColor(), *pm));
02243         QPoint o = p->brushOrigin();
02244         p->setBrushOrigin( o.x()-listView()->contentsX(), o.y()-listView()->contentsY() );
02245   }
02246   else if (isAlternate())
02247        if (listView()->viewport()->backgroundMode()==Qt::FixedColor)
02248             _cg.setColor(QColorGroup::Background, static_cast< KListView* >(listView())->alternateBackground());
02249        else
02250         _cg.setColor(QColorGroup::Base, static_cast< KListView* >(listView())->alternateBackground());
02251 
02252   QListViewItem::paintCell(p, _cg, column, width, alignment);
02253 }
02254 
02255 void KListView::virtual_hook( int, void* )
02256 { /*BASE::virtual_hook( id, data );*/ }
02257 
02258 #include "klistview.moc"
02259 #include "klistviewlineedit.moc"
02260 
02261 // vim: noet
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Jan 15 13:32:53 2006 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003