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