| # kdeui Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

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

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 12:57:16 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001