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