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