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