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