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 == AlignRight || ca == AlignAuto )
00495         width += item->width( fontMetrics(), this, 0 );
00496     }
00497 
00498     return ( x > offset && x < ( offset + width ) );
00499   }
00500 }
00501 
00502 void KListView::slotOnItem( QListViewItem *item )
00503 {
00504   QPoint vp = viewport()->mapFromGlobal( QCursor::pos() );
00505   if ( item && isExecuteArea( vp.x() ) && (d->autoSelectDelay > -1) && d->bUseSingle ) {
00506     d->autoSelect.start( d->autoSelectDelay, true );
00507     d->pCurrentItem = item;
00508   }
00509 }
00510 
00511 void KListView::slotOnViewport()
00512 {
00513   if ( d->bChangeCursorOverItem )
00514     viewport()->unsetCursor();
00515 
00516   d->autoSelect.stop();
00517   d->pCurrentItem = 0L;
00518 }
00519 
00520 void KListView::slotSettingsChanged(int category)
00521 {
00522   switch (category)
00523   {
00524   case KApplication::SETTINGS_MOUSE:
00525     d->dragDelay =  KGlobalSettings::dndEventDelay();
00526     d->bUseSingle = KGlobalSettings::singleClick();
00527 
00528     disconnect(this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
00529                this, SLOT (slotMouseButtonClicked (int, QListViewItem*, const QPoint &, int)));
00530 
00531     if( d->bUseSingle )
00532       connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
00533                this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int)));
00534 
00535     d->bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon();
00536     if ( !d->disableAutoSelection )
00537       d->autoSelectDelay = KGlobalSettings::autoSelectDelay();
00538 
00539     if( !d->bUseSingle || !d->bChangeCursorOverItem )
00540        viewport()->unsetCursor();
00541 
00542     break;
00543 
00544   case KApplication::SETTINGS_POPUPMENU:
00545     d->contextMenuKey = KGlobalSettings::contextMenuKey ();
00546     d->showContextMenusOnPress = KGlobalSettings::showContextMenusOnPress ();
00547 
00548     if (d->showContextMenusOnPress)
00549     {
00550       disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00551 
00552       connect(this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)),
00553               this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00554     }
00555     else
00556     {
00557       disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00558 
00559       connect(this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)),
00560               this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
00561     }
00562     break;
00563 
00564   default:
00565     break;
00566   }
00567 }
00568 
00569 void KListView::slotAutoSelect()
00570 {
00571   // check that the item still exists
00572   if( itemIndex( d->pCurrentItem ) == -1 )
00573     return;
00574 
00575   if (!isActiveWindow())
00576         {
00577           d->autoSelect.stop();
00578           return;
00579         }
00580 
00581   //Give this widget the keyboard focus.
00582   if( !hasFocus() )
00583     setFocus();
00584 
00585 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00586   // FIXME(E): Implement for Qt Embedded
00587   uint keybstate = KApplication::keyboardModifiers();
00588 #endif
00589 
00590   QListViewItem* previousItem = currentItem();
00591   setCurrentItem( d->pCurrentItem );
00592 
00593 //#ifndef Q_WS_QWS
00594 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00595   // FIXME(E): Implement for Qt Embedded
00596   if( d->pCurrentItem ) {
00597     //Shift pressed?
00598     if( (keybstate & KApplication::ShiftModifier) ) {
00599       bool block = signalsBlocked();
00600       blockSignals( true );
00601 
00602       //No Ctrl? Then clear before!
00603       if( !(keybstate & KApplication::ControlModifier) )
00604                 clearSelection();
00605 
00606       bool select = !d->pCurrentItem->isSelected();
00607       bool update = viewport()->isUpdatesEnabled();
00608       viewport()->setUpdatesEnabled( false );
00609 
00610       bool down = previousItem->itemPos() < d->pCurrentItem->itemPos();
00611       QListViewItemIterator lit( down ? previousItem : d->pCurrentItem );
00612       for ( ; lit.current(); ++lit ) {
00613                 if ( down && lit.current() == d->pCurrentItem ) {
00614                   d->pCurrentItem->setSelected( select );
00615                   break;
00616                 }
00617                 if ( !down && lit.current() == previousItem ) {
00618                   previousItem->setSelected( select );
00619                   break;
00620                 }
00621                 lit.current()->setSelected( select );
00622       }
00623 
00624       blockSignals( block );
00625       viewport()->setUpdatesEnabled( update );
00626       triggerUpdate();
00627 
00628       emit selectionChanged();
00629 
00630       if( selectionMode() == QListView::Single )
00631                 emit selectionChanged( d->pCurrentItem );
00632     }
00633     else if( (keybstate & KApplication::ControlModifier) )
00634       setSelected( d->pCurrentItem, !d->pCurrentItem->isSelected() );
00635     else {
00636       bool block = signalsBlocked();
00637       blockSignals( true );
00638 
00639       if( !d->pCurrentItem->isSelected() )
00640                 clearSelection();
00641 
00642       blockSignals( block );
00643 
00644       setSelected( d->pCurrentItem, true );
00645     }
00646   }
00647   else
00648     kdDebug() << "KListView::slotAutoSelect: Thatīs not supposed to happen!!!!" << endl;
00649 #endif
00650 }
00651 
00652 void KListView::slotHeaderChanged()
00653 {
00654   if (d->fullWidth && columns())
00655   {
00656     int w = 0;
00657     for (int i = 0; i < columns() - 1; ++i) w += columnWidth(i);
00658     setColumnWidth( columns() - 1, viewport()->width() - w - 1 );
00659   }
00660 }
00661 
00662 void KListView::emitExecute( QListViewItem *item, const QPoint &pos, int c )
00663 {
00664     if( isExecuteArea( viewport()->mapFromGlobal(pos) ) ) {
00665 
00666         // Double click mode ?
00667         if ( !d->bUseSingle )
00668         {
00669             viewport()->unsetCursor();
00670             emit executed( item );
00671             emit executed( item, pos, c );
00672         }
00673         else
00674         {
00675 //#ifndef Q_WS_QWS
00676 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00677         // FIXME(E): Implement for Qt Embedded
00678             uint keybstate = KApplication::keyboardModifiers();
00679 
00680             d->autoSelect.stop();
00681 
00682             //Donīt emit executed if in SC mode and Shift or Ctrl are pressed
00683             if( !( ((keybstate & KApplication::ShiftModifier) || (keybstate & KApplication::ControlModifier)) ) ) {
00684                 viewport()->unsetCursor();
00685                 emit executed( item );
00686                 emit executed( item, pos, c );
00687             }
00688 #endif
00689         }
00690     }
00691 }
00692 
00693 void KListView::focusInEvent( QFocusEvent *fe )
00694 {
00695  //   kdDebug()<<"KListView::focusInEvent()"<<endl;
00696   QListView::focusInEvent( fe );
00697   if ((d->selectedBySimpleMove)
00698       && (d->selectionMode == FileManager)
00699       && (fe->reason()!=QFocusEvent::Popup)
00700       && (fe->reason()!=QFocusEvent::ActiveWindow)
00701       && (currentItem()!=0))
00702   {
00703       currentItem()->setSelected(true);
00704       currentItem()->repaint();
00705       emit selectionChanged();
00706   };
00707 }
00708 
00709 void KListView::focusOutEvent( QFocusEvent *fe )
00710 {
00711   cleanDropVisualizer();
00712   cleanItemHighlighter();
00713 
00714   d->autoSelect.stop();
00715 
00716   if ((d->selectedBySimpleMove)
00717       && (d->selectionMode == FileManager)
00718       && (fe->reason()!=QFocusEvent::Popup)
00719       && (fe->reason()!=QFocusEvent::ActiveWindow)
00720       && (currentItem()!=0)
00721       && (!d->editor->isVisible()))
00722   {
00723       currentItem()->setSelected(false);
00724       currentItem()->repaint();
00725       emit selectionChanged();
00726   };
00727 
00728   QListView::focusOutEvent( fe );
00729 }
00730 
00731 void KListView::leaveEvent( QEvent *e )
00732 {
00733   d->autoSelect.stop();
00734 
00735   QListView::leaveEvent( e );
00736 }
00737 
00738 bool KListView::event( QEvent *e )
00739 {
00740   if (e->type() == QEvent::ApplicationPaletteChange)
00741     d->alternateBackground=KGlobalSettings::alternateBackgroundColor();
00742 
00743   return QListView::event(e);
00744 }
00745 
00746 void KListView::contentsMousePressEvent( QMouseEvent *e )
00747 {
00748   if( (selectionModeExt() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) )
00749   {
00750     bool block = signalsBlocked();
00751     blockSignals( true );
00752 
00753     clearSelection();
00754 
00755     blockSignals( block );
00756   }
00757   else if ((selectionModeExt()==FileManager) && (d->selectedBySimpleMove))
00758   {
00759      d->selectedBySimpleMove=false;
00760      d->selectedUsingMouse=true;
00761      if (currentItem()!=0)
00762      {
00763         currentItem()->setSelected(false);
00764         currentItem()->repaint();
00765 //        emit selectionChanged();
00766      }
00767   }
00768 
00769   QPoint p( contentsToViewport( e->pos() ) );
00770   QListViewItem *at = itemAt (p);
00771 
00772   // true if the root decoration of the item "at" was clicked (i.e. the +/- sign)
00773   bool rootDecoClicked = at
00774            && ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
00775                 treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() )
00776            && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
00777 
00778   if (e->button() == LeftButton && !rootDecoClicked)
00779   {
00780     //Start a drag
00781     d->startDragPos = e->pos();
00782 
00783     if (at)
00784     {
00785       d->validDrag = true;
00786       d->pressedOnSelected = at->isSelected();
00787     }
00788   }
00789 
00790   QListView::contentsMousePressEvent( e );
00791 }
00792 
00793 void KListView::contentsMouseMoveEvent( QMouseEvent *e )
00794 {
00795   if (!dragEnabled() || d->startDragPos.isNull() || !d->validDrag)
00796       QListView::contentsMouseMoveEvent (e);
00797 
00798   QPoint vp = contentsToViewport(e->pos());
00799   QListViewItem *item = itemAt( vp );
00800 
00801   //do we process cursor changes at all?
00802   if ( item && d->bChangeCursorOverItem && d->bUseSingle )
00803     {
00804       //Cursor moved on a new item or in/out the execute area
00805       if( (item != d->pCurrentItem) ||
00806           (isExecuteArea(vp) != d->cursorInExecuteArea) )
00807         {
00808           d->cursorInExecuteArea = isExecuteArea(vp);
00809 
00810           if( d->cursorInExecuteArea ) //cursor moved in execute area
00811             viewport()->setCursor( KCursor::handCursor() );
00812           else //cursor moved out of execute area
00813             viewport()->unsetCursor();
00814         }
00815     }
00816 
00817   bool dragOn = dragEnabled();
00818   QPoint newPos = e->pos();
00819   if (dragOn && d->validDrag &&
00820       (newPos.x() > d->startDragPos.x()+d->dragDelay ||
00821        newPos.x() < d->startDragPos.x()-d->dragDelay ||
00822        newPos.y() > d->startDragPos.y()+d->dragDelay ||
00823        newPos.y() < d->startDragPos.y()-d->dragDelay))
00824     //(d->startDragPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
00825     {
00826       QListView::contentsMouseReleaseEvent( 0 );
00827       startDrag();
00828       d->startDragPos = QPoint();
00829       d->validDrag = false;
00830     }
00831 }
00832 
00833 void KListView::contentsMouseReleaseEvent( QMouseEvent *e )
00834 {
00835   if (e->button() == LeftButton)
00836   {
00837     // If the row was already selected, maybe we want to start an in-place editing
00838     if ( d->pressedOnSelected && itemsRenameable() )
00839     {
00840       QPoint p( contentsToViewport( e->pos() ) );
00841       QListViewItem *at = itemAt (p);
00842       if ( at )
00843       {
00844         // true if the root decoration of the item "at" was clicked (i.e. the +/- sign)
00845         bool rootDecoClicked =
00846                   ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
00847                     treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() )
00848                && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
00849 
00850         if (!rootDecoClicked)
00851         {
00852           int col = header()->mapToLogical( header()->cellAt( p.x() ) );
00853           if ( d->renameable.contains(col) )
00854             rename(at, col);
00855         }
00856       }
00857     }
00858 
00859     d->pressedOnSelected = false;
00860     d->validDrag = false;
00861     d->startDragPos = QPoint();
00862   }
00863   QListView::contentsMouseReleaseEvent( e );
00864 }
00865 
00866 void KListView::contentsMouseDoubleClickEvent ( QMouseEvent *e )
00867 {
00868   // We don't want to call the parent method because it does setOpen,
00869   // whereas we don't do it in single click mode... (David)
00870   //QListView::contentsMouseDoubleClickEvent( e );
00871 
00872   QPoint vp = contentsToViewport(e->pos());
00873   QListViewItem *item = itemAt( vp );
00874   emit QListView::doubleClicked( item ); // we do it now
00875 
00876   int col = item ? header()->mapToLogical( header()->cellAt( vp.x() ) ) : -1;
00877 
00878   if( item ) {
00879     emit doubleClicked( item, e->globalPos(), col );
00880 
00881     if( (e->button() == LeftButton) && !d->bUseSingle )
00882       emitExecute( item, e->globalPos(), col );
00883   }
00884 }
00885 
00886 void KListView::slotMouseButtonClicked( int btn, QListViewItem *item, const QPoint &pos, int c )
00887 {
00888   if( (btn == LeftButton) && item )
00889     emitExecute(item, pos, c);
00890 }
00891 
00892 void KListView::contentsDropEvent(QDropEvent* e)
00893 {
00894   cleanDropVisualizer();
00895   cleanItemHighlighter();
00896   d->dragExpand.stop();
00897 
00898   if (acceptDrag (e))
00899   {
00900     e->acceptAction();
00901     QListViewItem *afterme;
00902     QListViewItem *parent;
00903     findDrop(e->pos(), parent, afterme);
00904 
00905     if (e->source() == viewport() && itemsMovable())
00906         movableDropEvent(parent, afterme);
00907     else
00908     {
00909         emit dropped(e, afterme);
00910         emit dropped(this, e, afterme);
00911         emit dropped(e, parent, afterme);
00912         emit dropped(this, e, parent, afterme);
00913     }
00914   }
00915 }
00916 
00917 void KListView::movableDropEvent (QListViewItem* parent, QListViewItem* afterme)
00918 {
00919   QPtrList<QListViewItem> items, afterFirsts, afterNows;
00920   QListViewItem *current=currentItem();
00921   bool hasMoved=false;
00922   for (QListViewItem *i = firstChild(), *iNext=0; i != 0; i = iNext)
00923   {
00924     iNext=i->itemBelow();
00925     if (!i->isSelected())
00926       continue;
00927 
00928     // don't drop an item after itself, or else
00929     // it moves to the top of the list
00930     if (i==afterme)
00931       continue;
00932 
00933     i->setSelected(false);
00934 
00935     QListViewItem *afterFirst = i->itemAbove();
00936 
00937         if (!hasMoved)
00938         {
00939                 emit aboutToMove();
00940                 hasMoved=true;
00941         }
00942 
00943     moveItem(i, parent, afterme);
00944 
00945     // ###### This should include the new parent !!! -> KDE 3.0
00946     // If you need this right now, have a look at keditbookmarks.
00947     emit moved(i, afterFirst, afterme);
00948 
00949     items.append (i);
00950     afterFirsts.append (afterFirst);
00951     afterNows.append (afterme);
00952 
00953     afterme = i;
00954   }
00955   clearSelection();
00956   for (QListViewItem *i=items.first(); i != 0; i=items.next() )
00957     i->setSelected(true);
00958   if (current)
00959     setCurrentItem(current);
00960 
00961   emit moved(items,afterFirsts,afterNows);
00962 
00963   if (firstChild())
00964     emit moved();
00965 }
00966 
00967 void KListView::contentsDragMoveEvent(QDragMoveEvent *event)
00968 {
00969   if (acceptDrag(event))
00970   {
00971     event->acceptAction();
00972     //Clean up the view
00973 
00974     findDrop(event->pos(), d->parentItemDrop, d->afterItemDrop);
00975     QPoint vp = contentsToViewport( event->pos() );
00976     QListViewItem *item = isExecuteArea( vp ) ? itemAt( vp ) : 0L;
00977 
00978     if ( item != d->dragOverItem )
00979     {
00980       d->dragExpand.stop();
00981       d->dragOverItem = item;
00982       d->dragOverPoint = vp;
00983       if ( d->dragOverItem && d->dragOverItem->isExpandable() && !d->dragOverItem->isOpen() )
00984         d->dragExpand.start( QApplication::startDragTime(), true );
00985     }
00986     if (dropVisualizer())
00987     {
00988       QRect tmpRect = drawDropVisualizer(0, d->parentItemDrop, d->afterItemDrop);
00989       if (tmpRect != d->mOldDropVisualizer)
00990       {
00991         cleanDropVisualizer();
00992         d->mOldDropVisualizer=tmpRect;
00993         viewport()->repaint(tmpRect);
00994       }
00995     }
00996     if (dropHighlighter())
00997     {
00998       QRect tmpRect = drawItemHighlighter(0, d->afterItemDrop);
00999       if (tmpRect != d->mOldDropHighlighter)
01000       {
01001         cleanItemHighlighter();
01002         d->mOldDropHighlighter=tmpRect;
01003         viewport()->repaint(tmpRect);
01004       }
01005     }
01006   }
01007   else
01008       event->ignore();
01009 }
01010 
01011 void KListView::slotDragExpand()
01012 {
01013   if ( itemAt( d->dragOverPoint ) == d->dragOverItem )
01014     d->dragOverItem->setOpen( true );
01015 }
01016 
01017 void KListView::contentsDragLeaveEvent (QDragLeaveEvent*)
01018 {
01019   d->dragExpand.stop();
01020   cleanDropVisualizer();
01021   cleanItemHighlighter();
01022 }
01023 
01024 void KListView::cleanDropVisualizer()
01025 {
01026   if (d->mOldDropVisualizer.isValid())
01027   {
01028     QRect rect=d->mOldDropVisualizer;
01029     d->mOldDropVisualizer = QRect();
01030     viewport()->repaint(rect, true);
01031   }
01032 }
01033 
01034 int KListView::depthToPixels( int depth )
01035 {
01036     return treeStepSize() * ( depth + (rootIsDecorated() ? 1 : 0) ) + itemMargin();
01037 }
01038 
01039 void KListView::findDrop(const QPoint &pos, QListViewItem *&parent, QListViewItem *&after)
01040 {
01041     QPoint p (contentsToViewport(pos));
01042 
01043     // Get the position to put it in
01044     QListViewItem *atpos = itemAt(p);
01045 
01046     QListViewItem *above;
01047     if (!atpos) // put it at the end
01048         above = lastItem();
01049     else
01050     {
01051         // Get the closest item before us ('atpos' or the one above, if any)
01052         if (p.y() - itemRect(atpos).topLeft().y() < (atpos->height()/2))
01053             above = atpos->itemAbove();
01054         else
01055             above = atpos;
01056     }
01057 
01058     if (above)
01059     {
01060         // if above has children, I might need to drop it as the first item there
01061 
01062         if (above->firstChild() && above->isOpen())
01063         {
01064             parent = above;
01065             after = 0;
01066             return;
01067         }
01068 
01069       // Now, we know we want to go after "above". But as a child or as a sibling ?
01070       // We have to ask the "above" item if it accepts children.
01071       if (above->isExpandable())
01072       {
01073           // The mouse is sufficiently on the right ? - doesn't matter if 'above' has visible children
01074           if (p.x() >= depthToPixels( above->depth() + 1 ) ||
01075               (above->isOpen() && above->childCount() > 0) )
01076           {
01077               parent = above;
01078               after = 0L;
01079               return;
01080           }
01081       }
01082 
01083       // Ok, there's one more level of complexity. We may want to become a new
01084       // sibling, but of an upper-level group, rather than the "above" item
01085       QListViewItem * betterAbove = above->parent();
01086       QListViewItem * last = above;
01087       while ( betterAbove )
01088       {
01089           // We are allowed to become a sibling of "betterAbove" only if we are
01090           // after its last child
01091           if ( last->nextSibling() == 0 )
01092           {
01093               if (p.x() < depthToPixels ( betterAbove->depth() + 1 ))
01094                   above = betterAbove; // store this one, but don't stop yet, there may be a better one
01095               else
01096                   break; // not enough on the left, so stop
01097               last = betterAbove;
01098               betterAbove = betterAbove->parent(); // up one level
01099           } else
01100               break; // we're among the child of betterAbove, not after the last one
01101       }
01102   }
01103   // set as sibling
01104   after = above;
01105   parent = after ? after->parent() : 0L ;
01106 }
01107 
01108 QListViewItem* KListView::lastChild () const
01109 {
01110   QListViewItem* lastchild = firstChild();
01111 
01112   if (lastchild)
01113         for (; lastchild->nextSibling(); lastchild = lastchild->nextSibling());
01114 
01115   return lastchild;
01116 }
01117 
01118 QListViewItem *KListView::lastItem() const
01119 {
01120   QListViewItem* last = lastChild();
01121 
01122   for (QListViewItemIterator it (last); it.current(); ++it)
01123     last = it.current();
01124 
01125   return last;
01126 }
01127 
01128 KLineEdit *KListView::renameLineEdit() const
01129 {
01130   return d->editor;
01131 }
01132 
01133 void KListView::startDrag()
01134 {
01135   QDragObject *drag = dragObject();
01136 
01137   if (!drag)
01138         return;
01139 
01140   if (drag->drag() && drag->target() != viewport())
01141     emit moved();
01142 }
01143 
01144 QDragObject *KListView::dragObject()
01145 {
01146   if (!currentItem())
01147         return 0;
01148 
01149   return new QStoredDrag("application/x-qlistviewitem", viewport());
01150 }
01151 
01152 void KListView::setItemsMovable(bool b)
01153 {
01154   d->itemsMovable=b;
01155 }
01156 
01157 bool KListView::itemsMovable() const
01158 {
01159   return d->itemsMovable;
01160 }
01161 
01162 void KListView::setItemsRenameable(bool b)
01163 {
01164   d->itemsRenameable=b;
01165 }
01166 
01167 bool KListView::itemsRenameable() const
01168 {
01169   return d->itemsRenameable;
01170 }
01171 
01172 
01173 void KListView::setDragEnabled(bool b)
01174 {
01175   d->dragEnabled=b;
01176 }
01177 
01178 bool KListView::dragEnabled() const
01179 {
01180   return d->dragEnabled;
01181 }
01182 
01183 void KListView::setAutoOpen(bool b)
01184 {
01185   d->autoOpen=b;
01186 }
01187 
01188 bool KListView::autoOpen() const
01189 {
01190   return d->autoOpen;
01191 }
01192 
01193 bool KListView::dropVisualizer() const
01194 {
01195   return d->dropVisualizer;
01196 }
01197 
01198 void KListView::setDropVisualizer(bool b)
01199 {
01200   d->dropVisualizer=b;
01201 }
01202 
01203 QPtrList<QListViewItem> KListView::selectedItems() const
01204 {
01205   QPtrList<QListViewItem> list;
01206 
01207   // Using selectionMode() instead of selectionModeExt() since for the cases that
01208   // we're interested in selectionMode() should work for either variety of the
01209   // setSelectionMode().
01210 
01211   switch(selectionMode())
01212   {
01213   case NoSelection:
01214       break;
01215   case Single:
01216       if(selectedItem())
01217           list.append(selectedItem());
01218       break;
01219   default:
01220   {
01221       QListViewItemIterator it(const_cast<KListView *>(this), QListViewItemIterator::Selected);
01222 
01223       for(; it.current(); ++it)
01224           list.append(it.current());
01225 
01226       break;
01227   }
01228   }
01229 
01230   return list;
01231 }
01232 
01233 
01234 void KListView::moveItem(QListViewItem *item, QListViewItem *parent, QListViewItem *after)
01235 {
01236   // sanity check - don't move a item into its own child structure
01237   QListViewItem *i = parent;
01238   while(i)
01239     {
01240       if(i == item)
01241         return;
01242       i = i->parent();
01243     }
01244 
01245   if (after)
01246   {
01247       item->moveItem(after);
01248       return;
01249   }
01250 
01251   // NOTE: This code shouldn't ever be reached if this method is used proprely,
01252   // QListVIew::moveItem() handles the same cases.  However, to avoid changing the (albeit
01253   // undocumented behavior) it's being left in for the moment.
01254 
01255   // Basically reimplementing the QListViewItem(QListViewItem*, QListViewItem*) constructor
01256   // in here, without ever deleting the item.
01257   if (item->parent())
01258         item->parent()->takeItem(item);
01259   else
01260         takeItem(item);
01261 
01262   if (parent)
01263         parent->insertItem(item);
01264   else
01265         insertItem(item);
01266 }
01267 
01268 void KListView::contentsDragEnterEvent(QDragEnterEvent *event)
01269 {
01270   if (acceptDrag (event))
01271     event->accept();
01272 }
01273 
01274 void KListView::setDropVisualizerWidth (int w)
01275 {
01276   d->mDropVisualizerWidth = w > 0 ? w : 1;
01277 }
01278 
01279 QRect KListView::drawDropVisualizer(QPainter *p, QListViewItem *parent,
01280                                     QListViewItem *after)
01281 {
01282     QRect insertmarker;
01283 
01284     if (!after && !parent)
01285         insertmarker = QRect (0, 0, viewport()->width(), d->mDropVisualizerWidth/2);
01286     else
01287     {
01288         int level = 0;
01289         if (after)
01290         {
01291             QListViewItem* it = 0L;
01292             if (after->isOpen())
01293             {
01294                 // Look for the last child (recursively)
01295                 it = after->firstChild();
01296                 if (it)
01297                     while (it->nextSibling() || it->firstChild())
01298                         if ( it->nextSibling() )
01299                             it = it->nextSibling();
01300                         else
01301                             it = it->firstChild();
01302             }
01303 
01304             insertmarker = itemRect (it ? it : after);
01305             level = after->depth();
01306         }
01307         else if (parent)
01308         {
01309             insertmarker = itemRect (parent);
01310             level = parent->depth() + 1;
01311         }
01312         insertmarker.setLeft( treeStepSize() * ( level + (rootIsDecorated() ? 1 : 0) ) + itemMargin() );
01313         insertmarker.setRight (viewport()->width());
01314         insertmarker.setTop (insertmarker.bottom() - d->mDropVisualizerWidth/2 + 1);
01315         insertmarker.setBottom (insertmarker.bottom() + d->mDropVisualizerWidth/2);
01316     }
01317 
01318     // This is not used anymore, at least by KListView itself (see viewportPaintEvent)
01319     // Remove for KDE 3.0.
01320     if (p)
01321         p->fillRect(insertmarker, Dense4Pattern);
01322 
01323     return insertmarker;
01324 }
01325 
01326 QRect KListView::drawItemHighlighter(QPainter *painter, QListViewItem *item)
01327 {
01328   QRect r;
01329 
01330   if (item)
01331   {
01332     r = itemRect(item);
01333     r.setLeft(r.left()+(item->depth()+1)*treeStepSize());
01334     if (painter)
01335       style().drawPrimitive(QStyle::PE_FocusRect, painter, r, colorGroup(),
01336                             QStyle::Style_FocusAtBorder, colorGroup().highlight());
01337   }
01338 
01339   return r;
01340 }
01341 
01342 void KListView::cleanItemHighlighter ()
01343 {
01344   if (d->mOldDropHighlighter.isValid())
01345   {
01346     QRect rect=d->mOldDropHighlighter;
01347     d->mOldDropHighlighter = QRect();
01348     viewport()->repaint(rect, true);
01349   }
01350 }
01351 
01352 void KListView::rename(QListViewItem *item, int c)
01353 {
01354   if (d->renameable.contains(c))
01355   {
01356     ensureItemVisible(item);
01357     d->editor->load(item,c);
01358   }
01359 }
01360 
01361 bool KListView::isRenameable (int col) const
01362 {
01363   return d->renameable.contains(col);
01364 }
01365 
01366 void KListView::setRenameable (int col, bool yesno)
01367 {
01368   if (col>=header()->count()) return;
01369 
01370   d->renameable.remove(col);
01371   if (yesno && d->renameable.find(col)==d->renameable.end())
01372     d->renameable+=col;
01373   else if (!yesno && d->renameable.find(col)!=d->renameable.end())
01374     d->renameable.remove(col);
01375 }
01376 
01377 void KListView::doneEditing(QListViewItem *item, int row)
01378 {
01379   emit itemRenamed(item, item->text(row), row);
01380   emit itemRenamed(item);
01381 }
01382 
01383 bool KListView::acceptDrag(QDropEvent* e) const
01384 {
01385   return acceptDrops() && itemsMovable() && (e->source()==viewport());
01386 }
01387 
01388 void KListView::setCreateChildren(bool b)
01389 {
01390         d->createChildren=b;
01391 }
01392 
01393 bool KListView::createChildren() const
01394 {
01395         return d->createChildren;
01396 }
01397 
01398 
01399 int KListView::tooltipColumn() const
01400 {
01401         return d->tooltipColumn;
01402 }
01403 
01404 void KListView::setTooltipColumn(int column)
01405 {
01406         d->tooltipColumn=column;
01407 }
01408 
01409 void KListView::setDropHighlighter(bool b)
01410 {
01411         d->dropHighlighter=b;
01412 }
01413 
01414 bool KListView::dropHighlighter() const
01415 {
01416         return d->dropHighlighter;
01417 }
01418 
01419 bool KListView::showTooltip(QListViewItem *item, const QPoint &, int column) const
01420 {
01421         return ((tooltip(item, column).length()>0) && (column==tooltipColumn()));
01422 }
01423 
01424 QString KListView::tooltip(QListViewItem *item, int column) const
01425 {
01426         return item->text(column);
01427 }
01428 
01429 void KListView::setTabOrderedRenaming(bool b)
01430 {
01431     d->tabRename = b;
01432 }
01433 
01434 bool KListView::tabOrderedRenaming() const
01435 {
01436     return d->tabRename;
01437 }
01438 
01439 void KListView::keyPressEvent (QKeyEvent* e)
01440 {
01441   //don't we need a contextMenuModifier too ? (aleXXX)
01442   if (e->key() == d->contextMenuKey)
01443         {
01444           emit menuShortCutPressed (this, currentItem());
01445           return;
01446         }
01447 
01448   if (d->selectionMode != FileManager)
01449         QListView::keyPressEvent (e);
01450   else
01451         fileManagerKeyPressEvent (e);
01452 }
01453 
01454 void KListView::activateAutomaticSelection()
01455 {
01456    d->selectedBySimpleMove=true;
01457    d->selectedUsingMouse=false;
01458    if (currentItem()!=0)
01459    {
01460       currentItem()->setSelected(true);
01461       currentItem()->repaint();
01462       emit selectionChanged();
01463    };
01464 }
01465 
01466 void KListView::deactivateAutomaticSelection()
01467 {
01468    d->selectedBySimpleMove=false;
01469 }
01470 
01471 bool KListView::automaticSelection() const
01472 {
01473    return d->selectedBySimpleMove;
01474 }
01475 
01476 void KListView::fileManagerKeyPressEvent (QKeyEvent* e)
01477 {
01478    //don't care whether it's on the keypad or not
01479     int e_state=(e->state() & ~Keypad);
01480 
01481     int oldSelectionDirection(d->selectionDirection);
01482 
01483     if ((e->key()!=Key_Shift) && (e->key()!=Key_Control)
01484         && (e->key()!=Key_Meta) && (e->key()!=Key_Alt))
01485     {
01486        if ((e_state==ShiftButton) && (!d->wasShiftEvent) && (!d->selectedBySimpleMove))
01487           selectAll(false);
01488        d->selectionDirection=0;
01489        d->wasShiftEvent = (e_state == ShiftButton);
01490     };
01491 
01492     //d->wasShiftEvent = (e_state == ShiftButton);
01493 
01494 
01495     QListViewItem* item = currentItem();
01496     if (item==0) return;
01497 
01498     QListViewItem* repaintItem1 = item;
01499     QListViewItem* repaintItem2 = 0L;
01500     QListViewItem* visItem = 0L;
01501 
01502     QListViewItem* nextItem = 0L;
01503     int items = 0;
01504 
01505     bool shiftOrCtrl((e_state==ControlButton) || (e_state==ShiftButton));
01506     int selectedItems(0);
01507     for (QListViewItem *tmpItem=firstChild(); tmpItem!=0; tmpItem=tmpItem->nextSibling())
01508        if (tmpItem->isSelected()) selectedItems++;
01509 
01510     if (((selectedItems==0) || ((selectedItems==1) && (d->selectedUsingMouse)))
01511         && (e_state==NoButton)
01512         && ((e->key()==Key_Down)
01513         || (e->key()==Key_Up)
01514         || (e->key()==Key_Next)
01515         || (e->key()==Key_Prior)
01516         || (e->key()==Key_Home)
01517         || (e->key()==Key_End)))
01518     {
01519        d->selectedBySimpleMove=true;
01520        d->selectedUsingMouse=false;
01521     }
01522     else if (selectedItems>1)
01523        d->selectedBySimpleMove=false;
01524 
01525     bool emitSelectionChanged(false);
01526 
01527     switch (e->key())
01528     {
01529     case Key_Escape:
01530        selectAll(false);
01531        emitSelectionChanged=true;
01532        break;
01533 
01534     case Key_Space:
01535        //toggle selection of current item
01536        if (d->selectedBySimpleMove)
01537           d->selectedBySimpleMove=false;
01538        item->setSelected(!item->isSelected());
01539        emitSelectionChanged=true;
01540        break;
01541 
01542     case Key_Insert:
01543        //toggle selection of current item and move to the next item
01544        if (d->selectedBySimpleMove)
01545        {
01546           d->selectedBySimpleMove=false;
01547           if (!item->isSelected()) item->setSelected(true);
01548        }
01549        else
01550        {
01551           item->setSelected(!item->isSelected());
01552        };
01553 
01554        nextItem=item->itemBelow();
01555 
01556        if (nextItem!=0)
01557        {
01558           repaintItem2=nextItem;
01559           visItem=nextItem;
01560           setCurrentItem(nextItem);
01561        };
01562        d->selectionDirection=1;
01563        emitSelectionChanged=true;
01564        break;
01565 
01566     case Key_Down:
01567        nextItem=item->itemBelow();
01568        //toggle selection of current item and move to the next item
01569        if (shiftOrCtrl)
01570        {
01571           d->selectionDirection=1;
01572           if (d->selectedBySimpleMove)
01573              d->selectedBySimpleMove=false;
01574           else
01575           {
01576              if (oldSelectionDirection!=-1)
01577              {
01578                 item->setSelected(!item->isSelected());
01579                 emitSelectionChanged=true;
01580              };
01581           };
01582        }
01583        else if ((d->selectedBySimpleMove) && (nextItem!=0))
01584        {
01585           item->setSelected(false);
01586           emitSelectionChanged=true;
01587        };
01588 
01589        if (nextItem!=0)
01590        {
01591           if (d->selectedBySimpleMove)
01592              nextItem->setSelected(true);
01593           repaintItem2=nextItem;
01594           visItem=nextItem;
01595           setCurrentItem(nextItem);
01596        };
01597        break;
01598 
01599     case Key_Up:
01600        nextItem=item->itemAbove();
01601        d->selectionDirection=-1;
01602        //move to the prev. item and toggle selection of this one
01603        // => No, can't select the last item, with this. For symmetry, let's
01604        // toggle selection and THEN move up, just like we do in down (David)
01605        if (shiftOrCtrl)
01606        {
01607           if (d->selectedBySimpleMove)
01608              d->selectedBySimpleMove=false;
01609           else
01610           {
01611              if (oldSelectionDirection!=1)
01612              {
01613                 item->setSelected(!item->isSelected());
01614                 emitSelectionChanged=true;
01615              };
01616           }
01617        }
01618        else if ((d->selectedBySimpleMove) && (nextItem!=0))
01619        {
01620           item->setSelected(false);
01621           emitSelectionChanged=true;
01622        };
01623 
01624        if (nextItem!=0)
01625        {
01626           if (d->selectedBySimpleMove)
01627              nextItem->setSelected(true);
01628           repaintItem2=nextItem;
01629           visItem=nextItem;
01630           setCurrentItem(nextItem);
01631        };
01632        break;
01633 
01634     case Key_End:
01635        //move to the last item and toggle selection of all items inbetween
01636        nextItem=item;
01637        if (d->selectedBySimpleMove)
01638           item->setSelected(false);
01639        if (shiftOrCtrl)
01640           d->selectedBySimpleMove=false;
01641 
01642        while(nextItem!=0)
01643        {
01644           if (shiftOrCtrl)
01645              nextItem->setSelected(!nextItem->isSelected());
01646           if (nextItem->itemBelow()==0)
01647           {
01648              if (d->selectedBySimpleMove)
01649                 nextItem->setSelected(true);
01650              repaintItem2=nextItem;
01651              visItem=nextItem;
01652              setCurrentItem(nextItem);
01653           }
01654           nextItem=nextItem->itemBelow();
01655        }
01656        emitSelectionChanged=true;
01657        break;
01658 
01659     case Key_Home:
01660        // move to the first item and toggle selection of all items inbetween
01661        nextItem = firstChild();
01662        visItem = nextItem;
01663        repaintItem2 = visItem;
01664        if (d->selectedBySimpleMove)
01665           item->setSelected(false);
01666        if (shiftOrCtrl)
01667        {
01668           d->selectedBySimpleMove=false;
01669 
01670           while ( nextItem != item )
01671           {
01672              nextItem->setSelected( !nextItem->isSelected() );
01673              nextItem = nextItem->itemBelow();
01674           }
01675           item->setSelected( !item->isSelected() );
01676        }
01677        setCurrentItem( firstChild() );
01678        emitSelectionChanged=true;
01679        break;
01680 
01681     case Key_Next:
01682        items=visibleHeight()/item->height();
01683        nextItem=item;
01684        if (d->selectedBySimpleMove)
01685           item->setSelected(false);
01686        if (shiftOrCtrl)
01687        {
01688           d->selectedBySimpleMove=false;
01689           d->selectionDirection=1;
01690        };
01691 
01692        for (int i=0; i<items; i++)
01693        {
01694           if (shiftOrCtrl)
01695              nextItem->setSelected(!nextItem->isSelected());
01696           //the end
01697           if ((i==items-1) || (nextItem->itemBelow()==0))
01698 
01699           {
01700              if (shiftOrCtrl)
01701                 nextItem->setSelected(!nextItem->isSelected());
01702              if (d->selectedBySimpleMove)
01703                 nextItem->setSelected(true);
01704              ensureItemVisible(nextItem);
01705              setCurrentItem(nextItem);
01706              update();
01707              if ((shiftOrCtrl) || (d->selectedBySimpleMove))
01708              {
01709                 emit selectionChanged();
01710              }
01711              return;
01712           }
01713           nextItem=nextItem->itemBelow();
01714        }
01715        break;
01716 
01717     case Key_Prior:
01718        items=visibleHeight()/item->height();
01719        nextItem=item;
01720        if (d->selectedBySimpleMove)
01721           item->setSelected(false);
01722        if (shiftOrCtrl)
01723        {
01724           d->selectionDirection=-1;
01725           d->selectedBySimpleMove=false;
01726        };
01727 
01728        for (int i=0; i<items; i++)
01729        {
01730           if ((nextItem!=item) &&(shiftOrCtrl))
01731              nextItem->setSelected(!nextItem->isSelected());
01732           //the end
01733           if ((i==items-1) || (nextItem->itemAbove()==0))
01734 
01735           {
01736              if (d->selectedBySimpleMove)
01737                 nextItem->setSelected(true);
01738              ensureItemVisible(nextItem);
01739              setCurrentItem(nextItem);
01740              update();
01741              if ((shiftOrCtrl) || (d->selectedBySimpleMove))
01742              {
01743                 emit selectionChanged();
01744              }
01745              return;
01746           }
01747           nextItem=nextItem->itemAbove();
01748        }
01749        break;
01750 
01751     case Key_Minus:
01752        if ( item->isOpen() )
01753           setOpen( item, false );
01754        break;
01755     case Key_Plus:
01756        if (  !item->isOpen() && (item->isExpandable() || item->childCount()) )
01757           setOpen( item, true );
01758        break;
01759     default:
01760        bool realKey = ((e->key()!=Key_Shift) && (e->key()!=Key_Control)
01761                         && (e->key()!=Key_Meta) && (e->key()!=Key_Alt));
01762 
01763        bool selectCurrentItem = (d->selectedBySimpleMove) && (item->isSelected());
01764        if (realKey && selectCurrentItem)
01765           item->setSelected(false);
01766        //this is mainly for the "goto filename beginning with pressed char" feature (aleXXX)
01767        QListView::SelectionMode oldSelectionMode = selectionMode();
01768        setSelectionMode (QListView::Multi);
01769        QListView::keyPressEvent (e);
01770        setSelectionMode (oldSelectionMode);
01771        if (realKey && selectCurrentItem)
01772        {
01773           currentItem()->setSelected(true);
01774           emitSelectionChanged=true;
01775        }
01776        repaintItem2=currentItem();
01777        if (realKey)
01778           visItem=currentItem();
01779        break;
01780     }
01781 
01782     if (visItem)
01783        ensureItemVisible(visItem);
01784 
01785     QRect ir;
01786     if (repaintItem1)
01787        ir = ir.unite( itemRect(repaintItem1) );
01788     if (repaintItem2)
01789        ir = ir.unite( itemRect(repaintItem2) );
01790 
01791     if ( !ir.isEmpty() )
01792     {                 // rectangle to be repainted
01793        if ( ir.x() < 0 )
01794           ir.moveBy( -ir.x(), 0 );
01795        viewport()->repaint( ir, false );
01796     }
01797     /*if (repaintItem1)
01798        repaintItem1->repaint();
01799     if (repaintItem2)
01800        repaintItem2->repaint();*/
01801     update();
01802     if (emitSelectionChanged)
01803        emit selectionChanged();
01804 }
01805 
01806 void KListView::setSelectionModeExt (SelectionModeExt mode)
01807 {
01808     d->selectionMode = mode;
01809 
01810     switch (mode)
01811     {
01812     case Single:
01813     case Multi:
01814     case Extended:
01815     case NoSelection:
01816         setSelectionMode (static_cast<QListView::SelectionMode>(static_cast<int>(mode)));
01817         break;
01818 
01819     case FileManager:
01820         setSelectionMode (QListView::Extended);
01821         break;
01822 
01823     default:
01824         kdWarning () << "Warning: illegal selection mode " << int(mode) << " set!" << endl;
01825         break;
01826     }
01827 }
01828 
01829 KListView::SelectionModeExt KListView::selectionModeExt () const
01830 {
01831   return d->selectionMode;
01832 }
01833 
01834 int KListView::itemIndex( const QListViewItem *item ) const
01835 {
01836     if ( !item )
01837         return -1;
01838 
01839     if ( item == firstChild() )
01840         return 0;
01841     else {
01842         QListViewItemIterator it(firstChild());
01843         uint j = 0;
01844         for (; it.current() && it.current() != item; ++it, ++j );
01845 
01846         if( !it.current() )
01847           return -1;
01848 
01849         return j;
01850     }
01851 }
01852 
01853 QListViewItem* KListView::itemAtIndex(int index)
01854 {
01855    if (index<0)
01856       return 0;
01857 
01858    int j(0);
01859    for (QListViewItemIterator it=firstChild(); it.current(); it++)
01860    {
01861       if (j==index)
01862          return it.current();
01863       j++;
01864    };
01865    return 0;
01866 }
01867 
01868 
01869 void KListView::emitContextMenu (KListView*, QListViewItem* i)
01870 {
01871   QPoint p;
01872 
01873   if (i)
01874         p = viewport()->mapToGlobal(itemRect(i).center());
01875   else
01876         p = mapToGlobal(rect().center());
01877 
01878   emit contextMenu (this, i, p);
01879 }
01880 
01881 void KListView::emitContextMenu (QListViewItem* i, const QPoint& p, int)
01882 {
01883   emit contextMenu (this, i, p);
01884 }
01885 
01886 void KListView::setAcceptDrops (bool val)
01887 {
01888   QListView::setAcceptDrops (val);
01889   viewport()->setAcceptDrops (val);
01890 }
01891 
01892 int KListView::dropVisualizerWidth () const
01893 {
01894         return d->mDropVisualizerWidth;
01895 }
01896 
01897 
01898 void KListView::viewportPaintEvent(QPaintEvent *e)
01899 {
01900   d->paintAbove = 0;
01901   d->paintCurrent = 0;
01902   d->paintBelow = 0;
01903   d->painting = true;
01904 
01905   QListView::viewportPaintEvent(e);
01906 
01907   if (d->mOldDropVisualizer.isValid() && e->rect().intersects(d->mOldDropVisualizer))
01908     {
01909       QPainter painter(viewport());
01910 
01911       // This is where we actually draw the drop-visualizer
01912       painter.fillRect(d->mOldDropVisualizer, Dense4Pattern);
01913     }
01914   if (d->mOldDropHighlighter.isValid() && e->rect().intersects(d->mOldDropHighlighter))
01915     {
01916       QPainter painter(viewport());
01917 
01918       // This is where we actually draw the drop-highlighter
01919       style().drawPrimitive(QStyle::PE_FocusRect, &painter, d->mOldDropHighlighter, colorGroup(),
01920                             QStyle::Style_FocusAtBorder);
01921     }
01922   d->painting = false;
01923 }
01924 
01925 void KListView::setFullWidth()
01926 {
01927   setFullWidth(true);
01928 }
01929 
01930 void KListView::setFullWidth(bool fullWidth)
01931 {
01932   d->fullWidth = fullWidth;
01933   header()->setStretchEnabled(fullWidth, columns()-1);
01934 }
01935 
01936 bool KListView::fullWidth() const
01937 {
01938   return d->fullWidth;
01939 }
01940 
01941 int KListView::addColumn(const QString& label, int width)
01942 {
01943   int result = QListView::addColumn(label, width);
01944   if (d->fullWidth) {
01945     header()->setStretchEnabled(false, columns()-2);
01946     header()->setStretchEnabled(true, columns()-1);
01947   }
01948   return result;
01949 }
01950 
01951 int KListView::addColumn(const QIconSet& iconset, const QString& label, int width)
01952 {
01953   int result = QListView::addColumn(iconset, label, width);
01954   if (d->fullWidth) {
01955     header()->setStretchEnabled(false, columns()-2);
01956     header()->setStretchEnabled(true, columns()-1);
01957   }
01958   return result;
01959 }
01960 
01961 void KListView::removeColumn(int index)
01962 {
01963   QListView::removeColumn(index);
01964   if (d->fullWidth && index == columns()) header()->setStretchEnabled(true, columns()-1);
01965 }
01966 
01967 void KListView::viewportResizeEvent(QResizeEvent* e)
01968 {
01969   QListView::viewportResizeEvent(e);
01970 }
01971 
01972 const QColor &KListView::alternateBackground() const
01973 {
01974   return d->alternateBackground;
01975 }
01976 
01977 void KListView::setAlternateBackground(const QColor &c)
01978 {
01979   d->alternateBackground = c;
01980   repaint();
01981 }
01982 
01983 void KListView::saveLayout(KConfig *config, const QString &group) const
01984 {
01985   KConfigGroupSaver saver(config, group);
01986   QStringList widths, order;
01987   for (int i = 0; i < columns(); ++i)
01988   {
01989     widths << QString::number(columnWidth(i));
01990     order << QString::number(header()->mapToIndex(i));
01991   }
01992   config->writeEntry("ColumnWidths", widths);
01993   config->writeEntry("ColumnOrder", order);
01994   config->writeEntry("SortColumn", d->sortColumn);
01995   config->writeEntry("SortAscending", d->sortAscending);
01996 }
01997 
01998 void KListView::restoreLayout(KConfig *config, const QString &group)
01999 {
02000   KConfigGroupSaver saver(config, group);
02001   QStringList cols = config->readListEntry("ColumnWidths");
02002   int i = 0;
02003   for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it)
02004     setColumnWidth(i++, (*it).toInt());
02005 
02006   cols = config->readListEntry("ColumnOrder");
02007   i = 0;
02008   for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it)
02009     header()->moveSection(i++, (*it).toInt());
02010   if (config->hasKey("SortColumn"))
02011     setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true));
02012 }
02013 
02014 void KListView::setSorting(int column, bool ascending)
02015 {
02016   d->sortColumn = column;
02017   d->sortAscending = ascending;
02018   QListView::setSorting(column, ascending);
02019   
02020   QListViewItem* item = firstChild();
02021   while ( item ) {
02022     KListViewItem *kItem = dynamic_cast<KListViewItem*>(item);
02023     if (kItem) kItem->m_known = false;
02024     item = item->itemBelow();
02025   }
02026 }
02027 
02028 int KListView::columnSorted(void) const
02029 {
02030   return d->sortColumn;
02031 }
02032 
02033 bool KListView::ascendingSort(void) const
02034 {
02035   return d->sortAscending;
02036 }
02037 
02038 void KListView::takeItem(QListViewItem *item)
02039 {
02040   if(item && item == d->editor->currentItem())
02041     d->editor->terminate();
02042 
02043   QListView::takeItem(item);
02044 }
02045 
02046 void KListView::disableAutoSelection()
02047 {
02048   if ( d->disableAutoSelection )
02049     return;
02050 
02051   d->disableAutoSelection = true;
02052   d->autoSelect.stop();
02053   d->autoSelectDelay = -1;
02054 }
02055 
02056 void KListView::resetAutoSelection()
02057 {
02058   if ( !d->disableAutoSelection )
02059     return;
02060 
02061   d->disableAutoSelection = false;
02062   d->autoSelectDelay = KGlobalSettings::autoSelectDelay();
02063 }
02064 
02065 void KListView::doubleClicked( QListViewItem *item, const QPoint &pos, int c )
02066 {
02067   emit QListView::doubleClicked( item, pos, c );
02068 }
02069 
02070 KListViewItem::KListViewItem(QListView *parent)
02071   : QListViewItem(parent)
02072 {
02073   init();
02074 }
02075 
02076 KListViewItem::KListViewItem(QListViewItem *parent)
02077   : QListViewItem(parent)
02078 {
02079   init();
02080 }
02081 
02082 KListViewItem::KListViewItem(QListView *parent, QListViewItem *after)
02083   : QListViewItem(parent, after)
02084 {
02085   init();
02086 }
02087 
02088 KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after)
02089   : QListViewItem(parent, after)
02090 {
02091   init();
02092 }
02093 
02094 KListViewItem::KListViewItem(QListView *parent,
02095     QString label1, QString label2, QString label3, QString label4,
02096     QString label5, QString label6, QString label7, QString label8)
02097   : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8)
02098 {
02099   init();
02100 }
02101 
02102 KListViewItem::KListViewItem(QListViewItem *parent,
02103     QString label1, QString label2, QString label3, QString label4,
02104     QString label5, QString label6, QString label7, QString label8)
02105   : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8)
02106 {
02107   init();
02108 }
02109 
02110 KListViewItem::KListViewItem(QListView *parent, QListViewItem *after,
02111     QString label1, QString label2, QString label3, QString label4,
02112     QString label5, QString label6, QString label7, QString label8)
02113   : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8)
02114 {
02115   init();
02116 }
02117 
02118 KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after,
02119     QString label1, QString label2, QString label3, QString label4,
02120     QString label5, QString label6, QString label7, QString label8)
02121   : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8)
02122 {
02123   init();
02124 }
02125 
02126 KListViewItem::~KListViewItem()
02127 {
02128   if(listView())
02129     emit static_cast<KListView *>(listView())->itemRemoved(this);
02130 }
02131 
02132 void KListViewItem::init()
02133 {
02134   m_odd = m_known = false;
02135   KListView *lv = static_cast<KListView *>(listView());
02136   setDragEnabled( dragEnabled() || lv->dragEnabled() );
02137   emit lv->itemAdded(this);
02138 }
02139 
02140 void KListViewItem::insertItem(QListViewItem *item)
02141 {
02142   QListViewItem::insertItem(item);
02143   if(listView())
02144     emit static_cast<KListView *>(listView())->itemAdded(item);
02145 }
02146 
02147 void KListViewItem::takeItem(QListViewItem *item)
02148 {
02149   QListViewItem::takeItem(item);
02150   if(listView())
02151     emit static_cast<KListView *>(listView())->itemRemoved(item);
02152 }
02153 
02154 const QColor &KListViewItem::backgroundColor()
02155 {
02156   if (isAlternate())
02157     return static_cast< KListView* >(listView())->alternateBackground();
02158   return listView()->viewport()->colorGroup().base();
02159 }
02160 
02161 bool KListViewItem::isAlternate()
02162 {
02163   KListView *lv = static_cast<KListView *>(listView());
02164   if (lv && lv->alternateBackground().isValid())
02165   {
02166     KListViewItem *above;
02167 
02168     // Ok, there's some weirdness here that requires explanation as this is a
02169     // speed hack.  itemAbove() is a O(n) operation (though this isn't
02170     // immediately clear) so we want to call it as infrequently as possible --
02171     // especially in the case of painting a cell.
02172     //
02173     // So, in the case that we *are* painting a cell:  (1) we're assuming that
02174     // said painting is happening top to bottem -- this assumption is present
02175     // elsewhere in the implementation of this class, (2) itemBelow() is fast --
02176     // roughly constant time.
02177     //
02178     // Given these assumptions we can do a mixture of caching and telling the
02179     // next item that the when that item is the current item that the now
02180     // current item will be the item above it.
02181     //
02182     // Ideally this will make checking to see if the item above the current item
02183     // is the alternate color a constant time operation rather than 0(n).
02184 
02185     if (lv->d->painting) {
02186       if (lv->d->paintCurrent != this)
02187       {
02188         lv->d->paintAbove = lv->d->paintBelow == this ? lv->d->paintCurrent : itemAbove();
02189         lv->d->paintCurrent = this;
02190         lv->d->paintBelow = itemBelow();
02191       }
02192 
02193       above = dynamic_cast<KListViewItem *>(lv->d->paintAbove);
02194     }
02195     else
02196     {
02197       above = dynamic_cast<KListViewItem *>(itemAbove());
02198     }
02199 
02200     m_known = above ? above->m_known : true;
02201     if (m_known)
02202     {
02203        m_odd = above ? !above->m_odd : false;
02204     }
02205     else
02206     {
02207        KListViewItem *item;
02208        bool previous = true;
02209        if (parent())
02210        {
02211           item = dynamic_cast<KListViewItem *>(parent());
02212           if (item)
02213              previous = item->m_odd;
02214           item = dynamic_cast<KListViewItem *>(parent()->firstChild());
02215        }
02216        else
02217        {
02218           item = dynamic_cast<KListViewItem *>(lv->firstChild());
02219        }
02220 
02221        while(item)
02222        {
02223           item->m_odd = previous = !previous;
02224           item->m_known = true;
02225           item = dynamic_cast<KListViewItem *>(item->nextSibling());
02226        }
02227     }
02228     return m_odd;
02229   }
02230   return false;
02231 }
02232 
02233 void KListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
02234 {
02235   QColorGroup _cg = cg;
02236   const QPixmap *pm = listView()->viewport()->backgroundPixmap();
02237   if (pm && !pm->isNull())
02238   {
02239         _cg.setBrush(QColorGroup::Base, QBrush(backgroundColor(), *pm));
02240         QPoint o = p->brushOrigin();
02241         p->setBrushOrigin( o.x()-listView()->contentsX(), o.y()-listView()->contentsY() );
02242   }
02243   else if (isAlternate())
02244        if (listView()->viewport()->backgroundMode()==Qt::FixedColor)
02245             _cg.setColor(QColorGroup::Background, static_cast< KListView* >(listView())->alternateBackground());
02246        else
02247         _cg.setColor(QColorGroup::Base, static_cast< KListView* >(listView())->alternateBackground());
02248 
02249   QListViewItem::paintCell(p, _cg, column, width, alignment);
02250 }
02251 
02252 void KListView::virtual_hook( int, void* )
02253 { /*BASE::virtual_hook( id, data );*/ }
02254 
02255 #include "klistview.moc"
02256 #include "klistviewlineedit.moc"
02257 
02258 // vim: noet
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 23 17:11:54 2004 by doxygen 1.3.8-20040913 written by Dimitri van Heesch, © 1997-2003