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