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