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