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