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