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