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