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