• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kdeui
 

kdeui

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

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdeui

Skip menu "kdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdeui by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |