klistview.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org> 00003 Copyright (C) 2000,2003 Charles Samuels <charles@kde.org> 00004 Copyright (C) 2000 Peter Putzer 00005 Copyright (C) 2014 Timothy Pearson <kb9vqf@pearsoncomputing.net> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License version 2 as published by the Free Software Foundation. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 #include "config.h" 00022 00023 #include <tqdragobject.h> 00024 #include <tqtimer.h> 00025 #include <tqheader.h> 00026 #include <tqcursor.h> 00027 #include <tqtooltip.h> 00028 #include <tqstyle.h> 00029 #include <tqpainter.h> 00030 00031 #include <kglobalsettings.h> 00032 #include <kconfig.h> 00033 #include <kcursor.h> 00034 #include <kapplication.h> 00035 #include <kipc.h> 00036 #include <kdebug.h> 00037 00038 #include "klistview.h" 00039 #include "klistviewlineedit.h" 00040 00041 class KListView::Tooltip : public TQToolTip 00042 { 00043 public: 00044 Tooltip (KListView* parent, TQToolTipGroup* group = 0L); 00045 virtual ~Tooltip () {} 00046 00047 protected: 00051 virtual void maybeTip (const TQPoint&); 00052 00053 private: 00054 KListView* mParent; 00055 }; 00056 00057 KListView::Tooltip::Tooltip (KListView* parent, TQToolTipGroup* group) 00058 : TQToolTip (parent, group), 00059 mParent (parent) 00060 { 00061 } 00062 00063 void KListView::Tooltip::maybeTip (const TQPoint&) 00064 { 00065 // FIXME 00066 } 00067 00068 class KListView::KListViewPrivate 00069 { 00070 public: 00071 KListViewPrivate (KListView* listview) 00072 : pCurrentItem (0), 00073 autoSelectDelay(0), 00074 dragOverItem(0), 00075 dragDelay (KGlobalSettings::dndEventDelay()), 00076 editor (new KListViewLineEdit (listview)), 00077 cursorInExecuteArea(false), 00078 itemsMovable (true), 00079 selectedBySimpleMove(false), 00080 selectedUsingMouse(false), 00081 itemsRenameable (false), 00082 validDrag (false), 00083 dragEnabled (false), 00084 autoOpen (true), 00085 disableAutoSelection (false), 00086 dropVisualizer (true), 00087 dropHighlighter (false), 00088 createChildren (true), 00089 pressedOnSelected (false), 00090 wasShiftEvent (false), 00091 fullWidth (false), 00092 sortAscending(true), 00093 tabRename(true), 00094 sortColumn(0), 00095 selectionDirection(0), 00096 selectionRegion(0), 00097 tooltipColumn (0), 00098 selectionMode (Single), 00099 contextMenuKey (KGlobalSettings::contextMenuKey()), 00100 showContextMenusOnPress (KGlobalSettings::showContextMenusOnPress()), 00101 mDropVisualizerWidth (4), 00102 paintAbove (0), 00103 paintCurrent (0), 00104 paintBelow (0), 00105 painting (false), 00106 shadeSortColumn(KGlobalSettings::shadeSortColumn()), 00107 initialFileManagerItem(0) 00108 { 00109 renameable.append(0); 00110 connect(editor, TQT_SIGNAL(done(TQListViewItem*,int)), listview, TQT_SLOT(doneEditing(TQListViewItem*,int))); 00111 } 00112 00113 ~KListViewPrivate () 00114 { 00115 delete editor; 00116 } 00117 00118 TQListViewItem* pCurrentItem; 00119 00120 TQTimer autoSelect; 00121 int autoSelectDelay; 00122 00123 TQTimer dragExpand; 00124 TQListViewItem* dragOverItem; 00125 TQPoint dragOverPoint; 00126 00127 TQPoint startDragPos; 00128 int dragDelay; 00129 00130 KListViewLineEdit *editor; 00131 TQValueList<int> renameable; 00132 00133 bool cursorInExecuteArea:1; 00134 bool bUseSingle:1; 00135 bool bChangeCursorOverItem:1; 00136 bool itemsMovable:1; 00137 bool selectedBySimpleMove : 1; 00138 bool selectedUsingMouse:1; 00139 bool itemsRenameable:1; 00140 bool validDrag:1; 00141 bool dragEnabled:1; 00142 bool autoOpen:1; 00143 bool disableAutoSelection:1; 00144 bool dropVisualizer:1; 00145 bool dropHighlighter:1; 00146 bool createChildren:1; 00147 bool pressedOnSelected:1; 00148 bool wasShiftEvent:1; 00149 bool fullWidth:1; 00150 bool sortAscending:1; 00151 bool tabRename:1; 00152 00153 int sortColumn; 00154 00155 //+1 means downwards (y increases, -1 means upwards, 0 means not selected), aleXXX 00156 int selectionDirection; 00157 int selectionRegion; 00158 int tooltipColumn; 00159 00160 SelectionModeExt selectionMode; 00161 int contextMenuKey; 00162 bool showContextMenusOnPress; 00163 00164 TQRect mOldDropVisualizer; 00165 int mDropVisualizerWidth; 00166 TQRect mOldDropHighlighter; 00167 TQListViewItem *afterItemDrop; 00168 TQListViewItem *parentItemDrop; 00169 00170 TQListViewItem *paintAbove; 00171 TQListViewItem *paintCurrent; 00172 TQListViewItem *paintBelow; 00173 bool painting:1; 00174 bool shadeSortColumn:1; 00175 00176 TQColor alternateBackground; 00177 00178 TQListViewItem *initialFileManagerItem; 00179 }; 00180 00181 00182 KListViewLineEdit::KListViewLineEdit(KListView *parent) 00183 : KLineEdit(parent->viewport()), item(0), col(0), p(parent) 00184 { 00185 setFrame( false ); 00186 hide(); 00187 connect( parent, TQT_SIGNAL( selectionChanged() ), TQT_SLOT( slotSelectionChanged() )); 00188 connect( parent, TQT_SIGNAL( itemRemoved( TQListViewItem * ) ), 00189 TQT_SLOT( slotItemRemoved( TQListViewItem * ) )); 00190 } 00191 00192 KListViewLineEdit::~KListViewLineEdit() 00193 { 00194 } 00195 00196 TQListViewItem *KListViewLineEdit::currentItem() const 00197 { 00198 return item; 00199 } 00200 00201 void KListViewLineEdit::load(TQListViewItem *i, int c) 00202 { 00203 item=i; 00204 col=c; 00205 00206 TQRect 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 TQHeader* 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 ) ) {// add width of pixmap 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 /* Helper functions to for 00238 * tabOrderedRename functionality. 00239 */ 00240 00241 static int nextCol (KListView *pl, TQListViewItem *pi, int start, int dir) 00242 { 00243 if (pi) 00244 { 00245 // Find the next renameable column in the current row 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 TQListViewItem *prevItem (TQListViewItem *pi) 00255 { 00256 TQListViewItem *pa = pi->itemAbove(); 00257 00258 /* Does what the TQListViewItem::previousSibling() 00259 * of my dreams would do. 00260 */ 00261 if (pa && pa->parent() == pi->parent()) 00262 return pa; 00263 00264 return 0; 00265 } 00266 00267 static TQListViewItem *lastQChild (TQListViewItem *pi) 00268 { 00269 if (pi) 00270 { 00271 /* Since there's no TQListViewItem::lastChild(). 00272 * This finds the last sibling for the given 00273 * item. 00274 */ 00275 for (TQListViewItem *pt = pi->nextSibling(); pt; pt = pt->nextSibling()) 00276 pi = pt; 00277 } 00278 00279 return pi; 00280 } 00281 00282 void KListViewLineEdit::selectNextCell (TQListViewItem *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 TQListViewItem *top = (pitem && pitem->parent()) 00288 ? pitem->parent()->firstChild() 00289 : p->firstChild(); 00290 TQListViewItem *pi = pitem; 00291 00292 terminate(); // Save current changes 00293 00294 do 00295 { 00296 /* Check the rest of the current row for an editable column, 00297 * if that fails, check the entire next/previous row. The 00298 * last case goes back to the first item in the current branch 00299 * or the last item in the current branch depending on the 00300 * direction. 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); // Calls terminate 00309 p->rename(pi, column); 00310 00311 /* Some listviews may override rename() to 00312 * prevent certain items from being renamed, 00313 * if this is done, [m_]item will be NULL 00314 * after the rename() call... try again. 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 KListViewLineEdit::event (TQEvent *pe) 00331 { 00332 if (pe->type() == TQEvent::KeyPress) 00333 { 00334 TQKeyEvent *k = (TQKeyEvent *) pe; 00335 00336 if ((k->key() == Qt::Key_Backtab || k->key() == Qt::Key_Tab) && 00337 p->tabOrderedRenaming() && p->itemsRenameable() && 00338 !(k->state() & ControlButton || k->state() & AltButton)) 00339 { 00340 selectNextCell(item, col, 00341 (k->key() == Key_Tab && !(k->state() & ShiftButton))); 00342 return true; 00343 } 00344 } 00345 00346 return KLineEdit::event(pe); 00347 } 00348 00349 void KListViewLineEdit::keyPressEvent(TQKeyEvent *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 KListViewLineEdit::terminate() 00365 { 00366 terminate(true); 00367 } 00368 00369 void KListViewLineEdit::terminate(bool commit) 00370 { 00371 if ( item ) 00372 { 00373 //kdDebug() << "KListViewLineEdit::terminate " << commit << endl; 00374 if (commit) 00375 item->setText(col, text()); 00376 int c=col; 00377 TQListViewItem *i=item; 00378 col=0; 00379 item=0; 00380 p->setFocus();// will call focusOutEvent, that's why we set item=0 before 00381 hide(); 00382 if (commit) 00383 emit done(i,c); 00384 } 00385 } 00386 00387 void KListViewLineEdit::focusOutEvent(TQFocusEvent *ev) 00388 { 00389 TQFocusEvent * focusEv = static_cast<TQFocusEvent*>(ev); 00390 // Don't let a RMB close the editor 00391 if (focusEv->reason() != TQFocusEvent::Popup && focusEv->reason() != TQFocusEvent::ActiveWindow) 00392 terminate(true); 00393 else 00394 KLineEdit::focusOutEvent(ev); 00395 } 00396 00397 void KListViewLineEdit::paintEvent( TQPaintEvent *e ) 00398 { 00399 KLineEdit::paintEvent( e ); 00400 00401 if ( !frame() ) { 00402 TQPainter p( this ); 00403 p.setClipRegion( e->region() ); 00404 p.drawRect( rect() ); 00405 } 00406 } 00407 00408 // selection changed -> terminate. As our "item" can be already deleted, 00409 // we can't call terminate(false), because that would emit done() with 00410 // a dangling pointer to "item". 00411 void KListViewLineEdit::slotSelectionChanged() 00412 { 00413 item = 0; 00414 col = 0; 00415 hide(); 00416 } 00417 00418 // if the current item was removed -> terminate. Can't call terminate(false) 00419 // due to same reason as slotSelectionChanged(). 00420 void KListViewLineEdit::slotItemRemoved(TQListViewItem *i) 00421 { 00422 if (currentItem() != i) 00423 return; 00424 00425 item = 0; 00426 col = 0; 00427 hide(); 00428 } 00429 00430 00431 KListView::KListView( TQWidget *parent, const char *name ) 00432 : TQListView( parent, name ), 00433 d (new KListViewPrivate (this)) 00434 { 00435 setDragAutoScroll(true); 00436 00437 connect( this, TQT_SIGNAL( onViewport() ), 00438 this, TQT_SLOT( slotOnViewport() ) ); 00439 connect( this, TQT_SIGNAL( onItem( TQListViewItem * ) ), 00440 this, TQT_SLOT( slotOnItem( TQListViewItem * ) ) ); 00441 00442 connect (this, TQT_SIGNAL(contentsMoving(int,int)), 00443 this, TQT_SLOT(cleanDropVisualizer())); 00444 connect (this, TQT_SIGNAL(contentsMoving(int,int)), 00445 this, TQT_SLOT(cleanItemHighlighter())); 00446 00447 slotSettingsChanged(KApplication::SETTINGS_MOUSE); 00448 if (kapp) 00449 { 00450 connect( kapp, TQT_SIGNAL( settingsChanged(int) ), TQT_SLOT( slotSettingsChanged(int) ) ); 00451 kapp->addKipcEventMask( KIPC::SettingsChanged ); 00452 } 00453 00454 connect(&d->autoSelect, TQT_SIGNAL( timeout() ), 00455 this, TQT_SLOT( slotAutoSelect() ) ); 00456 connect(&d->dragExpand, TQT_SIGNAL( timeout() ), 00457 this, TQT_SLOT( slotDragExpand() ) ); 00458 00459 // context menu handling 00460 if (d->showContextMenusOnPress) 00461 { 00462 connect (this, TQT_SIGNAL (rightButtonPressed (TQListViewItem*, const TQPoint&, int)), 00463 this, TQT_SLOT (emitContextMenu (TQListViewItem*, const TQPoint&, int))); 00464 } 00465 else 00466 { 00467 connect (this, TQT_SIGNAL (rightButtonClicked (TQListViewItem*, const TQPoint&, int)), 00468 this, TQT_SLOT (emitContextMenu (TQListViewItem*, const TQPoint&, int))); 00469 } 00470 00471 connect (this, TQT_SIGNAL (menuShortCutPressed (KListView*, TQListViewItem*)), 00472 this, TQT_SLOT (emitContextMenu (KListView*, TQListViewItem*))); 00473 d->alternateBackground = KGlobalSettings::alternateBackgroundColor(); 00474 } 00475 00476 KListView::~KListView() 00477 { 00478 delete d; 00479 } 00480 00481 bool KListView::isExecuteArea( const TQPoint& point ) 00482 { 00483 TQListViewItem* item = itemAt( point ); 00484 if ( item ) { 00485 return isExecuteArea( point.x(), item ); 00486 } 00487 00488 return false; 00489 } 00490 00491 bool KListView::isExecuteArea( int x ) 00492 { 00493 return isExecuteArea( x, 0 ); 00494 } 00495 00496 bool KListView::isExecuteArea( int x, TQListViewItem* item ) 00497 { 00498 if ( allColumnsShowFocus() ) { 00499 return true; 00500 } 00501 else { 00502 int offset = 0; 00503 int width = columnWidth( 0 ); 00504 00505 TQHeader* const thisHeader = header(); 00506 const int pos = thisHeader->mapToIndex( 0 ); 00507 00508 for ( int index = 0; index < pos; ++index ) { 00509 offset += columnWidth( thisHeader->mapToSection( index ) ); 00510 } 00511 00512 x += contentsX(); // in case of a horizontal scrollbar 00513 00514 // What was this supposed to do??? 00515 // Just use the column width, as at least one entire column is highlighted on row selection! 00516 #if 0 00517 if ( item ) { 00518 width = treeStepSize()*( item->depth() + ( rootIsDecorated() ? 1 : 0 ) ); 00519 width += itemMargin(); 00520 int ca = AlignHorizontal_Mask & columnAlignment( 0 ); 00521 if ( ca == AlignLeft || ca == AlignAuto ) { 00522 width += item->width( fontMetrics(), this, 0 ); 00523 if ( width > columnWidth( 0 ) ) { 00524 width = columnWidth( 0 ); 00525 } 00526 } 00527 } 00528 #endif 00529 if ( item ) { 00530 if (!allColumnsShowFocus()) { 00531 offset += treeStepSize()*( item->depth() + ( rootIsDecorated() ? 1 : 0 ) ); 00532 } 00533 } 00534 00535 return ( x > offset && x < ( offset + width ) ); 00536 } 00537 } 00538 00539 void KListView::slotOnItem( TQListViewItem *item ) 00540 { 00541 TQPoint vp = viewport()->mapFromGlobal( TQCursor::pos() ); 00542 if ( item && isExecuteArea( vp.x() ) && (d->autoSelectDelay > -1) && d->bUseSingle ) { 00543 d->autoSelect.start( d->autoSelectDelay, true ); 00544 d->pCurrentItem = item; 00545 } 00546 } 00547 00548 void KListView::slotOnViewport() 00549 { 00550 if ( d->bChangeCursorOverItem ) 00551 viewport()->unsetCursor(); 00552 00553 d->autoSelect.stop(); 00554 d->pCurrentItem = 0L; 00555 } 00556 00557 void KListView::slotSettingsChanged(int category) 00558 { 00559 switch (category) 00560 { 00561 case KApplication::SETTINGS_MOUSE: 00562 d->dragDelay = KGlobalSettings::dndEventDelay(); 00563 d->bUseSingle = KGlobalSettings::singleClick(); 00564 00565 disconnect(this, TQT_SIGNAL (mouseButtonClicked (int, TQListViewItem*, const TQPoint &, int)), 00566 this, TQT_SLOT (slotMouseButtonClicked (int, TQListViewItem*, const TQPoint &, int))); 00567 00568 if( d->bUseSingle ) 00569 connect (this, TQT_SIGNAL (mouseButtonClicked (int, TQListViewItem*, const TQPoint &, int)), 00570 this, TQT_SLOT (slotMouseButtonClicked( int, TQListViewItem*, const TQPoint &, int))); 00571 00572 d->bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon(); 00573 if ( !d->disableAutoSelection ) 00574 d->autoSelectDelay = KGlobalSettings::autoSelectDelay(); 00575 00576 if( !d->bUseSingle || !d->bChangeCursorOverItem ) 00577 viewport()->unsetCursor(); 00578 00579 break; 00580 00581 case KApplication::SETTINGS_POPUPMENU: 00582 d->contextMenuKey = KGlobalSettings::contextMenuKey (); 00583 d->showContextMenusOnPress = KGlobalSettings::showContextMenusOnPress (); 00584 00585 if (d->showContextMenusOnPress) 00586 { 00587 disconnect (0L, 0L, this, TQT_SLOT (emitContextMenu (TQListViewItem*, const TQPoint&, int))); 00588 00589 connect(this, TQT_SIGNAL (rightButtonPressed (TQListViewItem*, const TQPoint&, int)), 00590 this, TQT_SLOT (emitContextMenu (TQListViewItem*, const TQPoint&, int))); 00591 } 00592 else 00593 { 00594 disconnect (0L, 0L, this, TQT_SLOT (emitContextMenu (TQListViewItem*, const TQPoint&, int))); 00595 00596 connect(this, TQT_SIGNAL (rightButtonClicked (TQListViewItem*, const TQPoint&, int)), 00597 this, TQT_SLOT (emitContextMenu (TQListViewItem*, const TQPoint&, int))); 00598 } 00599 break; 00600 00601 default: 00602 break; 00603 } 00604 } 00605 00606 void KListView::slotAutoSelect() 00607 { 00608 // check that the item still exists 00609 if( itemIndex( d->pCurrentItem ) == -1 ) 00610 return; 00611 00612 if (!isActiveWindow()) 00613 { 00614 d->autoSelect.stop(); 00615 return; 00616 } 00617 00618 //Give this widget the keyboard focus. 00619 if( !hasFocus() ) 00620 setFocus(); 00621 00622 ButtonState keybstate = KApplication::keyboardMouseState(); 00623 00624 TQListViewItem* previousItem = currentItem(); 00625 setCurrentItem( d->pCurrentItem ); 00626 00627 if( d->pCurrentItem ) { 00628 //Shift pressed? 00629 if( (keybstate & TQt::ShiftButton) ) { 00630 bool block = signalsBlocked(); 00631 blockSignals( true ); 00632 00633 //No Ctrl? Then clear before! 00634 if( !(keybstate & TQt::ControlButton) ) 00635 clearSelection(); 00636 00637 bool select = !d->pCurrentItem->isSelected(); 00638 bool update = viewport()->isUpdatesEnabled(); 00639 viewport()->setUpdatesEnabled( false ); 00640 00641 bool down = previousItem->itemPos() < d->pCurrentItem->itemPos(); 00642 TQListViewItemIterator lit( down ? previousItem : d->pCurrentItem ); 00643 for ( ; lit.current(); ++lit ) { 00644 if ( down && lit.current() == d->pCurrentItem ) { 00645 d->pCurrentItem->setSelected( select ); 00646 break; 00647 } 00648 if ( !down && lit.current() == previousItem ) { 00649 previousItem->setSelected( select ); 00650 break; 00651 } 00652 lit.current()->setSelected( select ); 00653 } 00654 00655 blockSignals( block ); 00656 viewport()->setUpdatesEnabled( update ); 00657 triggerUpdate(); 00658 00659 emit selectionChanged(); 00660 00661 if( selectionMode() == TQListView::Single ) 00662 emit selectionChanged( d->pCurrentItem ); 00663 } 00664 else if( (keybstate & KApplication::ControlModifier) ) 00665 setSelected( d->pCurrentItem, !d->pCurrentItem->isSelected() ); 00666 else { 00667 bool block = signalsBlocked(); 00668 blockSignals( true ); 00669 00670 if( !d->pCurrentItem->isSelected() ) 00671 clearSelection(); 00672 00673 blockSignals( block ); 00674 00675 setSelected( d->pCurrentItem, true ); 00676 } 00677 } 00678 else 00679 kdDebug() << "KListView::slotAutoSelect: That�s not supposed to happen!!!!" << endl; 00680 } 00681 00682 void KListView::slotHeaderChanged() 00683 { 00684 00685 const int colCount = columns(); 00686 if (d->fullWidth && colCount) 00687 { 00688 int w = 0; 00689 const int lastColumn = colCount - 1; 00690 for (int i = 0; i < lastColumn; ++i) w += columnWidth(i); 00691 setColumnWidth( lastColumn, viewport()->width() - w - 1 ); 00692 } 00693 } 00694 00695 void KListView::emitExecute( TQListViewItem *item, const TQPoint &pos, int c ) 00696 { 00697 if( isExecuteArea( viewport()->mapFromGlobal(pos) ) ) { 00698 d->validDrag=false; 00699 00700 // Double click mode ? 00701 if ( !d->bUseSingle ) 00702 { 00703 viewport()->unsetCursor(); 00704 emit executed( item ); 00705 emit executed( item, pos, c ); 00706 } 00707 else 00708 { 00709 ButtonState keybstate = KApplication::keyboardMouseState(); 00710 00711 d->autoSelect.stop(); 00712 00713 //Don't emit executed if in SC mode and Shift or Ctrl are pressed 00714 if( !( ((keybstate & TQt::ShiftButton) || (keybstate & TQt::ControlButton)) ) ) { 00715 viewport()->unsetCursor(); 00716 emit executed( item ); 00717 emit executed( item, pos, c ); 00718 } 00719 } 00720 } 00721 } 00722 00723 void KListView::focusInEvent( TQFocusEvent *fe ) 00724 { 00725 // kdDebug()<<"KListView::focusInEvent()"<<endl; 00726 TQListView::focusInEvent( fe ); 00727 if ((d->selectedBySimpleMove) 00728 && (d->selectionMode == FileManager) 00729 && (fe->reason()!=TQFocusEvent::Popup) 00730 && (fe->reason()!=TQFocusEvent::ActiveWindow) 00731 && (currentItem())) 00732 { 00733 currentItem()->setSelected(true); 00734 currentItem()->repaint(); 00735 emit selectionChanged(); 00736 }; 00737 } 00738 00739 void KListView::focusOutEvent( TQFocusEvent *fe ) 00740 { 00741 cleanDropVisualizer(); 00742 cleanItemHighlighter(); 00743 00744 d->autoSelect.stop(); 00745 00746 if ((d->selectedBySimpleMove) 00747 && (d->selectionMode == FileManager) 00748 && (fe->reason()!=TQFocusEvent::Popup) 00749 && (fe->reason()!=TQFocusEvent::ActiveWindow) 00750 && (currentItem()) 00751 && (!d->editor->isVisible())) 00752 { 00753 currentItem()->setSelected(false); 00754 currentItem()->repaint(); 00755 emit selectionChanged(); 00756 }; 00757 00758 TQListView::focusOutEvent( fe ); 00759 } 00760 00761 void KListView::leaveEvent( TQEvent *e ) 00762 { 00763 d->autoSelect.stop(); 00764 00765 TQListView::leaveEvent( e ); 00766 } 00767 00768 bool KListView::event( TQEvent *e ) 00769 { 00770 if (e->type() == TQEvent::ApplicationPaletteChange) 00771 d->alternateBackground=KGlobalSettings::alternateBackgroundColor(); 00772 00773 return TQListView::event(e); 00774 } 00775 00776 void KListView::contentsMousePressEvent( TQMouseEvent *e ) 00777 { 00778 if( (selectionModeExt() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) ) 00779 { 00780 bool block = signalsBlocked(); 00781 blockSignals( true ); 00782 00783 clearSelection(); 00784 00785 blockSignals( block ); 00786 } 00787 else if ((selectionModeExt()==FileManager) && (d->selectedBySimpleMove)) 00788 { 00789 d->selectedBySimpleMove=false; 00790 d->selectedUsingMouse=true; 00791 if (currentItem()) 00792 { 00793 currentItem()->setSelected(false); 00794 currentItem()->repaint(); 00795 // emit selectionChanged(); 00796 } 00797 } 00798 00799 TQPoint p( contentsToViewport( e->pos() ) ); 00800 TQListViewItem *at = itemAt (p); 00801 00802 // true if the root decoration of the item "at" was clicked (i.e. the +/- sign) 00803 bool rootDecoClicked = at 00804 && ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) + 00805 treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ) 00806 && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) ); 00807 00808 if (e->button() == Qt::LeftButton && !rootDecoClicked) 00809 { 00810 //Start a drag 00811 d->startDragPos = e->pos(); 00812 00813 if (at) 00814 { 00815 d->validDrag = true; 00816 d->pressedOnSelected = at->isSelected(); 00817 } 00818 } 00819 00820 TQListView::contentsMousePressEvent( e ); 00821 } 00822 00823 void KListView::contentsMouseMoveEvent( TQMouseEvent *e ) 00824 { 00825 if (!dragEnabled() || d->startDragPos.isNull() || !d->validDrag) 00826 TQListView::contentsMouseMoveEvent (e); 00827 00828 TQPoint vp = contentsToViewport(e->pos()); 00829 TQListViewItem *item = itemAt( vp ); 00830 00831 //do we process cursor changes at all? 00832 if ( item && d->bChangeCursorOverItem && d->bUseSingle ) 00833 { 00834 //Cursor moved on a new item or in/out the execute area 00835 if( (item != d->pCurrentItem) || 00836 (isExecuteArea(vp) != d->cursorInExecuteArea) ) 00837 { 00838 d->cursorInExecuteArea = isExecuteArea(vp); 00839 00840 if( d->cursorInExecuteArea ) //cursor moved in execute area 00841 viewport()->setCursor( KCursor::handCursor() ); 00842 else //cursor moved out of execute area 00843 viewport()->unsetCursor(); 00844 } 00845 } 00846 00847 bool dragOn = dragEnabled(); 00848 TQPoint newPos = e->pos(); 00849 if (dragOn && d->validDrag && 00850 (newPos.x() > d->startDragPos.x()+d->dragDelay || 00851 newPos.x() < d->startDragPos.x()-d->dragDelay || 00852 newPos.y() > d->startDragPos.y()+d->dragDelay || 00853 newPos.y() < d->startDragPos.y()-d->dragDelay)) 00854 //(d->startDragPos - e->pos()).manhattanLength() > TQApplication::startDragDistance()) 00855 { 00856 TQListView::contentsMouseReleaseEvent( 0 ); 00857 startDrag(); 00858 d->startDragPos = TQPoint(); 00859 d->validDrag = false; 00860 } 00861 } 00862 00863 void KListView::contentsMouseReleaseEvent( TQMouseEvent *e ) 00864 { 00865 if (e->button() == Qt::LeftButton) 00866 { 00867 // If the row was already selected, maybe we want to start an in-place editing 00868 if ( d->pressedOnSelected && itemsRenameable() ) 00869 { 00870 TQPoint p( contentsToViewport( e->pos() ) ); 00871 TQListViewItem *at = itemAt (p); 00872 if ( at ) 00873 { 00874 // true if the root decoration of the item "at" was clicked (i.e. the +/- sign) 00875 bool rootDecoClicked = 00876 ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) + 00877 treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ) 00878 && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) ); 00879 00880 if (!rootDecoClicked) 00881 { 00882 int col = header()->mapToLogical( header()->cellAt( p.x() ) ); 00883 if ( d->renameable.contains(col) ) 00884 rename(at, col); 00885 } 00886 } 00887 } 00888 00889 d->pressedOnSelected = false; 00890 d->validDrag = false; 00891 d->startDragPos = TQPoint(); 00892 } 00893 TQListView::contentsMouseReleaseEvent( e ); 00894 } 00895 00896 void KListView::contentsMouseDoubleClickEvent ( TQMouseEvent *e ) 00897 { 00898 // We don't want to call the parent method because it does setOpen, 00899 // whereas we don't do it in single click mode... (David) 00900 //TQListView::contentsMouseDoubleClickEvent( e ); 00901 if ( !e || e->button() != Qt::LeftButton ) { 00902 return; 00903 } 00904 00905 TQPoint vp = contentsToViewport(e->pos()); 00906 TQListViewItem *item = itemAt( vp ); 00907 emit TQListView::doubleClicked( item ); // we do it now 00908 00909 int col = item ? header()->mapToLogical( header()->cellAt( vp.x() ) ) : -1; 00910 00911 if( item ) { 00912 emit doubleClicked( item, e->globalPos(), col ); 00913 00914 if( (e->button() == Qt::LeftButton) && !d->bUseSingle ) { 00915 emitExecute( item, e->globalPos(), col ); 00916 } 00917 } 00918 } 00919 00920 void KListView::slotMouseButtonClicked( int btn, TQListViewItem *item, const TQPoint &pos, int c ) 00921 { 00922 if( (btn == Qt::LeftButton) && item ) { 00923 emitExecute(item, pos, c); 00924 } 00925 } 00926 00927 void KListView::contentsDropEvent(TQDropEvent* e) 00928 { 00929 cleanDropVisualizer(); 00930 cleanItemHighlighter(); 00931 d->dragExpand.stop(); 00932 00933 if (acceptDrag (e)) 00934 { 00935 e->acceptAction(); 00936 TQListViewItem *afterme; 00937 TQListViewItem *parent; 00938 00939 findDrop(e->pos(), parent, afterme); 00940 00941 if (e->source() == viewport() && itemsMovable()) 00942 movableDropEvent(parent, afterme); 00943 else 00944 { 00945 emit dropped(e, afterme); 00946 emit dropped(this, e, afterme); 00947 emit dropped(e, parent, afterme); 00948 emit dropped(this, e, parent, afterme); 00949 } 00950 } 00951 } 00952 00953 void KListView::movableDropEvent (TQListViewItem* parent, TQListViewItem* afterme) 00954 { 00955 TQPtrList<TQListViewItem> items, afterFirsts, afterNows; 00956 TQListViewItem *current=currentItem(); 00957 bool hasMoved=false; 00958 for (TQListViewItem *i = firstChild(), *iNext=0; i; i = iNext) 00959 { 00960 iNext=i->itemBelow(); 00961 if (!i->isSelected()) 00962 continue; 00963 00964 // don't drop an item after itself, or else 00965 // it moves to the top of the list 00966 if (i==afterme) 00967 continue; 00968 00969 i->setSelected(false); 00970 00971 TQListViewItem *afterFirst = i->itemAbove(); 00972 00973 if (!hasMoved) 00974 { 00975 emit aboutToMove(); 00976 hasMoved=true; 00977 } 00978 00979 moveItem(i, parent, afterme); 00980 00981 // ###### This should include the new parent !!! -> KDE 3.0 00982 // If you need this right now, have a look at keditbookmarks. 00983 emit moved(i, afterFirst, afterme); 00984 00985 items.append (i); 00986 afterFirsts.append (afterFirst); 00987 afterNows.append (afterme); 00988 00989 afterme = i; 00990 } 00991 clearSelection(); 00992 for (TQListViewItem *i=items.first(); i; i=items.next() ) 00993 i->setSelected(true); 00994 if (current) 00995 setCurrentItem(current); 00996 00997 emit moved(items,afterFirsts,afterNows); 00998 00999 if (firstChild()) 01000 emit moved(); 01001 } 01002 01003 void KListView::contentsDragMoveEvent(TQDragMoveEvent *event) 01004 { 01005 if (acceptDrag(event)) 01006 { 01007 event->acceptAction(); 01008 //Clean up the view 01009 01010 findDrop(event->pos(), d->parentItemDrop, d->afterItemDrop); 01011 TQPoint vp = contentsToViewport( event->pos() ); 01012 TQListViewItem *item = isExecuteArea( vp ) ? itemAt( vp ) : 0L; 01013 01014 if ( item != d->dragOverItem ) 01015 { 01016 d->dragExpand.stop(); 01017 d->dragOverItem = item; 01018 d->dragOverPoint = vp; 01019 if ( d->dragOverItem && d->dragOverItem->isExpandable() && !d->dragOverItem->isOpen() ) 01020 d->dragExpand.start( TQApplication::startDragTime(), true ); 01021 } 01022 if (dropVisualizer()) 01023 { 01024 TQRect tmpRect = drawDropVisualizer(0, d->parentItemDrop, d->afterItemDrop); 01025 if (tmpRect != d->mOldDropVisualizer) 01026 { 01027 cleanDropVisualizer(); 01028 d->mOldDropVisualizer=tmpRect; 01029 viewport()->repaint(tmpRect); 01030 } 01031 } 01032 if (dropHighlighter()) 01033 { 01034 TQRect tmpRect = drawItemHighlighter(0, itemAt( vp )); 01035 if (tmpRect != d->mOldDropHighlighter) 01036 { 01037 cleanItemHighlighter(); 01038 d->mOldDropHighlighter=tmpRect; 01039 viewport()->repaint(tmpRect); 01040 } 01041 } 01042 } 01043 else 01044 event->ignore(); 01045 } 01046 01047 void KListView::slotDragExpand() 01048 { 01049 if ( itemAt( d->dragOverPoint ) == d->dragOverItem ) 01050 d->dragOverItem->setOpen( true ); 01051 } 01052 01053 void KListView::contentsDragLeaveEvent (TQDragLeaveEvent*) 01054 { 01055 d->dragExpand.stop(); 01056 cleanDropVisualizer(); 01057 cleanItemHighlighter(); 01058 } 01059 01060 void KListView::cleanDropVisualizer() 01061 { 01062 if (d->mOldDropVisualizer.isValid()) 01063 { 01064 TQRect rect=d->mOldDropVisualizer; 01065 d->mOldDropVisualizer = TQRect(); 01066 viewport()->repaint(rect, true); 01067 } 01068 } 01069 01070 int KListView::depthToPixels( int depth ) 01071 { 01072 return treeStepSize() * ( depth + (rootIsDecorated() ? 1 : 0) ) + itemMargin(); 01073 } 01074 01075 void KListView::findDrop(const TQPoint &pos, TQListViewItem *&parent, TQListViewItem *&after) 01076 { 01077 TQPoint p (contentsToViewport(pos)); 01078 01079 // Get the position to put it in 01080 TQListViewItem *atpos = itemAt(p); 01081 01082 TQListViewItem *above; 01083 if (!atpos) // put it at the end 01084 above = lastItem(); 01085 else 01086 { 01087 // Get the closest item before us ('atpos' or the one above, if any) 01088 if (p.y() - itemRect(atpos).topLeft().y() < (atpos->height()/2)) 01089 above = atpos->itemAbove(); 01090 else 01091 above = atpos; 01092 } 01093 01094 if (above) 01095 { 01096 // if above has children, I might need to drop it as the first item there 01097 01098 if (above->firstChild() && above->isOpen()) 01099 { 01100 parent = above; 01101 after = 0; 01102 return; 01103 } 01104 01105 // Now, we know we want to go after "above". But as a child or as a sibling ? 01106 // We have to ask the "above" item if it accepts children. 01107 if (above->isExpandable()) 01108 { 01109 // The mouse is sufficiently on the right ? - doesn't matter if 'above' has visible children 01110 if (p.x() >= depthToPixels( above->depth() + 1 ) || 01111 (above->isOpen() && above->childCount() > 0) ) 01112 { 01113 parent = above; 01114 after = 0L; 01115 return; 01116 } 01117 } 01118 01119 // Ok, there's one more level of complexity. We may want to become a new 01120 // sibling, but of an upper-level group, rather than the "above" item 01121 TQListViewItem * betterAbove = above->parent(); 01122 TQListViewItem * last = above; 01123 while ( betterAbove ) 01124 { 01125 // We are allowed to become a sibling of "betterAbove" only if we are 01126 // after its last child 01127 if ( !last->nextSibling() ) 01128 { 01129 if (p.x() < depthToPixels ( betterAbove->depth() + 1 )) 01130 above = betterAbove; // store this one, but don't stop yet, there may be a better one 01131 else 01132 break; // not enough on the left, so stop 01133 last = betterAbove; 01134 betterAbove = betterAbove->parent(); // up one level 01135 } else 01136 break; // we're among the child of betterAbove, not after the last one 01137 } 01138 } 01139 // set as sibling 01140 after = above; 01141 parent = after ? after->parent() : 0L ; 01142 } 01143 01144 TQListViewItem* KListView::lastChild () const 01145 { 01146 TQListViewItem* lastchild = firstChild(); 01147 01148 if (lastchild) 01149 for (; lastchild->nextSibling(); lastchild = lastchild->nextSibling()); 01150 01151 return lastchild; 01152 } 01153 01154 TQListViewItem *KListView::lastItem() const 01155 { 01156 TQListViewItem* last = lastChild(); 01157 01158 for (TQListViewItemIterator it (last); it.current(); ++it) 01159 last = it.current(); 01160 01161 return last; 01162 } 01163 01164 KLineEdit *KListView::renameLineEdit() const 01165 { 01166 return d->editor; 01167 } 01168 01169 void KListView::startDrag() 01170 { 01171 TQDragObject *drag = dragObject(); 01172 01173 if (!drag) 01174 return; 01175 01176 if (drag->drag() && drag->target() != viewport()) 01177 emit moved(); 01178 } 01179 01180 TQDragObject *KListView::dragObject() 01181 { 01182 if (!currentItem()) 01183 return 0; 01184 01185 01186 return new TQStoredDrag("application/x-qlistviewitem", viewport()); 01187 } 01188 01189 void KListView::setItemsMovable(bool b) 01190 { 01191 d->itemsMovable=b; 01192 } 01193 01194 bool KListView::itemsMovable() const 01195 { 01196 return d->itemsMovable; 01197 } 01198 01199 void KListView::setItemsRenameable(bool b) 01200 { 01201 d->itemsRenameable=b; 01202 } 01203 01204 bool KListView::itemsRenameable() const 01205 { 01206 return d->itemsRenameable; 01207 } 01208 01209 01210 void KListView::setDragEnabled(bool b) 01211 { 01212 d->dragEnabled=b; 01213 } 01214 01215 bool KListView::dragEnabled() const 01216 { 01217 return d->dragEnabled; 01218 } 01219 01220 void KListView::setAutoOpen(bool b) 01221 { 01222 d->autoOpen=b; 01223 } 01224 01225 bool KListView::autoOpen() const 01226 { 01227 return d->autoOpen; 01228 } 01229 01230 bool KListView::dropVisualizer() const 01231 { 01232 return d->dropVisualizer; 01233 } 01234 01235 void KListView::setDropVisualizer(bool b) 01236 { 01237 d->dropVisualizer=b; 01238 } 01239 01240 TQPtrList<TQListViewItem> KListView::selectedItems() const 01241 { 01242 return selectedItems(true); 01243 } 01244 01245 TQPtrList<TQListViewItem> KListView::selectedItems(bool includeHiddenItems) const 01246 { 01247 TQPtrList<TQListViewItem> list; 01248 01249 // Using selectionMode() instead of selectionModeExt() since for the cases that 01250 // we're interested in selectionMode() should work for either variety of the 01251 // setSelectionMode(). 01252 01253 switch(selectionMode()) 01254 { 01255 case NoSelection: 01256 break; 01257 case Single: 01258 if(selectedItem() && (includeHiddenItems || selectedItem()->isVisible())) 01259 list.append(selectedItem()); 01260 break; 01261 default: 01262 { 01263 int flags = TQListViewItemIterator::Selected; 01264 if (!includeHiddenItems) 01265 { 01266 flags |= TQListViewItemIterator::Visible; 01267 } 01268 01269 TQListViewItemIterator it(const_cast<KListView *>(this), flags); 01270 01271 for(; it.current(); ++it) 01272 list.append(it.current()); 01273 01274 break; 01275 } 01276 } 01277 01278 return list; 01279 } 01280 01281 01282 void KListView::moveItem(TQListViewItem *item, TQListViewItem *parent, TQListViewItem *after) 01283 { 01284 // sanity check - don't move a item into its own child structure 01285 TQListViewItem *i = parent; 01286 while(i) 01287 { 01288 if(i == item) 01289 return; 01290 i = i->parent(); 01291 } 01292 01293 if (after) 01294 { 01295 item->moveItem(after); 01296 return; 01297 } 01298 01299 // Basically reimplementing the TQListViewItem(TQListViewItem*, TQListViewItem*) constructor 01300 // in here, without ever deleting the item. 01301 if (item->parent()) 01302 item->parent()->takeItem(item); 01303 else 01304 takeItem(item); 01305 01306 if (parent) 01307 parent->insertItem(item); 01308 else 01309 insertItem(item); 01310 } 01311 01312 void KListView::contentsDragEnterEvent(TQDragEnterEvent *event) 01313 { 01314 if (acceptDrag (event)) 01315 event->accept(); 01316 } 01317 01318 void KListView::setDropVisualizerWidth (int w) 01319 { 01320 d->mDropVisualizerWidth = w > 0 ? w : 1; 01321 } 01322 01323 TQRect KListView::drawDropVisualizer(TQPainter *p, TQListViewItem *parent, 01324 TQListViewItem *after) 01325 { 01326 TQRect insertmarker; 01327 01328 if (!after && !parent) 01329 insertmarker = TQRect (0, 0, viewport()->width(), d->mDropVisualizerWidth/2); 01330 else 01331 { 01332 int level = 0; 01333 if (after) 01334 { 01335 TQListViewItem* it = 0L; 01336 if (after->isOpen()) 01337 { 01338 // Look for the last child (recursively) 01339 it = after->firstChild(); 01340 if (it) 01341 while (it->nextSibling() || it->firstChild()) 01342 if ( it->nextSibling() ) 01343 it = it->nextSibling(); 01344 else 01345 it = it->firstChild(); 01346 } 01347 01348 insertmarker = itemRect (it ? it : after); 01349 level = after->depth(); 01350 } 01351 else if (parent) 01352 { 01353 insertmarker = itemRect (parent); 01354 level = parent->depth() + 1; 01355 } 01356 insertmarker.setLeft( treeStepSize() * ( level + (rootIsDecorated() ? 1 : 0) ) + itemMargin() ); 01357 insertmarker.setRight (viewport()->width()); 01358 insertmarker.setTop (insertmarker.bottom() - d->mDropVisualizerWidth/2 + 1); 01359 insertmarker.setBottom (insertmarker.bottom() + d->mDropVisualizerWidth/2); 01360 } 01361 01362 // This is not used anymore, at least by KListView itself (see viewportPaintEvent) 01363 // Remove for KDE 4.0. 01364 if (p) 01365 p->fillRect(insertmarker, Dense4Pattern); 01366 01367 return insertmarker; 01368 } 01369 01370 TQRect KListView::drawItemHighlighter(TQPainter *painter, TQListViewItem *item) 01371 { 01372 TQRect r; 01373 01374 if (item) 01375 { 01376 r = itemRect(item); 01377 r.setLeft(r.left()+(item->depth()+(rootIsDecorated() ? 1 : 0))*treeStepSize()); 01378 if (painter) 01379 style().tqdrawPrimitive(TQStyle::PE_FocusRect, painter, r, colorGroup(), 01380 TQStyle::Style_FocusAtBorder, colorGroup().highlight()); 01381 } 01382 01383 return r; 01384 } 01385 01386 void KListView::cleanItemHighlighter () 01387 { 01388 if (d->mOldDropHighlighter.isValid()) 01389 { 01390 TQRect rect=d->mOldDropHighlighter; 01391 d->mOldDropHighlighter = TQRect(); 01392 viewport()->repaint(rect, true); 01393 } 01394 } 01395 01396 void KListView::rename(TQListViewItem *item, int c) 01397 { 01398 if (d->renameable.contains(c)) 01399 { 01400 ensureItemVisible(item); 01401 d->editor->load(item,c); 01402 } 01403 } 01404 01405 bool KListView::isRenameable (int col) const 01406 { 01407 return d->renameable.contains(col); 01408 } 01409 01410 void KListView::setRenameable (int col, bool renameable) 01411 { 01412 if (col>=header()->count()) return; 01413 01414 d->renameable.remove(col); 01415 if (renameable) 01416 d->renameable+=col; 01417 } 01418 01419 void KListView::doneEditing(TQListViewItem *item, int row) 01420 { 01421 emit itemRenamed(item, item->text(row), row); 01422 emit itemRenamed(item); 01423 } 01424 01425 bool KListView::acceptDrag(TQDropEvent* e) const 01426 { 01427 return acceptDrops() && itemsMovable() && (e->source()==viewport()); 01428 } 01429 01430 void KListView::setCreateChildren(bool b) 01431 { 01432 d->createChildren=b; 01433 } 01434 01435 bool KListView::createChildren() const 01436 { 01437 return d->createChildren; 01438 } 01439 01440 01441 int KListView::tooltipColumn() const 01442 { 01443 return d->tooltipColumn; 01444 } 01445 01446 void KListView::setTooltipColumn(int column) 01447 { 01448 d->tooltipColumn=column; 01449 } 01450 01451 void KListView::setDropHighlighter(bool b) 01452 { 01453 d->dropHighlighter=b; 01454 } 01455 01456 bool KListView::dropHighlighter() const 01457 { 01458 return d->dropHighlighter; 01459 } 01460 01461 bool KListView::showTooltip(TQListViewItem *item, const TQPoint &, int column) const 01462 { 01463 return ((column==tooltipColumn()) && !tooltip(item, column).isEmpty()); 01464 } 01465 01466 TQString KListView::tooltip(TQListViewItem *item, int column) const 01467 { 01468 return item->text(column); 01469 } 01470 01471 void KListView::setTabOrderedRenaming(bool b) 01472 { 01473 d->tabRename = b; 01474 } 01475 01476 bool KListView::tabOrderedRenaming() const 01477 { 01478 return d->tabRename; 01479 } 01480 01481 void KListView::keyPressEvent (TQKeyEvent* e) 01482 { 01483 //don't we need a contextMenuModifier too ? (aleXXX) 01484 if (e->key() == d->contextMenuKey) 01485 { 01486 emit menuShortCutPressed (this, currentItem()); 01487 return; 01488 } 01489 01490 if (d->selectionMode != FileManager) 01491 TQListView::keyPressEvent (e); 01492 else 01493 fileManagerKeyPressEvent (e); 01494 } 01495 01496 void KListView::activateAutomaticSelection() 01497 { 01498 d->selectedBySimpleMove=true; 01499 d->selectedUsingMouse=false; 01500 if (currentItem()) 01501 { 01502 currentItem()->setSelected(true); 01503 currentItem()->repaint(); 01504 emit selectionChanged(); 01505 }; 01506 } 01507 01508 void KListView::deactivateAutomaticSelection() 01509 { 01510 d->selectedBySimpleMove=false; 01511 } 01512 01513 bool KListView::automaticSelection() const 01514 { 01515 return d->selectedBySimpleMove; 01516 } 01517 01518 void KListView::resetKeyboardSelectionOperation() 01519 { 01520 d->wasShiftEvent = false; 01521 d->selectionDirection = 0; 01522 } 01523 01524 void KListView::setActiveMultiSelectItem(TQListViewItem *item) { 01525 TQListViewItem* origItem = currentItem(); 01526 if (!d->initialFileManagerItem) { 01527 d->initialFileManagerItem = origItem; 01528 } 01529 setCurrentItem(item); 01530 } 01531 01532 void KListView::fileManagerKeyPressEvent (TQKeyEvent* e) 01533 { 01534 //don't care whether it's on the keypad or not 01535 int e_state=(e->state() & ~Keypad); 01536 01537 // Handle non-control keypresses 01538 if ((e->key()!=Key_Shift) && (e->key()!=Key_Control) 01539 && (e->key()!=Key_Meta) && (e->key()!=Key_Alt)) { 01540 if ((e_state==ShiftButton) && (!d->wasShiftEvent) && (!d->selectedBySimpleMove)) { 01541 selectAll(false); 01542 d->selectionRegion = 0; 01543 d->initialFileManagerItem = NULL; 01544 } 01545 d->selectionDirection=0; 01546 d->wasShiftEvent = (e_state == ShiftButton); 01547 } 01548 01549 //d->wasShiftEvent = (e_state == ShiftButton); 01550 01551 TQListViewItem* item = currentItem(); 01552 if (!item) { 01553 return; 01554 } 01555 01556 TQListViewItem* repaintItem1 = item; 01557 TQListViewItem* repaintItem2 = 0L; 01558 TQListViewItem* visItem = 0L; 01559 01560 TQListViewItem* nextItem = 0L; 01561 int items = 0; 01562 01563 bool shiftOrCtrl((e_state==ControlButton) || (e_state==ShiftButton)); 01564 int selectedItems(0); 01565 for (TQListViewItem *tmpItem=firstChild(); tmpItem; tmpItem=tmpItem->nextSibling()) { 01566 if (tmpItem->isSelected()) selectedItems++; 01567 } 01568 01569 if (((!selectedItems) || ((selectedItems==1) && (d->selectedUsingMouse))) 01570 && (e_state==Qt::NoButton) 01571 && ((e->key()==Key_Down) 01572 || (e->key()==Key_Up) 01573 || (e->key()==Key_Next) 01574 || (e->key()==Key_Prior) 01575 || (e->key()==Key_Home) 01576 || (e->key()==Key_End))) { 01577 d->selectedBySimpleMove=true; 01578 d->selectedUsingMouse=false; 01579 } 01580 else if (selectedItems>1) { 01581 d->selectedBySimpleMove=false; 01582 } 01583 01584 bool emitSelectionChanged(false); 01585 01586 switch (e->key()) { 01587 case Key_Escape: 01588 selectAll(false); 01589 emitSelectionChanged=true; 01590 break; 01591 01592 case Key_Space: 01593 //toggle selection of current item 01594 if (d->selectedBySimpleMove) { 01595 d->selectedBySimpleMove=false; 01596 } 01597 item->setSelected(!item->isSelected()); 01598 emitSelectionChanged=true; 01599 break; 01600 01601 case Key_Insert: 01602 //toggle selection of current item and move to the next item 01603 if (d->selectedBySimpleMove) { 01604 d->selectedBySimpleMove=false; 01605 if (!item->isSelected()) item->setSelected(true); 01606 } 01607 else { 01608 item->setSelected(!item->isSelected()); 01609 } 01610 01611 nextItem=item->itemBelow(); 01612 01613 if (nextItem) { 01614 repaintItem2=nextItem; 01615 visItem=nextItem; 01616 setCurrentItem(nextItem); 01617 } 01618 d->selectionDirection=1; 01619 emitSelectionChanged=true; 01620 break; 01621 01622 case Key_Down: 01623 nextItem=item->itemBelow(); 01624 if (shiftOrCtrl) { 01625 d->selectionDirection=1; 01626 d->selectedBySimpleMove=false; 01627 if (!d->initialFileManagerItem) { 01628 d->initialFileManagerItem = item; 01629 item->setSelected(true); 01630 if (nextItem) { 01631 nextItem->setSelected(true); 01632 } 01633 emitSelectionChanged=true; 01634 d->selectionRegion=1; 01635 } 01636 else { 01637 if (item == d->initialFileManagerItem) { 01638 item->setSelected(true); 01639 if (nextItem) { 01640 nextItem->setSelected(true); 01641 } 01642 emitSelectionChanged=true; 01643 d->selectionRegion=1; 01644 } 01645 else { 01646 if (d->selectionRegion == 1) { 01647 if (nextItem) { 01648 nextItem->setSelected(true); 01649 } 01650 emitSelectionChanged=true; 01651 } 01652 else if (d->selectionRegion == -1) { 01653 item->setSelected(false); 01654 emitSelectionChanged=true; 01655 } 01656 } 01657 } 01658 } 01659 else if ((d->selectedBySimpleMove) && (nextItem)) { 01660 item->setSelected(false); 01661 emitSelectionChanged=true; 01662 } 01663 01664 if (nextItem) { 01665 if (d->selectedBySimpleMove) { 01666 nextItem->setSelected(true); 01667 } 01668 repaintItem2=nextItem; 01669 visItem=nextItem; 01670 setCurrentItem(nextItem); 01671 } 01672 break; 01673 01674 case Key_Up: 01675 nextItem=item->itemAbove(); 01676 if (shiftOrCtrl) { 01677 d->selectionDirection=-1; 01678 d->selectedBySimpleMove=false; 01679 if (!d->initialFileManagerItem) { 01680 d->initialFileManagerItem = item; 01681 item->setSelected(true); 01682 if (nextItem) { 01683 nextItem->setSelected(true); 01684 } 01685 emitSelectionChanged=true; 01686 d->selectionRegion=-1; 01687 } 01688 else { 01689 if (item == d->initialFileManagerItem) { 01690 item->setSelected(true); 01691 if (nextItem) { 01692 nextItem->setSelected(true); 01693 } 01694 emitSelectionChanged=true; 01695 d->selectionRegion=-1; 01696 } 01697 else { 01698 if (d->selectionRegion == -1) { 01699 if (nextItem) { 01700 nextItem->setSelected(true); 01701 } 01702 emitSelectionChanged=true; 01703 } 01704 else if (d->selectionRegion == 1) { 01705 item->setSelected(false); 01706 emitSelectionChanged=true; 01707 } 01708 } 01709 } 01710 } 01711 else if ((d->selectedBySimpleMove) && (nextItem)) { 01712 item->setSelected(false); 01713 emitSelectionChanged=true; 01714 } 01715 01716 if (nextItem) { 01717 if (d->selectedBySimpleMove) { 01718 nextItem->setSelected(true); 01719 } 01720 repaintItem2=nextItem; 01721 visItem=nextItem; 01722 setCurrentItem(nextItem); 01723 } 01724 break; 01725 01726 case Key_End: 01727 // move to the last item and toggle selection of all items in-between 01728 nextItem=item; 01729 if (d->selectedBySimpleMove) { 01730 item->setSelected(false); 01731 } 01732 if (shiftOrCtrl) { 01733 d->selectedBySimpleMove=false; 01734 } 01735 01736 while (nextItem) { 01737 if (shiftOrCtrl) { 01738 if (!d->initialFileManagerItem) { 01739 d->initialFileManagerItem = nextItem; 01740 nextItem->setSelected(true); 01741 emitSelectionChanged=true; 01742 d->selectionRegion=1; 01743 } 01744 else { 01745 if (nextItem == d->initialFileManagerItem) { 01746 nextItem->setSelected(true); 01747 emitSelectionChanged=true; 01748 d->selectionRegion=1; 01749 } 01750 else { 01751 if (d->selectionRegion == 1) { 01752 nextItem->setSelected(true); 01753 emitSelectionChanged=true; 01754 } 01755 else if (d->selectionRegion == -1) { 01756 nextItem->setSelected(false); 01757 emitSelectionChanged=true; 01758 } 01759 } 01760 } 01761 } 01762 if (!nextItem->itemBelow()) { 01763 if (d->selectedBySimpleMove) { 01764 nextItem->setSelected(true); 01765 } 01766 repaintItem2=nextItem; 01767 visItem=nextItem; 01768 setCurrentItem(nextItem); 01769 } 01770 nextItem=nextItem->itemBelow(); 01771 } 01772 emitSelectionChanged=true; 01773 break; 01774 01775 case Key_Home: 01776 // move to the first item and toggle selection of all items in-between 01777 nextItem=item; 01778 if (d->selectedBySimpleMove) { 01779 item->setSelected(false); 01780 } 01781 if (shiftOrCtrl) { 01782 d->selectedBySimpleMove=false; 01783 } 01784 01785 while (nextItem) { 01786 if (shiftOrCtrl) { 01787 if (!d->initialFileManagerItem) { 01788 d->initialFileManagerItem = nextItem; 01789 nextItem->setSelected(true); 01790 emitSelectionChanged=true; 01791 d->selectionRegion=-1; 01792 } 01793 else { 01794 if (nextItem == d->initialFileManagerItem) { 01795 nextItem->setSelected(true); 01796 emitSelectionChanged=true; 01797 d->selectionRegion=-1; 01798 } 01799 else { 01800 if (d->selectionRegion == -1) { 01801 nextItem->setSelected(true); 01802 emitSelectionChanged=true; 01803 } 01804 else if (d->selectionRegion == 1) { 01805 nextItem->setSelected(false); 01806 emitSelectionChanged=true; 01807 } 01808 } 01809 } 01810 } 01811 if (!nextItem->itemAbove()) { 01812 if (d->selectedBySimpleMove) { 01813 nextItem->setSelected(true); 01814 } 01815 repaintItem2=nextItem; 01816 visItem=nextItem; 01817 setCurrentItem(nextItem); 01818 } 01819 nextItem=nextItem->itemAbove(); 01820 } 01821 emitSelectionChanged=true; 01822 break; 01823 01824 case Key_Next: 01825 items=visibleHeight()/item->height(); 01826 nextItem=item; 01827 if (d->selectedBySimpleMove) { 01828 item->setSelected(false); 01829 } 01830 if (shiftOrCtrl) { 01831 d->selectedBySimpleMove=false; 01832 d->selectionDirection=1; 01833 } 01834 01835 for (int i=0; i<items; i++) { 01836 if (shiftOrCtrl) { 01837 if (!d->initialFileManagerItem) { 01838 d->initialFileManagerItem = nextItem; 01839 nextItem->setSelected(true); 01840 emitSelectionChanged=true; 01841 d->selectionRegion=1; 01842 } 01843 else { 01844 if (nextItem == d->initialFileManagerItem) { 01845 nextItem->setSelected(true); 01846 emitSelectionChanged=true; 01847 d->selectionRegion=1; 01848 } 01849 else { 01850 if (d->selectionRegion == 1) { 01851 nextItem->setSelected(true); 01852 emitSelectionChanged=true; 01853 } 01854 else if (d->selectionRegion == -1) { 01855 if (i==items-1) { 01856 nextItem->setSelected(true); 01857 } 01858 else { 01859 nextItem->setSelected(false); 01860 } 01861 emitSelectionChanged=true; 01862 } 01863 } 01864 } 01865 } 01866 // last item 01867 if ((i==items-1) || (!nextItem->itemBelow())) { 01868 if (d->selectedBySimpleMove) { 01869 nextItem->setSelected(true); 01870 } 01871 ensureItemVisible(nextItem); 01872 setCurrentItem(nextItem); 01873 update(); 01874 if ((shiftOrCtrl) || (d->selectedBySimpleMove)) { 01875 emit selectionChanged(); 01876 } 01877 return; 01878 } 01879 nextItem=nextItem->itemBelow(); 01880 } 01881 break; 01882 01883 case Key_Prior: 01884 items=visibleHeight()/item->height(); 01885 nextItem=item; 01886 if (d->selectedBySimpleMove) { 01887 item->setSelected(false); 01888 } 01889 if (shiftOrCtrl) { 01890 d->selectionDirection=-1; 01891 d->selectedBySimpleMove=false; 01892 } 01893 01894 for (int i=0; i<items; i++) { 01895 if (shiftOrCtrl) { 01896 if (!d->initialFileManagerItem) { 01897 d->initialFileManagerItem = nextItem; 01898 nextItem->setSelected(true); 01899 emitSelectionChanged=true; 01900 d->selectionRegion=-1; 01901 } 01902 else { 01903 if (nextItem == d->initialFileManagerItem) { 01904 nextItem->setSelected(true); 01905 emitSelectionChanged=true; 01906 d->selectionRegion=-1; 01907 } 01908 else { 01909 if (d->selectionRegion == -1) { 01910 nextItem->setSelected(true); 01911 emitSelectionChanged=true; 01912 } 01913 else if (d->selectionRegion == 1) { 01914 if (i==items-1) { 01915 nextItem->setSelected(true); 01916 } 01917 else { 01918 nextItem->setSelected(false); 01919 } 01920 emitSelectionChanged=true; 01921 } 01922 } 01923 } 01924 } 01925 // last item 01926 if ((i==items-1) || (!nextItem->itemAbove())) { 01927 if (d->selectedBySimpleMove) { 01928 nextItem->setSelected(true); 01929 } 01930 ensureItemVisible(nextItem); 01931 setCurrentItem(nextItem); 01932 update(); 01933 if ((shiftOrCtrl) || (d->selectedBySimpleMove)) { 01934 emit selectionChanged(); 01935 } 01936 return; 01937 } 01938 nextItem=nextItem->itemAbove(); 01939 } 01940 break; 01941 01942 case Key_Minus: 01943 if ( item->isOpen() ) { 01944 setOpen( item, false ); 01945 } 01946 break; 01947 case Key_Plus: 01948 if ( !item->isOpen() && (item->isExpandable() || item->childCount()) ) { 01949 setOpen( item, true ); 01950 } 01951 break; 01952 default: 01953 bool realKey = ((e->key()!=Key_Shift) && (e->key()!=Key_Control) 01954 && (e->key()!=Key_Meta) && (e->key()!=Key_Alt)); 01955 01956 bool selectCurrentItem = (d->selectedBySimpleMove) && (item->isSelected()); 01957 if (realKey && selectCurrentItem) { 01958 item->setSelected(false); 01959 } 01960 //this is mainly for the "goto filename beginning with pressed char" feature (aleXXX) 01961 TQListView::SelectionMode oldSelectionMode = selectionMode(); 01962 setSelectionMode (TQListView::Multi); 01963 TQListView::keyPressEvent (e); 01964 setSelectionMode (oldSelectionMode); 01965 if (realKey && selectCurrentItem) { 01966 currentItem()->setSelected(true); 01967 emitSelectionChanged=true; 01968 } 01969 repaintItem2=currentItem(); 01970 if (realKey) { 01971 visItem=currentItem(); 01972 } 01973 break; 01974 } 01975 01976 if (visItem) { 01977 ensureItemVisible(visItem); 01978 } 01979 01980 TQRect ir; 01981 if (repaintItem1) { 01982 ir = ir.unite( itemRect(repaintItem1) ); 01983 } 01984 if (repaintItem2) { 01985 ir = ir.unite( itemRect(repaintItem2) ); 01986 } 01987 01988 if ( !ir.isEmpty() ) { 01989 // rectangle to be repainted 01990 if ( ir.x() < 0 ) { 01991 ir.moveBy( -ir.x(), 0 ); 01992 } 01993 viewport()->repaint( ir, false ); 01994 } 01995 /*if (repaintItem1) { 01996 repaintItem1->repaint(); 01997 } 01998 if (repaintItem2) { 01999 repaintItem2->repaint(); 02000 }*/ 02001 02002 update(); 02003 if (emitSelectionChanged) { 02004 emit selectionChanged(); 02005 } 02006 } 02007 02008 void KListView::setSelectionModeExt (SelectionModeExt mode) 02009 { 02010 d->selectionMode = mode; 02011 02012 switch (mode) 02013 { 02014 case Single: 02015 case Multi: 02016 case Extended: 02017 case NoSelection: 02018 setSelectionMode (static_cast<TQListView::SelectionMode>(static_cast<int>(mode))); 02019 break; 02020 02021 case FileManager: 02022 setSelectionMode (TQListView::Extended); 02023 break; 02024 02025 default: 02026 kdWarning () << "Warning: illegal selection mode " << int(mode) << " set!" << endl; 02027 break; 02028 } 02029 } 02030 02031 KListView::SelectionModeExt KListView::selectionModeExt () const 02032 { 02033 return d->selectionMode; 02034 } 02035 02036 int KListView::itemIndex( const TQListViewItem *item ) const 02037 { 02038 if ( !item ) 02039 return -1; 02040 02041 if ( item == firstChild() ) 02042 return 0; 02043 else { 02044 TQListViewItemIterator it(firstChild()); 02045 uint j = 0; 02046 for (; it.current() && it.current() != item; ++it, ++j ); 02047 02048 if( !it.current() ) 02049 return -1; 02050 02051 return j; 02052 } 02053 } 02054 02055 TQListViewItem* KListView::itemAtIndex(int index) 02056 { 02057 if (index<0) 02058 return 0; 02059 02060 int j(0); 02061 for (TQListViewItemIterator it=firstChild(); it.current(); ++it) 02062 { 02063 if (j==index) 02064 return it.current(); 02065 ++j; 02066 }; 02067 return 0; 02068 } 02069 02070 02071 void KListView::emitContextMenu (KListView*, TQListViewItem* i) 02072 { 02073 TQPoint p; 02074 02075 if (i) 02076 p = viewport()->mapToGlobal(itemRect(i).center()); 02077 else 02078 p = mapToGlobal(rect().center()); 02079 02080 emit contextMenu (this, i, p); 02081 } 02082 02083 void KListView::emitContextMenu (TQListViewItem* i, const TQPoint& p, int) 02084 { 02085 emit contextMenu (this, i, p); 02086 } 02087 02088 void KListView::setAcceptDrops (bool val) 02089 { 02090 TQListView::setAcceptDrops (val); 02091 viewport()->setAcceptDrops (val); 02092 } 02093 02094 int KListView::dropVisualizerWidth () const 02095 { 02096 return d->mDropVisualizerWidth; 02097 } 02098 02099 02100 void KListView::viewportPaintEvent(TQPaintEvent *e) 02101 { 02102 d->paintAbove = 0; 02103 d->paintCurrent = 0; 02104 d->paintBelow = 0; 02105 d->painting = true; 02106 02107 TQListView::viewportPaintEvent(e); 02108 02109 if (d->mOldDropVisualizer.isValid() && e->rect().intersects(d->mOldDropVisualizer)) 02110 { 02111 TQPainter painter(viewport()); 02112 02113 // This is where we actually draw the drop-visualizer 02114 painter.fillRect(d->mOldDropVisualizer, Dense4Pattern); 02115 } 02116 if (d->mOldDropHighlighter.isValid() && e->rect().intersects(d->mOldDropHighlighter)) 02117 { 02118 TQPainter painter(viewport()); 02119 02120 // This is where we actually draw the drop-highlighter 02121 style().tqdrawPrimitive(TQStyle::PE_FocusRect, &painter, d->mOldDropHighlighter, colorGroup(), 02122 TQStyle::Style_FocusAtBorder); 02123 } 02124 d->painting = false; 02125 } 02126 02127 void KListView::setFullWidth() 02128 { 02129 setFullWidth(true); 02130 } 02131 02132 void KListView::setFullWidth(bool fullWidth) 02133 { 02134 d->fullWidth = fullWidth; 02135 header()->setStretchEnabled(fullWidth, columns()-1); 02136 } 02137 02138 bool KListView::fullWidth() const 02139 { 02140 return d->fullWidth; 02141 } 02142 02143 int KListView::addColumn(const TQString& label, int width) 02144 { 02145 int result = TQListView::addColumn(label, width); 02146 if (d->fullWidth) { 02147 header()->setStretchEnabled(false, columns()-2); 02148 header()->setStretchEnabled(true, columns()-1); 02149 } 02150 return result; 02151 } 02152 02153 int KListView::addColumn(const TQIconSet& iconset, const TQString& label, int width) 02154 { 02155 int result = TQListView::addColumn(iconset, label, width); 02156 if (d->fullWidth) { 02157 header()->setStretchEnabled(false, columns()-2); 02158 header()->setStretchEnabled(true, columns()-1); 02159 } 02160 return result; 02161 } 02162 02163 void KListView::removeColumn(int index) 02164 { 02165 TQListView::removeColumn(index); 02166 if (d->fullWidth && index == columns()) header()->setStretchEnabled(true, columns()-1); 02167 } 02168 02169 void KListView::viewportResizeEvent(TQResizeEvent* e) 02170 { 02171 TQListView::viewportResizeEvent(e); 02172 } 02173 02174 const TQColor &KListView::alternateBackground() const 02175 { 02176 return d->alternateBackground; 02177 } 02178 02179 void KListView::setAlternateBackground(const TQColor &c) 02180 { 02181 d->alternateBackground = c; 02182 repaint(); 02183 } 02184 02185 void KListView::setShadeSortColumn(bool shadeSortColumn) 02186 { 02187 d->shadeSortColumn = shadeSortColumn; 02188 repaint(); 02189 } 02190 02191 bool KListView::shadeSortColumn() const 02192 { 02193 return d->shadeSortColumn; 02194 } 02195 02196 void KListView::saveLayout(KConfig *config, const TQString &group) const 02197 { 02198 KConfigGroupSaver saver(config, group); 02199 TQStringList widths, order; 02200 02201 const int colCount = columns(); 02202 TQHeader* const thisHeader = header(); 02203 for (int i = 0; i < colCount; ++i) 02204 { 02205 widths << TQString::number(columnWidth(i)); 02206 order << TQString::number(thisHeader->mapToIndex(i)); 02207 } 02208 config->writeEntry("ColumnWidths", widths); 02209 config->writeEntry("ColumnOrder", order); 02210 config->writeEntry("SortColumn", d->sortColumn); 02211 config->writeEntry("SortAscending", d->sortAscending); 02212 } 02213 02214 void KListView::restoreLayout(KConfig *config, const TQString &group) 02215 { 02216 KConfigGroupSaver saver(config, group); 02217 TQStringList cols = config->readListEntry("ColumnWidths"); 02218 int i = 0; 02219 { // scope the iterators 02220 TQStringList::ConstIterator it = cols.constBegin(); 02221 const TQStringList::ConstIterator itEnd = cols.constEnd(); 02222 for (; it != itEnd; ++it) 02223 setColumnWidth(i++, (*it).toInt()); 02224 } 02225 02226 // move sections in the correct sequence: from lowest to highest index position 02227 // otherwise we move a section from an index, which modifies 02228 // all index numbers to the right of the moved one 02229 cols = config->readListEntry("ColumnOrder"); 02230 const int colCount = columns(); 02231 for (i = 0; i < colCount; ++i) // final index positions from lowest to highest 02232 { 02233 TQStringList::ConstIterator it = cols.constBegin(); 02234 const TQStringList::ConstIterator itEnd = cols.constEnd(); 02235 02236 int section = 0; 02237 for (; (it != itEnd) && ((*it).toInt() != i); ++it, ++section) ; 02238 02239 if ( it != itEnd ) { 02240 // found the section to move to position i 02241 header()->moveSection(section, i); 02242 } 02243 } 02244 02245 if (config->hasKey("SortColumn")) 02246 setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true)); 02247 } 02248 02249 void KListView::setSorting(int column, bool ascending) 02250 { 02251 TQListViewItem *selected = 0; 02252 02253 if (selectionMode() == TQListView::Single) { 02254 selected = selectedItem(); 02255 if (selected && !selected->isVisible()) 02256 selected = 0; 02257 } 02258 else if (selectionMode() != TQListView::NoSelection) { 02259 TQListViewItem *item = firstChild(); 02260 while (item && !selected) { 02261 if (item->isSelected() && item->isVisible()) 02262 selected = item; 02263 item = item->itemBelow(); 02264 } 02265 } 02266 02267 d->sortColumn = column; 02268 d->sortAscending = ascending; 02269 TQListView::setSorting(column, ascending); 02270 02271 if (selected) 02272 ensureItemVisible(selected); 02273 02274 TQListViewItem* item = firstChild(); 02275 while ( item ) { 02276 KListViewItem *kItem = dynamic_cast<KListViewItem*>(item); 02277 if (kItem) kItem->m_known = false; 02278 item = item->itemBelow(); 02279 } 02280 } 02281 02282 int KListView::columnSorted(void) const 02283 { 02284 return d->sortColumn; 02285 } 02286 02287 bool KListView::ascendingSort(void) const 02288 { 02289 return d->sortAscending; 02290 } 02291 02292 void KListView::takeItem(TQListViewItem *item) 02293 { 02294 if(item && item == d->editor->currentItem()) 02295 d->editor->terminate(); 02296 02297 TQListView::takeItem(item); 02298 } 02299 02300 void KListView::disableAutoSelection() 02301 { 02302 if ( d->disableAutoSelection ) 02303 return; 02304 02305 d->disableAutoSelection = true; 02306 d->autoSelect.stop(); 02307 d->autoSelectDelay = -1; 02308 } 02309 02310 void KListView::resetAutoSelection() 02311 { 02312 if ( !d->disableAutoSelection ) 02313 return; 02314 02315 d->disableAutoSelection = false; 02316 d->autoSelectDelay = KGlobalSettings::autoSelectDelay(); 02317 } 02318 02319 void KListView::doubleClicked( TQListViewItem *item, const TQPoint &pos, int c ) 02320 { 02321 emit TQListView::doubleClicked( item, pos, c ); 02322 } 02323 02324 KListViewItem::KListViewItem(TQListView *parent) 02325 : TQListViewItem(parent) 02326 { 02327 init(); 02328 } 02329 02330 KListViewItem::KListViewItem(TQListViewItem *parent) 02331 : TQListViewItem(parent) 02332 { 02333 init(); 02334 } 02335 02336 KListViewItem::KListViewItem(TQListView *parent, TQListViewItem *after) 02337 : TQListViewItem(parent, after) 02338 { 02339 init(); 02340 } 02341 02342 KListViewItem::KListViewItem(TQListViewItem *parent, TQListViewItem *after) 02343 : TQListViewItem(parent, after) 02344 { 02345 init(); 02346 } 02347 02348 KListViewItem::KListViewItem(TQListView *parent, 02349 TQString label1, TQString label2, TQString label3, TQString label4, 02350 TQString label5, TQString label6, TQString label7, TQString label8) 02351 : TQListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8) 02352 { 02353 init(); 02354 } 02355 02356 KListViewItem::KListViewItem(TQListViewItem *parent, 02357 TQString label1, TQString label2, TQString label3, TQString label4, 02358 TQString label5, TQString label6, TQString label7, TQString label8) 02359 : TQListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8) 02360 { 02361 init(); 02362 } 02363 02364 KListViewItem::KListViewItem(TQListView *parent, TQListViewItem *after, 02365 TQString label1, TQString label2, TQString label3, TQString label4, 02366 TQString label5, TQString label6, TQString label7, TQString label8) 02367 : TQListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8) 02368 { 02369 init(); 02370 } 02371 02372 KListViewItem::KListViewItem(TQListViewItem *parent, TQListViewItem *after, 02373 TQString label1, TQString label2, TQString label3, TQString label4, 02374 TQString label5, TQString label6, TQString label7, TQString label8) 02375 : TQListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8) 02376 { 02377 init(); 02378 } 02379 02380 KListViewItem::~KListViewItem() 02381 { 02382 if(listView()) 02383 emit static_cast<KListView *>(listView())->itemRemoved(this); 02384 } 02385 02386 void KListViewItem::init() 02387 { 02388 m_odd = m_known = false; 02389 KListView *lv = static_cast<KListView *>(listView()); 02390 setDragEnabled( dragEnabled() || lv->dragEnabled() ); 02391 emit lv->itemAdded(this); 02392 } 02393 02394 void KListViewItem::insertItem(TQListViewItem *item) 02395 { 02396 TQListViewItem::insertItem(item); 02397 if(listView()) 02398 emit static_cast<KListView *>(listView())->itemAdded(item); 02399 } 02400 02401 void KListViewItem::takeItem(TQListViewItem *item) 02402 { 02403 TQListViewItem::takeItem(item); 02404 if(listView()) 02405 emit static_cast<KListView *>(listView())->itemRemoved(item); 02406 } 02407 02408 const TQColor &KListViewItem::backgroundColor() 02409 { 02410 if (isAlternate()) 02411 return static_cast< KListView* >(listView())->alternateBackground(); 02412 return listView()->viewport()->colorGroup().base(); 02413 } 02414 02415 TQColor KListViewItem::backgroundColor(int column) 02416 { 02417 KListView* view = static_cast< KListView* >(listView()); 02418 TQColor color = isAlternate() ? 02419 view->alternateBackground() : 02420 view->viewport()->colorGroup().base(); 02421 02422 // calculate a different color if the current column is sorted (only if more than 1 column) 02423 if ( (view->columns() > 1) && view->shadeSortColumn() && (column == view->columnSorted()) ) 02424 { 02425 if ( color == Qt::black ) 02426 color = TQColor(55, 55, 55); // dark gray 02427 else 02428 { 02429 int h,s,v; 02430 color.hsv(&h, &s, &v); 02431 if ( v > 175 ) 02432 color = color.dark(104); 02433 else 02434 color = color.light(120); 02435 } 02436 } 02437 02438 return color; 02439 } 02440 02441 bool KListViewItem::isAlternate() 02442 { 02443 KListView* const lv = static_cast<KListView *>(listView()); 02444 if (lv && lv->alternateBackground().isValid()) 02445 { 02446 KListViewItem *above; 02447 02448 KListView::KListViewPrivate* const lvD = lv->d; 02449 02450 // Ok, there's some weirdness here that requires explanation as this is a 02451 // speed hack. itemAbove() is a O(n) operation (though this isn't 02452 // immediately clear) so we want to call it as infrequently as possible -- 02453 // especially in the case of painting a cell. 02454 // 02455 // So, in the case that we *are* painting a cell: (1) we're assuming that 02456 // said painting is happening top to bottem -- this assumption is present 02457 // elsewhere in the implementation of this class, (2) itemBelow() is fast -- 02458 // roughly constant time. 02459 // 02460 // Given these assumptions we can do a mixture of caching and telling the 02461 // next item that the when that item is the current item that the now 02462 // current item will be the item above it. 02463 // 02464 // Ideally this will make checking to see if the item above the current item 02465 // is the alternate color a constant time operation rather than 0(n). 02466 02467 if (lvD->painting) { 02468 if (lvD->paintCurrent != this) 02469 { 02470 lvD->paintAbove = lvD->paintBelow == this ? lvD->paintCurrent : itemAbove(); 02471 lvD->paintCurrent = this; 02472 lvD->paintBelow = itemBelow(); 02473 } 02474 02475 above = dynamic_cast<KListViewItem *>(lvD->paintAbove); 02476 } 02477 else 02478 { 02479 above = dynamic_cast<KListViewItem *>(itemAbove()); 02480 } 02481 02482 m_known = above ? above->m_known : true; 02483 if (m_known) 02484 { 02485 m_odd = above ? !above->m_odd : false; 02486 } 02487 else 02488 { 02489 KListViewItem *item; 02490 bool previous = true; 02491 if (parent()) 02492 { 02493 item = dynamic_cast<KListViewItem *>(parent()); 02494 if (item) 02495 previous = item->m_odd; 02496 item = dynamic_cast<KListViewItem *>(parent()->firstChild()); 02497 } 02498 else 02499 { 02500 item = dynamic_cast<KListViewItem *>(lv->firstChild()); 02501 } 02502 02503 while(item) 02504 { 02505 previous = !previous; 02506 item->m_odd = previous; 02507 item->m_known = true; 02508 item = dynamic_cast<KListViewItem *>(item->nextSibling()); 02509 } 02510 } 02511 return m_odd; 02512 } 02513 return false; 02514 } 02515 02516 void KListViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment) 02517 { 02518 TQColorGroup _cg = cg; 02519 TQListView* lv = listView(); 02520 const TQPixmap *pm = lv->viewport()->backgroundPixmap(); 02521 02522 if (pm && !pm->isNull()) 02523 { 02524 _cg.setBrush(TQColorGroup::Base, TQBrush(backgroundColor(column), *pm)); 02525 TQPoint o = p->brushOrigin(); 02526 p->setBrushOrigin( o.x()-lv->contentsX(), o.y()-lv->contentsY() ); 02527 } 02528 else 02529 { 02530 _cg.setColor((lv->viewport()->backgroundMode() == TQt::FixedColor) ? 02531 TQColorGroup::Background : TQColorGroup::Base, 02532 backgroundColor(column)); 02533 } 02534 TQListViewItem::paintCell(p, _cg, column, width, alignment); 02535 } 02536 02544 void KListView::selectAll( bool select ) 02545 { 02546 if ( ((SelectionModeExt)selectionMode() == Multi) || ((SelectionModeExt)selectionMode() == Extended) ) { 02547 bool b = signalsBlocked(); 02548 blockSignals( TRUE ); 02549 bool anything = FALSE; 02550 TQListViewItemIterator it( this ); 02551 while ( it.current() ) { 02552 TQListViewItem *i = it.current(); 02553 if ( select == TRUE ) { 02554 if ( (bool)i->isVisible() == TRUE ) { 02555 i->setSelected( TRUE ); 02556 anything = TRUE; 02557 } 02558 if ( (bool)i->isVisible() == FALSE ) { 02559 i->setSelected( FALSE ); 02560 anything = TRUE; 02561 } 02562 } 02563 else { 02564 if ( (bool)i->isSelected() != select ) { 02565 i->setSelected( select ); 02566 anything = TRUE; 02567 } 02568 } 02569 ++it; 02570 } 02571 blockSignals( b ); 02572 if ( anything ) { 02573 emit selectionChanged(); 02574 // d->useDoubleBuffer = TRUE; 02575 triggerUpdate(); 02576 } 02577 } else if ( currentItem() ) { 02578 TQListViewItem * i = currentItem(); 02579 setSelected( i, select ); 02580 } 02581 } 02582 02583 void KListView::virtual_hook( int, void* ) 02584 { /*BASE::virtual_hook( id, data );*/ } 02585 02586 #include "klistview.moc" 02587 #include "klistviewlineedit.moc" 02588 02589 // vim: noet