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