summaryrefslogtreecommitdiffabout
path: root/microkde/kdeui/klistview.cpp
Unidiff
Diffstat (limited to 'microkde/kdeui/klistview.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--microkde/kdeui/klistview.cpp2191
1 files changed, 2191 insertions, 0 deletions
diff --git a/microkde/kdeui/klistview.cpp b/microkde/kdeui/klistview.cpp
new file mode 100644
index 0000000..b53a88a
--- a/dev/null
+++ b/microkde/kdeui/klistview.cpp
@@ -0,0 +1,2191 @@
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Reginald Stadlbauer <reggie@kde.org>
3 Copyright (C) 2000 Charles Samuels <charles@kde.org>
4 Copyright (C) 2000 Peter Putzer
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License version 2 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21#include <qdragobject.h>
22#include <qtimer.h>
23#include <qheader.h>
24#include <qcursor.h>
25#include <qtooltip.h>
26#include <qstyle.h>
27#include <qpainter.h>
28
29#include <kglobalsettings.h>
30#include <kconfig.h>
31#include <kconfigbase.h>
32//US #include <kcursor.h>
33#include <kapplication.h>
34//US #include <kipc.h>
35#include <kdebug.h>
36#ifdef _WIN32_
37#define Q_WS_QWS
38#endif
39#ifndef _WIN32_
40#define private public
41#include <qlistview.h>
42#undef private
43#endif
44#include "klistview.h"
45//US #include "klistviewlineedit.h"
46#ifndef DESKTOP_VERSION
47#include <qpe/qpeapplication.h>
48#endif
49
50// /*US
51class KListView::Tooltip : public QToolTip
52{
53public:
54 Tooltip (KListView* parent, QToolTipGroup* group = 0L);
55 virtual ~Tooltip () {}
56
57protected:
58 // */
59 /**
60 * Reimplemented from QToolTip for internal reasons.
61 */
62 // /*US
63 virtual void maybeTip (const QPoint&);
64
65private:
66 KListView* mParent;
67};
68
69KListView::Tooltip::Tooltip (KListView* parent, QToolTipGroup* group)
70 : QToolTip (parent, group),
71 mParent (parent)
72{
73}
74
75void KListView::Tooltip::maybeTip (const QPoint&)
76{
77 // FIXME
78}
79// */
80
81class KListView::KListViewPrivate
82{
83public:
84 KListViewPrivate (KListView* listview)
85 : pCurrentItem (0L),
86 autoSelectDelay(1),
87//US dragDelay (KGlobalSettings::dndEventDelay()),
88
89 dragDelay (10),
90//US editor (new KListViewLineEdit (listview)),
91 cursorInExecuteArea(false),
92 bUseSingle(false),
93 bChangeCursorOverItem(false),
94 itemsMovable (true),
95 selectedBySimpleMove(false),
96 selectedUsingMouse(false),
97 showContextMenusOnPress(true),
98 itemsRenameable (false),
99 validDrag (false),
100 dragEnabled (false),
101 autoOpen (true),
102 dropVisualizer (true),
103 dropHighlighter (false),
104 createChildren (true),
105 pressedOnSelected (false),
106 wasShiftEvent (false),
107 fullWidth (false),
108 sortAscending(true),
109 tabRename(true),
110 sortColumn(0),
111 selectionDirection(0),
112 tooltipColumn (0),
113 selectionMode (Single),
114//US contextMenuKey (KGlobalSettings::contextMenuKey()),
115//US showContextMenusOnPress (KGlobalSettings::showContextMenusOnPress()),
116 mDropVisualizerWidth (4)
117 {
118 renameable += 0;
119//US connect(editor, SIGNAL(done(QListViewItem*,int)), listview, SLOT(doneEditing(QListViewItem*,int)));
120 }
121
122 ~KListViewPrivate ()
123 {
124//US delete editor;
125 }
126
127 QListViewItem* pCurrentItem;
128
129 QTimer autoSelect;
130 int autoSelectDelay;
131
132 QTimer dragExpand;
133 QListViewItem* dragOverItem;
134 QPoint dragOverPoint;
135
136 QPoint startDragPos;
137 int dragDelay;
138
139//US KListViewLineEdit *editor;
140 QValueList<int> renameable;
141
142 bool cursorInExecuteArea:1;
143 bool bUseSingle:1;
144 bool bChangeCursorOverItem:1;
145 bool itemsMovable:1;
146 bool selectedBySimpleMove : 1;
147 bool selectedUsingMouse:1;
148 bool itemsRenameable:1;
149 bool validDrag:1;
150 bool dragEnabled:1;
151 bool autoOpen:1;
152 bool dropVisualizer:1;
153 bool dropHighlighter:1;
154 bool createChildren:1;
155 bool pressedOnSelected:1;
156 bool wasShiftEvent:1;
157 bool fullWidth:1;
158 bool sortAscending:1;
159 bool tabRename:1;
160
161 int sortColumn;
162
163 //+1 means downwards (y increases, -1 means upwards, 0 means not selected), aleXXX
164 int selectionDirection;
165 int tooltipColumn;
166
167 SelectionModeExt selectionMode;
168 int contextMenuKey;
169 bool showContextMenusOnPress;
170
171 QRect mOldDropVisualizer;
172 int mDropVisualizerWidth;
173 QRect mOldDropHighlighter;
174 QListViewItem *afterItemDrop;
175 QListViewItem *parentItemDrop;
176
177 QColor alternateBackground;
178};
179
180/*US
181KListViewLineEdit::KListViewLineEdit(KListView *parent)
182 : KLineEdit(parent->viewport()), item(0), col(0), p(parent)
183{
184 setFrame( false );
185 hide();
186 connect( parent, SIGNAL( selectionChanged() ), SLOT( slotSelectionChanged() ));
187}
188
189KListViewLineEdit::~KListViewLineEdit()
190{
191}
192
193void KListViewLineEdit::load(QListViewItem *i, int c)
194{
195 item=i;
196 col=c;
197
198 QRect rect(p->itemRect(i));
199 setText(item->text(c));
200
201 int fieldX = rect.x() - 1;
202 int fieldW = p->columnWidth(col) + 2;
203
204 int pos = p->header()->mapToIndex(col);
205 for ( int index = 0; index < pos; index++ )
206 fieldX += p->columnWidth( p->header()->mapToSection( index ));
207
208 if ( col == 0 ) {
209 int d = i->depth() + (p->rootIsDecorated() ? 1 : 0);
210 d *= p->treeStepSize();
211 fieldX += d;
212 fieldW -= d;
213 }
214
215 if ( i->pixmap( col ) ) {// add width of pixmap
216 int d = i->pixmap( col )->width();
217 fieldX += d;
218 fieldW -= d;
219 }
220
221 setGeometry(fieldX, rect.y() - 1, fieldW, rect.height() + 2);
222 show();
223 setFocus();
224}
225*/
226 /*Helper functions to for
227 *tabOrderedRename functionality.
228 */
229
230static int nextCol (KListView *pl, QListViewItem *pi, int start, int dir)
231{
232 if (pi)
233 {
234 //Find the next renameable column in the current row
235 for (; ((dir == +1) ? (start < pl->columns()) : (start >= 0)); start += dir)
236 if (pl->isRenameable(start))
237 return start;
238 }
239
240 return -1;
241}
242
243static QListViewItem *prevItem (QListViewItem *pi)
244{
245 QListViewItem *pa = pi->itemAbove();
246
247 /*Does what the QListViewItem::previousSibling()
248 *of my dreams would do.
249 */
250 if (pa && pa->parent() == pi->parent())
251 return pa;
252
253 return NULL;
254}
255
256static QListViewItem *lastQChild (QListViewItem *pi)
257{
258 if (pi)
259 {
260 /*Since there's no QListViewItem::lastChild().
261 *This finds the last sibling for the given
262 *item.
263 */
264 for (QListViewItem *pt = pi->nextSibling(); pt; pt = pt->nextSibling())
265 pi = pt;
266 }
267
268 return pi;
269}
270/*US
271void KListViewLineEdit::selectNextCell (QListViewItem *pitem, int column, bool forward)
272{
273 const int ncols = p->columns();
274 const int dir = forward ? +1 : -1;
275 const int restart = forward ? 0 : (ncols - 1);
276 QListViewItem *top = (pitem && pitem->parent())
277 ? pitem->parent()->firstChild()
278 : p->firstChild();
279 QListViewItem *pi = pitem;
280
281 terminate(); //Save current changes
282
283 do
284 {
285*/
286 /*Check the rest of the current row for an editable column,
287 *if that fails, check the entire next/previous row. The
288 *last case goes back to the first item in the current branch
289 *or the last item in the current branch depending on the
290 *direction.
291 */
292/*US
293 if ((column = nextCol(p, pi, column + dir, dir)) != -1 ||
294 (column = nextCol(p, (pi = (forward ? pi->nextSibling() : prevItem(pi))), restart, dir)) != -1 ||
295 (column = nextCol(p, (pi = (forward ? top : lastQChild(pitem))), restart, dir)) != -1)
296 {
297 if (pi)
298 {
299 p->setCurrentItem(pi); //Calls terminate
300 p->rename(pi, column);
301*/
302 /*Some listviews may override rename() to
303 *prevent certain items from being renamed,
304 *if this is done, [m_]item will be NULL
305 *after the rename() call... try again.
306 */
307/*US
308 if (!item)
309 continue;
310
311 break;
312 }
313 }
314 }
315 while (pi && !item);
316}
317*/
318
319/*US
320#ifdef KeyPress
321#undef KeyPress
322#endif
323
324bool KListViewLineEdit::event (QEvent *pe)
325{
326 if (pe->type() == QEvent::KeyPress)
327 {
328 QKeyEvent *k = (QKeyEvent *) pe;
329
330 if ((k->key() == Qt::Key_Backtab || k->key() == Qt::Key_Tab) &&
331 p->tabOrderedRenaming() && p->itemsRenameable() &&
332 !(k->state() & ControlButton || k->state() & AltButton))
333 {
334 selectNextCell(item, col,
335 (k->key() == Key_Tab && !(k->state() & ShiftButton)));
336 return true;
337 }
338 }
339
340 return KLineEdit::event(pe);
341}
342
343void KListViewLineEdit::keyPressEvent(QKeyEvent *e)
344{
345 if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )
346 terminate(true);
347 else if(e->key() == Qt::Key_Escape)
348 terminate(false);
349 else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Up)
350 {
351 terminate(true);
352 KLineEdit::keyPressEvent(e);
353 }
354 else
355 KLineEdit::keyPressEvent(e);
356}
357
358void KListViewLineEdit::terminate()
359{
360 terminate(true);
361}
362
363void KListViewLineEdit::terminate(bool commit)
364{
365 if ( item )
366 {
367 //kdDebug() << "KListViewLineEdit::terminate " << commit << endl;
368 if (commit)
369 item->setText(col, text());
370 int c=col;
371 QListViewItem *i=item;
372 col=0;
373 item=0;
374 hide(); // will call focusOutEvent, that's why we set item=0 before
375 emit done(i,c);
376 }
377}
378
379void KListViewLineEdit::focusOutEvent(QFocusEvent *ev)
380{
381 QFocusEvent * focusEv = static_cast<QFocusEvent*>(ev);
382 // Don't let a RMB close the editor
383 if (focusEv->reason() != QFocusEvent::Popup && focusEv->reason() != QFocusEvent::ActiveWindow)
384 terminate(true);
385}
386
387void KListViewLineEdit::paintEvent( QPaintEvent *e )
388{
389 KLineEdit::paintEvent( e );
390
391 if ( !frame() ) {
392 QPainter p( this );
393 p.setClipRegion( e->region() );
394 p.drawRect( rect() );
395 }
396}
397
398// selection changed -> terminate. As our "item" can be already deleted,
399// we can't call terminate(false), because that would emit done() with
400// a dangling pointer to "item".
401void KListViewLineEdit::slotSelectionChanged()
402{
403 item = 0;
404 col = 0;
405 hide();
406}
407*/
408
409KListView::KListView( QWidget *parent, const char *name )
410 : QListView( parent, name ),
411 d (new KListViewPrivate (this))
412{
413#ifndef DESKTOP_VERSION
414 QPEApplication::setStylusOperation( viewport(), QPEApplication::RightOnHold );
415#endif
416//US setDragAutoScroll(true);
417
418 connect( this, SIGNAL( onViewport() ),
419 this, SLOT( slotOnViewport() ) );
420 connect( this, SIGNAL( onItem( QListViewItem * ) ),
421 this, SLOT( slotOnItem( QListViewItem * ) ) );
422
423 connect (this, SIGNAL(contentsMoving(int,int)),
424 this, SLOT(cleanDropVisualizer()));
425 connect (this, SIGNAL(contentsMoving(int,int)),
426 this, SLOT(cleanItemHighlighter()));
427
428/*US
429 slotSettingsChanged(KApplication::SETTINGS_MOUSE);
430
431 if (kapp)
432 {
433 connect( kapp, SIGNAL( settingsChanged(int) ), SLOT( slotSettingsChanged(int) ) );
434 kapp->addKipcEventMask( KIPC::SettingsChanged );
435 }
436*/
437 slotSettingsChanged(1); //US do this to initialize the connections
438
439
440 connect(&d->autoSelect, SIGNAL( timeout() ),
441 this, SLOT( slotAutoSelect() ) );
442 connect(&d->dragExpand, SIGNAL( timeout() ),
443 this, SLOT( slotDragExpand() ) );
444
445 // context menu handling
446 if (d->showContextMenusOnPress)
447 {
448 connect (this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)),
449 this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
450 }
451 else
452 {
453 connect (this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)),
454 this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
455 }
456
457 connect (this, SIGNAL (menuShortCutPressed (KListView*, QListViewItem*)),
458 this, SLOT (emitContextMenu (KListView*, QListViewItem*)));
459
460
461 //qDebug("KListView::KListView make alternate color configurable");
462//US d->alternateBackground = KGlobalSettings::alternateBackgroundColor();
463 d->alternateBackground = QColor(240, 240, 240);
464}
465
466
467
468KListView::~KListView()
469{
470 delete d;
471}
472
473bool KListView::isExecuteArea( const QPoint& point )
474{
475 if ( itemAt( point ) )
476 return isExecuteArea( point.x() );
477
478 return false;
479}
480
481bool KListView::isExecuteArea( int x )
482{
483 if( allColumnsShowFocus() )
484 return true;
485 else {
486 int offset = 0;
487 int width = columnWidth( 0 );
488 int pos = header()->mapToIndex( 0 );
489
490 for ( int index = 0; index < pos; index++ )
491 offset += columnWidth( header()->mapToSection( index ) );
492
493 x += contentsX(); // in case of a horizontal scrollbar
494 return ( x > offset && x < ( offset + width ) );
495 }
496}
497
498void KListView::slotOnItem( QListViewItem *item )
499{
500 QPoint vp = viewport()->mapFromGlobal( QCursor::pos() );
501 if ( item && isExecuteArea( vp.x() ) && (d->autoSelectDelay > -1) && d->bUseSingle ) {
502 d->autoSelect.start( d->autoSelectDelay, true );
503 d->pCurrentItem = item;
504 }
505}
506
507void KListView::slotOnViewport()
508{
509 if ( d->bChangeCursorOverItem )
510 viewport()->unsetCursor();
511
512 d->autoSelect.stop();
513 d->pCurrentItem = 0L;
514}
515
516void KListView::slotSettingsChanged(int category)
517{
518qDebug("KListView::slotSettingsChanged has to be verified");
519/*US
520
521 switch (category)
522 {
523 case KApplication::SETTINGS_MOUSE:
524 d->dragDelay = KGlobalSettings::dndEventDelay();
525 d->bUseSingle = KGlobalSettings::singleClick();
526
527 disconnect(this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
528 this, SLOT (slotMouseButtonClicked (int, QListViewItem*, const QPoint &, int)));
529
530 if( d->bUseSingle )
531 connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
532 this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int)));
533
534 d->bChangeCursorOverItem = KGlobalSettings::changeCursorOverIcon();
535 d->autoSelectDelay = KGlobalSettings::autoSelectDelay();
536
537 if( !d->bUseSingle || !d->bChangeCursorOverItem )
538 viewport()->unsetCursor();
539
540 break;
541
542 case KApplication::SETTINGS_POPUPMENU:
543 d->contextMenuKey = KGlobalSettings::contextMenuKey ();
544 d->showContextMenusOnPress = KGlobalSettings::showContextMenusOnPress ();
545
546 if (d->showContextMenusOnPress)
547 {
548 disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
549
550 connect(this, SIGNAL (rightButtonPressed (QListViewItem*, const QPoint&, int)),
551 this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
552 }
553 else
554 {
555 disconnect (0L, 0L, this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
556
557 connect(this, SIGNAL (rightButtonClicked (QListViewItem*, const QPoint&, int)),
558 this, SLOT (emitContextMenu (QListViewItem*, const QPoint&, int)));
559 }
560 break;
561
562 default:
563 break;
564 }
565*/
566
567 if( d->bUseSingle )
568 connect (this, SIGNAL (mouseButtonClicked (int, QListViewItem*, const QPoint &, int)),
569 this, SLOT (slotMouseButtonClicked( int, QListViewItem*, const QPoint &, int)));
570
571}
572
573void KListView::slotAutoSelect()
574{
575 // check that the item still exists
576 if( itemIndex( d->pCurrentItem ) == -1 )
577 return;
578
579 if (!isActiveWindow())
580 {
581 d->autoSelect.stop();
582 return;
583 }
584
585 //Give this widget the keyboard focus.
586 if( !hasFocus() )
587 setFocus();
588
589 QListViewItem* previousItem = currentItem();
590 setCurrentItem( d->pCurrentItem );
591
592#if 0
593#ifndef Q_WS_QWS
594 // FIXME(E): Implement for Qt Embedded
595 if( d->pCurrentItem ) {
596 //Shift pressed?
597 if( (keybstate & ShiftMask) ) {
598 bool block = signalsBlocked();
599 blockSignals( true );
600
601 //No Ctrl? Then clear before!
602 if( !(keybstate & ControlMask) )
603 clearSelection();
604
605 bool select = !d->pCurrentItem->isSelected();
606 bool update = viewport()->isUpdatesEnabled();
607 viewport()->setUpdatesEnabled( false );
608
609 bool down = previousItem->itemPos() < d->pCurrentItem->itemPos();
610 QListViewItemIterator lit( down ? previousItem : d->pCurrentItem );
611 for ( ; lit.current(); ++lit ) {
612 if ( down && lit.current() == d->pCurrentItem ) {
613 d->pCurrentItem->setSelected( select );
614 break;
615 }
616 if ( !down && lit.current() == previousItem ) {
617 previousItem->setSelected( select );
618 break;
619 }
620 lit.current()->setSelected( select );
621 }
622
623 blockSignals( block );
624 viewport()->setUpdatesEnabled( update );
625 triggerUpdate();
626
627 emit selectionChanged();
628
629 if( selectionMode() == QListView::Single )
630 emit selectionChanged( d->pCurrentItem );
631 }
632 else if( (keybstate & ControlMask) )
633 setSelected( d->pCurrentItem, !d->pCurrentItem->isSelected() );
634 else {
635 bool block = signalsBlocked();
636 blockSignals( true );
637
638 if( !d->pCurrentItem->isSelected() )
639 clearSelection();
640
641 blockSignals( block );
642
643 setSelected( d->pCurrentItem, true );
644 }
645 }
646 else
647 kdDebug() << "KListView::slotAutoSelect: Thats not supposed to happen!!!!" << endl;
648#endif
649#endif
650}
651
652void KListView::slotHeaderChanged()
653{
654 if (d->fullWidth && columns())
655 {
656 int w = 0;
657 for (int i = 0; i < columns() - 1; ++i) w += columnWidth(i);
658 setColumnWidth( columns() - 1, viewport()->width() - w - 1 );
659 }
660}
661
662void KListView::emitExecute( QListViewItem *item, const QPoint &pos, int c )
663{
664 if( isExecuteArea( viewport()->mapFromGlobal(pos) ) ) {
665
666 // Double click mode ?
667 if ( !d->bUseSingle )
668 {
669 emit executed( item );
670 emit executed( item, pos, c );
671 }
672 else
673 {
674#if 0
675#ifndef Q_WS_QWS
676 // FIXME(E): Implement for Qt Embedded
677 Window root;
678 Window child;
679 int root_x, root_y, win_x, win_y;
680 uint keybstate;
681 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
682 &root_x, &root_y, &win_x, &win_y, &keybstate );
683
684 d->autoSelect.stop();
685
686 //Dont emit executed if in SC mode and Shift or Ctrl are pressed
687 if( !( ((keybstate & ShiftMask) || (keybstate & ControlMask)) ) ) {
688 emit executed( item );
689 emit executed( item, pos, c );
690 }
691#endif
692#endif
693 }
694 }
695}
696
697void KListView::focusInEvent( QFocusEvent *fe )
698{
699 // kdDebug()<<"KListView::focusInEvent()"<<endl;
700 QListView::focusInEvent( fe );
701 if ((d->selectedBySimpleMove)
702 && (d->selectionMode == FileManager)
703 && (fe->reason()!=QFocusEvent::Popup)
704 && (fe->reason()!=QFocusEvent::ActiveWindow)
705 && (currentItem()!=0))
706 {
707 currentItem()->setSelected(true);
708 currentItem()->repaint();
709 emit selectionChanged();
710 };
711}
712
713void KListView::focusOutEvent( QFocusEvent *fe )
714{
715 cleanDropVisualizer();
716 cleanItemHighlighter();
717
718 d->autoSelect.stop();
719
720 if ((d->selectedBySimpleMove)
721 && (d->selectionMode == FileManager)
722 && (fe->reason()!=QFocusEvent::Popup)
723 && (fe->reason()!=QFocusEvent::ActiveWindow)
724 && (currentItem()!=0)
725/*US && (!d->editor->isVisible()) */
726 )
727 {
728 currentItem()->setSelected(false);
729 currentItem()->repaint();
730 emit selectionChanged();
731 };
732
733 QListView::focusOutEvent( fe );
734}
735
736void KListView::leaveEvent( QEvent *e )
737{
738 d->autoSelect.stop();
739
740 QListView::leaveEvent( e );
741}
742
743bool KListView::event( QEvent *e )
744{
745 if (e->type() == QEvent::ApplicationPaletteChange) {
746qDebug("KListView::event make alternate color configurable");
747//US d->alternateBackground=KGlobalSettings::alternateBackgroundColor();
748 d->alternateBackground = QColor(240, 240, 240);
749 }
750
751 return QListView::event(e);
752}
753
754void KListView::contentsMousePressEvent( QMouseEvent *e )
755{
756 if( (selectionModeExt() == Extended) && (e->state() & ShiftButton) && !(e->state() & ControlButton) )
757 {
758 bool block = signalsBlocked();
759 blockSignals( true );
760
761 clearSelection();
762
763 blockSignals( block );
764 }
765 else if ((selectionModeExt()==FileManager) && (d->selectedBySimpleMove))
766 {
767 d->selectedBySimpleMove=false;
768 d->selectedUsingMouse=true;
769 if (currentItem()!=0)
770 {
771 currentItem()->setSelected(false);
772 currentItem()->repaint();
773// emit selectionChanged();
774 };
775 };
776
777 QPoint p( contentsToViewport( e->pos() ) );
778 QListViewItem *at = itemAt (p);
779
780 // true if the root decoration of the item "at" was clicked (i.e. the +/- sign)
781 bool rootDecoClicked = at
782 && ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
783 treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() )
784 && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
785
786 if (e->button() == LeftButton && !rootDecoClicked)
787 {
788 //Start a drag
789 d->startDragPos = e->pos();
790
791 if (at)
792 {
793 d->validDrag = true;
794 d->pressedOnSelected = at->isSelected();
795 }
796 }
797
798 QListView::contentsMousePressEvent( e );
799}
800
801void KListView::contentsMouseMoveEvent( QMouseEvent *e )
802{
803 if (!dragEnabled() || d->startDragPos.isNull() || !d->validDrag) {
804 QListView::contentsMouseMoveEvent (e);
805 return;
806 }
807
808 QPoint vp = contentsToViewport(e->pos());
809 QListViewItem *item = itemAt( vp );
810
811 //do we process cursor changes at all?
812 if ( item && d->bChangeCursorOverItem && d->bUseSingle )
813 {
814 //Cursor moved on a new item or in/out the execute area
815 if( (item != d->pCurrentItem) ||
816 (isExecuteArea(vp) != d->cursorInExecuteArea) )
817 {
818 d->cursorInExecuteArea = isExecuteArea(vp);
819qDebug("KListView::contentsMouseMoveEvent drag&drop not supported yet");
820/*US
821 if( d->cursorInExecuteArea ) //cursor moved in execute area
822 viewport()->setCursor( KCursor::handCursor() );
823 else //cursor moved out of execute area
824 viewport()->unsetCursor();
825*/
826 }
827 }
828
829 bool dragOn = dragEnabled();
830 QPoint newPos = e->pos();
831 if (dragOn && d->validDrag &&
832 (newPos.x() > d->startDragPos.x()+d->dragDelay ||
833 newPos.x() < d->startDragPos.x()-d->dragDelay ||
834 newPos.y() > d->startDragPos.y()+d->dragDelay ||
835 newPos.y() < d->startDragPos.y()-d->dragDelay))
836 //(d->startDragPos - e->pos()).manhattanLength() > QApplication::startDragDistance())
837 {
838 QListView::contentsMouseReleaseEvent( 0 );
839 startDrag();
840 d->startDragPos = QPoint();
841 d->validDrag = false;
842 }
843}
844
845void KListView::contentsMouseReleaseEvent( QMouseEvent *e )
846{
847 if (e->button() == LeftButton)
848 {
849 // If the row was already selected, maybe we want to start an in-place editing
850 if ( d->pressedOnSelected && itemsRenameable() )
851 {
852 QPoint p( contentsToViewport( e->pos() ) );
853 QListViewItem *at = itemAt (p);
854 if ( at )
855 {
856 // true if the root decoration of the item "at" was clicked (i.e. the +/- sign)
857 bool rootDecoClicked =
858 ( p.x() <= header()->cellPos( header()->mapToActual( 0 ) ) +
859 treeStepSize() * ( at->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() )
860 && ( p.x() >= header()->cellPos( header()->mapToActual( 0 ) ) );
861
862 if (!rootDecoClicked)
863 {
864 int col = header()->mapToLogical( header()->cellAt( p.x() ) );
865 if ( d->renameable.contains(col) )
866 rename(at, col);
867 }
868 }
869 }
870
871 d->pressedOnSelected = false;
872 d->validDrag = false;
873 d->startDragPos = QPoint();
874 }
875 QListView::contentsMouseReleaseEvent( e );
876}
877
878void KListView::contentsMouseDoubleClickEvent ( QMouseEvent *e )
879{
880 // We don't want to call the parent method because it does setOpen,
881 // whereas we don't do it in single click mode... (David)
882 //QListView::contentsMouseDoubleClickEvent( e );
883
884 QPoint vp = contentsToViewport(e->pos());
885 QListViewItem *item = itemAt( vp );
886 emit QListView::doubleClicked( item ); // we do it now
887
888 int col = item ? header()->mapToLogical( header()->cellAt( vp.x() ) ) : -1;
889
890 if( item ) {
891 emit doubleClicked( item, e->globalPos(), col );
892
893 if( (e->button() == LeftButton) && !d->bUseSingle )
894 emitExecute( item, e->globalPos(), col );
895 }
896}
897
898void KListView::slotMouseButtonClicked( int btn, QListViewItem *item, const QPoint &pos, int c )
899{
900 if( (btn == LeftButton) && item )
901 emitExecute(item, pos, c);
902}
903
904void KListView::contentsDropEvent(QDropEvent* e)
905{
906qDebug("KListView::contentsDropEvent drag&drop not supported yet");
907/*US
908 cleanDropVisualizer();
909 cleanItemHighlighter();
910 d->dragExpand.stop();
911
912 if (acceptDrag (e))
913 {
914 e->acceptAction();
915 QListViewItem *afterme;
916 QListViewItem *parent;
917 findDrop(e->pos(), parent, afterme);
918
919 if (e->source() == viewport() && itemsMovable())
920 movableDropEvent(parent, afterme);
921 else
922 {
923
924 emit dropped(e, afterme);
925 emit dropped(this, e, afterme);
926 emit dropped(e, parent, afterme);
927 emit dropped(this, e, parent, afterme);
928
929 }
930 }
931*/
932
933}
934
935void KListView::movableDropEvent (QListViewItem* parent, QListViewItem* afterme)
936{
937 QPtrList<QListViewItem> items, afterFirsts, afterNows;
938 QListViewItem *current=currentItem();
939 bool hasMoved=false;
940 for (QListViewItem *i = firstChild(), *iNext=0; i != 0; i = iNext)
941 {
942 iNext=i->itemBelow();
943 if (!i->isSelected())
944 continue;
945
946 // don't drop an item after itself, or else
947 // it moves to the top of the list
948 if (i==afterme)
949 continue;
950
951 i->setSelected(false);
952
953 QListViewItem *afterFirst = i->itemAbove();
954
955 if (!hasMoved)
956 {
957 emit aboutToMove();
958 hasMoved=true;
959 }
960
961 moveItem(i, parent, afterme);
962
963 // ###### This should include the new parent !!! -> KDE 3.0
964 // If you need this right now, have a look at keditbookmarks.
965 emit moved(i, afterFirst, afterme);
966
967 items.append (i);
968 afterFirsts.append (afterFirst);
969 afterNows.append (afterme);
970
971 afterme = i;
972 }
973 clearSelection();
974 for (QListViewItem *i=items.first(); i != 0; i=items.next() )
975 i->setSelected(true);
976 if (current)
977 setCurrentItem(current);
978
979 emit moved(items,afterFirsts,afterNows);
980
981 if (firstChild())
982 emit moved();
983}
984
985void KListView::contentsDragMoveEvent(QDragMoveEvent *event)
986{
987qDebug("KListView::contentsDropEvent drag&drop not supported yet");
988/*US
989 if (acceptDrag(event))
990 {
991 event->acceptAction();
992 //Clean up the view
993
994 findDrop(event->pos(), d->parentItemDrop, d->afterItemDrop);
995 QPoint vp = contentsToViewport( event->pos() );
996 QListViewItem *item = isExecuteArea( vp ) ? itemAt( vp ) : 0L;
997
998 if ( item != d->dragOverItem )
999 {
1000 d->dragExpand.stop();
1001 d->dragOverItem = item;
1002 d->dragOverPoint = vp;
1003 if ( d->dragOverItem && d->dragOverItem->isExpandable() && !d->dragOverItem->isOpen() )
1004 d->dragExpand.start( QApplication::startDragTime(), true );
1005 }
1006 if (dropVisualizer())
1007 {
1008 QRect tmpRect = drawDropVisualizer(0, d->parentItemDrop, d->afterItemDrop);
1009 if (tmpRect != d->mOldDropVisualizer)
1010 {
1011 cleanDropVisualizer();
1012 d->mOldDropVisualizer=tmpRect;
1013 viewport()->repaint(tmpRect);
1014 }
1015 }
1016 if (dropHighlighter())
1017 {
1018 QRect tmpRect = drawItemHighlighter(0, d->afterItemDrop);
1019 if (tmpRect != d->mOldDropHighlighter)
1020 {
1021 cleanItemHighlighter();
1022 d->mOldDropHighlighter=tmpRect;
1023 viewport()->repaint(tmpRect);
1024 }
1025 }
1026 }
1027 else
1028 event->ignore();
1029*/
1030}
1031
1032void KListView::slotDragExpand()
1033{
1034 if ( itemAt( d->dragOverPoint ) == d->dragOverItem )
1035 d->dragOverItem->setOpen( true );
1036}
1037
1038void KListView::contentsDragLeaveEvent (QDragLeaveEvent*)
1039{
1040 d->dragExpand.stop();
1041 cleanDropVisualizer();
1042 cleanItemHighlighter();
1043}
1044
1045void KListView::cleanDropVisualizer()
1046{
1047 if (d->mOldDropVisualizer.isValid())
1048 {
1049 QRect rect=d->mOldDropVisualizer;
1050 d->mOldDropVisualizer = QRect();
1051 viewport()->repaint(rect, true);
1052 }
1053}
1054
1055int KListView::depthToPixels( int depth )
1056{
1057 return treeStepSize() * ( depth + (rootIsDecorated() ? 1 : 0) ) + itemMargin();
1058}
1059
1060void KListView::findDrop(const QPoint &pos, QListViewItem *&parent, QListViewItem *&after)
1061{
1062 QPoint p (contentsToViewport(pos));
1063
1064 // Get the position to put it in
1065 QListViewItem *atpos = itemAt(p);
1066
1067 QListViewItem *above;
1068 if (!atpos) // put it at the end
1069 above = lastItem();
1070 else
1071 {
1072 // Get the closest item before us ('atpos' or the one above, if any)
1073 if (p.y() - itemRect(atpos).topLeft().y() < (atpos->height()/2))
1074 above = atpos->itemAbove();
1075 else
1076 above = atpos;
1077 }
1078
1079 if (above)
1080 {
1081 // Now, we know we want to go after "above". But as a child or as a sibling ?
1082 // We have to ask the "above" item if it accepts children.
1083 if (above->isExpandable())
1084 {
1085 // The mouse is sufficiently on the right ? - doesn't matter if 'above' has visible children
1086 if (p.x() >= depthToPixels( above->depth() + 1 ) ||
1087 (above->isOpen() && above->childCount() > 0) )
1088 {
1089 parent = above;
1090 after = 0L;
1091 return;
1092 }
1093 }
1094
1095 // Ok, there's one more level of complexity. We may want to become a new
1096 // sibling, but of an upper-level group, rather than the "above" item
1097 QListViewItem * betterAbove = above->parent();
1098 QListViewItem * last = above;
1099 while ( betterAbove )
1100 {
1101 // We are allowed to become a sibling of "betterAbove" only if we are
1102 // after its last child
1103 if ( last->nextSibling() == 0 )
1104 {
1105 if (p.x() < depthToPixels ( betterAbove->depth() + 1 ))
1106 above = betterAbove; // store this one, but don't stop yet, there may be a better one
1107 else
1108 break; // not enough on the left, so stop
1109 last = betterAbove;
1110 betterAbove = betterAbove->parent(); // up one level
1111 } else
1112 break; // we're among the child of betterAbove, not after the last one
1113 }
1114 }
1115 // set as sibling
1116 after = above;
1117 parent = after ? after->parent() : 0L ;
1118}
1119
1120QListViewItem* KListView::lastChild () const
1121{
1122 QListViewItem* lastchild = firstChild();
1123
1124 if (lastchild)
1125 for (; lastchild->nextSibling(); lastchild = lastchild->nextSibling());
1126
1127 return lastchild;
1128}
1129
1130QListViewItem *KListView::lastItem() const
1131{
1132 QListViewItem* last = lastChild();
1133
1134 for (QListViewItemIterator it (last); it.current(); ++it)
1135 last = it.current();
1136
1137 return last;
1138}
1139
1140KLineEdit *KListView::renameLineEdit() const
1141{
1142//US return d->editor;
1143qDebug("KListView::renameLineEdit returns 0. Might crash");
1144return 0;
1145}
1146
1147void KListView::startDrag()
1148{
1149qDebug("KListView::startDrag drag&drop not supported yet.");
1150/*US
1151 QDragObject *drag = dragObject();
1152
1153 if (!drag)
1154 return;
1155
1156 if (drag->drag() && drag->target() != viewport())
1157 emit moved();
1158*/
1159}
1160
1161QDragObject *KListView::dragObject()
1162{
1163 if (!currentItem())
1164 return 0;
1165
1166 return new QStoredDrag("application/x-qlistviewitem", viewport());
1167}
1168
1169void KListView::setItemsMovable(bool b)
1170{
1171 d->itemsMovable=b;
1172}
1173
1174bool KListView::itemsMovable() const
1175{
1176 return d->itemsMovable;
1177}
1178
1179void KListView::setItemsRenameable(bool b)
1180{
1181 d->itemsRenameable=b;
1182}
1183
1184bool KListView::itemsRenameable() const
1185{
1186 return d->itemsRenameable;
1187}
1188
1189
1190void KListView::setDragEnabled(bool b)
1191{
1192 d->dragEnabled=b;
1193}
1194
1195bool KListView::dragEnabled() const
1196{
1197 return d->dragEnabled;
1198}
1199
1200void KListView::setAutoOpen(bool b)
1201{
1202 d->autoOpen=b;
1203}
1204
1205bool KListView::autoOpen() const
1206{
1207 return d->autoOpen;
1208}
1209
1210bool KListView::dropVisualizer() const
1211{
1212 return d->dropVisualizer;
1213}
1214
1215void KListView::setDropVisualizer(bool b)
1216{
1217 d->dropVisualizer=b;
1218}
1219
1220QPtrList<QListViewItem> KListView::selectedItems() const
1221{
1222 QPtrList<QListViewItem> list;
1223 for (QListViewItem *i=firstChild(); i!=0; i=i->itemBelow())
1224 if (i->isSelected()) list.append(i);
1225 return list;
1226}
1227
1228
1229void KListView::moveItem(QListViewItem *item, QListViewItem *parent, QListViewItem *after)
1230{
1231 // sanity check - don't move a item into it's own child structure
1232 QListViewItem *i = parent;
1233 while(i)
1234 {
1235 if(i == item)
1236 return;
1237 i = i->parent();
1238 }
1239
1240 // Basically reimplementing the QListViewItem(QListViewItem*, QListViewItem*) constructor
1241 // in here, without ever deleting the item.
1242 if (item->parent())
1243 item->parent()->takeItem(item);
1244 else
1245 takeItem(item);
1246
1247 if (parent)
1248 parent->insertItem(item);
1249 else
1250 insertItem(item);
1251
1252 if (after)
1253 ;//item->moveToJustAfter(after);
1254}
1255
1256void KListView::contentsDragEnterEvent(QDragEnterEvent *event)
1257{
1258qDebug("KListView::contentsDragEnterEvent drag&drop not supported yet.");
1259/*US
1260 if (acceptDrag (event))
1261 event->accept();
1262*/
1263}
1264
1265void KListView::setDropVisualizerWidth (int w)
1266{
1267 d->mDropVisualizerWidth = w > 0 ? w : 1;
1268}
1269
1270QRect KListView::drawDropVisualizer(QPainter *p, QListViewItem *parent,
1271 QListViewItem *after)
1272{
1273 QRect insertmarker;
1274
1275 if (!after && !parent)
1276 insertmarker = QRect (0, 0, viewport()->width(), d->mDropVisualizerWidth/2);
1277 else
1278 {
1279 int level = 0;
1280 if (after)
1281 {
1282 QListViewItem* it = 0L;
1283 if (after->isOpen())
1284 {
1285 // Look for the last child (recursively)
1286 it = after->firstChild();
1287 if (it)
1288 while (it->nextSibling() || it->firstChild())
1289 if ( it->nextSibling() )
1290 it = it->nextSibling();
1291 else
1292 it = it->firstChild();
1293 }
1294
1295 insertmarker = itemRect (it ? it : after);
1296 level = after->depth();
1297 }
1298 else if (parent)
1299 {
1300 insertmarker = itemRect (parent);
1301 level = parent->depth() + 1;
1302 }
1303 insertmarker.setLeft( treeStepSize() * ( level + (rootIsDecorated() ? 1 : 0) ) + itemMargin() );
1304 insertmarker.setRight (viewport()->width());
1305 insertmarker.setTop (insertmarker.bottom() - d->mDropVisualizerWidth/2 + 1);
1306 insertmarker.setBottom (insertmarker.bottom() + d->mDropVisualizerWidth/2);
1307 }
1308
1309 // This is not used anymore, at least by KListView itself (see viewportPaintEvent)
1310 // Remove for KDE 3.0.
1311 if (p)
1312 p->fillRect(insertmarker, Dense4Pattern);
1313
1314 return insertmarker;
1315}
1316
1317QRect KListView::drawItemHighlighter(QPainter *painter, QListViewItem *item)
1318{
1319 QRect r;
1320
1321 if (item)
1322 {
1323 r = itemRect(item);
1324 r.setLeft(r.left()+(item->depth()+1)*treeStepSize());
1325 if (painter) {
1326//US style().drawPrimitive(QStyle::PE_FocusRect, painter, r, colorGroup(),
1327//US QStyle::Style_FocusAtBorder, colorGroup().highlight());
1328 const QColor* pHighl = &(colorGroup().highlight());
1329 //LR style().drawFocusRect(painter, r, colorGroup(), pHighl, true);
1330
1331qDebug("KListView::drawItemHighlighter has to be verified");
1332
1333 }
1334
1335 }
1336
1337 return r;
1338}
1339
1340void KListView::cleanItemHighlighter ()
1341{
1342 if (d->mOldDropHighlighter.isValid())
1343 {
1344 QRect rect=d->mOldDropHighlighter;
1345 d->mOldDropHighlighter = QRect();
1346 viewport()->repaint(rect, true);
1347 }
1348}
1349
1350void KListView::rename(QListViewItem *item, int c)
1351{
1352 if (d->renameable.contains(c))
1353 {
1354 ensureItemVisible(item);
1355//US d->editor->load(item,c);
1356qDebug("KListView::rename has to be verified");
1357
1358 }
1359}
1360
1361bool KListView::isRenameable (int col) const
1362{
1363 return d->renameable.contains(col);
1364}
1365
1366void KListView::setRenameable (int col, bool yesno)
1367{
1368 if (col>=header()->count()) return;
1369
1370 d->renameable.remove(col);
1371 if (yesno && d->renameable.find(col)==d->renameable.end())
1372 d->renameable+=col;
1373 else if (!yesno && d->renameable.find(col)!=d->renameable.end())
1374 d->renameable.remove(col);
1375}
1376
1377void KListView::doneEditing(QListViewItem *item, int row)
1378{
1379 emit itemRenamed(item, item->text(row), row);
1380 emit itemRenamed(item);
1381}
1382
1383bool KListView::acceptDrag(QDropEvent* e) const
1384{
1385qDebug("KListView::acceptDrag drag&drop not supported yet");
1386//US return acceptDrops() && itemsMovable() && (e->source()==viewport());
1387return false;
1388}
1389
1390void KListView::setCreateChildren(bool b)
1391{
1392 d->createChildren=b;
1393}
1394
1395bool KListView::createChildren() const
1396{
1397 return d->createChildren;
1398}
1399
1400
1401int KListView::tooltipColumn() const
1402{
1403 return d->tooltipColumn;
1404}
1405
1406void KListView::setTooltipColumn(int column)
1407{
1408 d->tooltipColumn=column;
1409}
1410
1411void KListView::setDropHighlighter(bool b)
1412{
1413 d->dropHighlighter=b;
1414}
1415
1416bool KListView::dropHighlighter() const
1417{
1418 return d->dropHighlighter;
1419}
1420
1421bool KListView::showTooltip(QListViewItem *item, const QPoint &, int column) const
1422{
1423 return ((tooltip(item, column).length()>0) && (column==tooltipColumn()));
1424}
1425
1426QString KListView::tooltip(QListViewItem *item, int column) const
1427{
1428 return item->text(column);
1429}
1430
1431void KListView::setTabOrderedRenaming(bool b)
1432{
1433 d->tabRename = b;
1434}
1435
1436bool KListView::tabOrderedRenaming() const
1437{
1438 return d->tabRename;
1439}
1440
1441void KListView::keyPressEvent (QKeyEvent* e)
1442{
1443 //don't we need a contextMenuModifier too ? (aleXXX)
1444 if (e->key() == d->contextMenuKey)
1445 {
1446 emit menuShortCutPressed (this, currentItem());
1447 return;
1448 }
1449 if (e->key() == Qt::Key_Delete || e->key() == Qt::Key_Backspace)
1450 {
1451 emit signalDelete ( );
1452 return;
1453 }
1454
1455 if (d->selectionMode != FileManager)
1456 QListView::keyPressEvent (e);
1457 else
1458 fileManagerKeyPressEvent (e);
1459}
1460
1461void KListView::activateAutomaticSelection()
1462{
1463 d->selectedBySimpleMove=true;
1464 d->selectedUsingMouse=false;
1465 if (currentItem()!=0)
1466 {
1467 selectAll(false);
1468 currentItem()->setSelected(true);
1469 currentItem()->repaint();
1470 emit selectionChanged();
1471 };
1472}
1473
1474void KListView::deactivateAutomaticSelection()
1475{
1476 d->selectedBySimpleMove=false;
1477}
1478
1479bool KListView::automaticSelection() const
1480{
1481 return d->selectedBySimpleMove;
1482}
1483
1484void KListView::fileManagerKeyPressEvent (QKeyEvent* e)
1485{
1486 //don't care whether it's on the keypad or not
1487 int e_state=(e->state() & ~Keypad);
1488
1489 int oldSelectionDirection(d->selectionDirection);
1490
1491 if ((e->key()!=Key_Shift) && (e->key()!=Key_Control)
1492 && (e->key()!=Key_Meta) && (e->key()!=Key_Alt))
1493 {
1494 if ((e_state==ShiftButton) && (!d->wasShiftEvent) && (!d->selectedBySimpleMove))
1495 selectAll(FALSE);
1496 d->selectionDirection=0;
1497 d->wasShiftEvent = (e_state == ShiftButton);
1498 };
1499
1500 //d->wasShiftEvent = (e_state == ShiftButton);
1501
1502
1503 QListViewItem* item = currentItem();
1504 if (item==0) return;
1505
1506 QListViewItem* repaintItem1 = item;
1507 QListViewItem* repaintItem2 = 0L;
1508 QListViewItem* visItem = 0L;
1509
1510 QListViewItem* nextItem = 0L;
1511 int items = 0;
1512
1513 bool shiftOrCtrl((e_state==ControlButton) || (e_state==ShiftButton));
1514 int selectedItems(0);
1515 for (QListViewItem *tmpItem=firstChild(); tmpItem!=0; tmpItem=tmpItem->nextSibling())
1516 if (tmpItem->isSelected()) selectedItems++;
1517
1518 if (((selectedItems==0) || ((selectedItems==1) && (d->selectedUsingMouse)))
1519 && (e_state==NoButton)
1520 && ((e->key()==Key_Down)
1521 || (e->key()==Key_Up)
1522 || (e->key()==Key_Next)
1523 || (e->key()==Key_Prior)
1524 || (e->key()==Key_Home)
1525 || (e->key()==Key_End)))
1526 {
1527 d->selectedBySimpleMove=true;
1528 d->selectedUsingMouse=false;
1529 }
1530 else if (selectedItems>1)
1531 d->selectedBySimpleMove=false;
1532
1533 bool emitSelectionChanged(false);
1534
1535 switch (e->key())
1536 {
1537 case Key_Escape:
1538 selectAll(FALSE);
1539 emitSelectionChanged=TRUE;
1540 break;
1541
1542 case Key_Space:
1543 //toggle selection of current item
1544 if (d->selectedBySimpleMove)
1545 d->selectedBySimpleMove=false;
1546 item->setSelected(!item->isSelected());
1547 emitSelectionChanged=TRUE;
1548 break;
1549
1550 case Key_Insert:
1551 //toggle selection of current item and move to the next item
1552 if (d->selectedBySimpleMove)
1553 {
1554 d->selectedBySimpleMove=false;
1555 if (!item->isSelected()) item->setSelected(TRUE);
1556 }
1557 else
1558 {
1559 item->setSelected(!item->isSelected());
1560 };
1561
1562 nextItem=item->itemBelow();
1563
1564 if (nextItem!=0)
1565 {
1566 repaintItem2=nextItem;
1567 visItem=nextItem;
1568 setCurrentItem(nextItem);
1569 };
1570 d->selectionDirection=1;
1571 emitSelectionChanged=TRUE;
1572 break;
1573
1574 case Key_Down:
1575 nextItem=item->itemBelow();
1576 //toggle selection of current item and move to the next item
1577 if (shiftOrCtrl)
1578 {
1579 d->selectionDirection=1;
1580 if (d->selectedBySimpleMove)
1581 d->selectedBySimpleMove=false;
1582 else
1583 {
1584 if (oldSelectionDirection!=-1)
1585 {
1586 item->setSelected(!item->isSelected());
1587 emitSelectionChanged=TRUE;
1588 };
1589 };
1590 }
1591 else if ((d->selectedBySimpleMove) && (nextItem!=0))
1592 {
1593 item->setSelected(false);
1594 emitSelectionChanged=TRUE;
1595 };
1596
1597 if (nextItem!=0)
1598 {
1599 if (d->selectedBySimpleMove)
1600 nextItem->setSelected(true);
1601 repaintItem2=nextItem;
1602 visItem=nextItem;
1603 setCurrentItem(nextItem);
1604 };
1605 break;
1606
1607 case Key_Up:
1608 nextItem=item->itemAbove();
1609 d->selectionDirection=-1;
1610 //move to the prev. item and toggle selection of this one
1611 // => No, can't select the last item, with this. For symmetry, let's
1612 // toggle selection and THEN move up, just like we do in down (David)
1613 if (shiftOrCtrl)
1614 {
1615 if (d->selectedBySimpleMove)
1616 d->selectedBySimpleMove=false;
1617 else
1618 {
1619 if (oldSelectionDirection!=1)
1620 {
1621 item->setSelected(!item->isSelected());
1622 emitSelectionChanged=TRUE;
1623 };
1624 }
1625 }
1626 else if ((d->selectedBySimpleMove) && (nextItem!=0))
1627 {
1628 item->setSelected(false);
1629 emitSelectionChanged=TRUE;
1630 };
1631
1632 if (nextItem!=0)
1633 {
1634 if (d->selectedBySimpleMove)
1635 nextItem->setSelected(true);
1636 repaintItem2=nextItem;
1637 visItem=nextItem;
1638 setCurrentItem(nextItem);
1639 };
1640 break;
1641
1642 case Key_End:
1643 //move to the last item and toggle selection of all items inbetween
1644 nextItem=item;
1645 if (d->selectedBySimpleMove)
1646 item->setSelected(false);
1647 if (shiftOrCtrl)
1648 d->selectedBySimpleMove=false;
1649
1650 while(nextItem!=0)
1651 {
1652 if (shiftOrCtrl)
1653 nextItem->setSelected(!nextItem->isSelected());
1654 if (nextItem->itemBelow()==0)
1655 {
1656 if (d->selectedBySimpleMove)
1657 nextItem->setSelected(true);
1658 repaintItem2=nextItem;
1659 visItem=nextItem;
1660 setCurrentItem(nextItem);
1661 }
1662 nextItem=nextItem->itemBelow();
1663 }
1664 emitSelectionChanged=TRUE;
1665 break;
1666
1667 case Key_Home:
1668 // move to the first item and toggle selection of all items inbetween
1669 nextItem = firstChild();
1670 visItem = nextItem;
1671 repaintItem2 = visItem;
1672 if (d->selectedBySimpleMove)
1673 item->setSelected(false);
1674 if (shiftOrCtrl)
1675 {
1676 d->selectedBySimpleMove=false;
1677
1678 while ( nextItem != item )
1679 {
1680 nextItem->setSelected( !nextItem->isSelected() );
1681 nextItem = nextItem->itemBelow();
1682 }
1683 item->setSelected( !item->isSelected() );
1684 }
1685 setCurrentItem( firstChild() );
1686 emitSelectionChanged=TRUE;
1687 break;
1688
1689 case Key_Next:
1690 items=visibleHeight()/item->height();
1691 nextItem=item;
1692 if (d->selectedBySimpleMove)
1693 item->setSelected(false);
1694 if (shiftOrCtrl)
1695 {
1696 d->selectedBySimpleMove=false;
1697 d->selectionDirection=1;
1698 };
1699
1700 for (int i=0; i<items; i++)
1701 {
1702 if (shiftOrCtrl)
1703 nextItem->setSelected(!nextItem->isSelected());
1704 //the end
1705 if ((i==items-1) || (nextItem->itemBelow()==0))
1706
1707 {
1708 if (shiftOrCtrl)
1709 nextItem->setSelected(!nextItem->isSelected());
1710 if (d->selectedBySimpleMove)
1711 nextItem->setSelected(true);
1712 ensureItemVisible(nextItem);
1713 setCurrentItem(nextItem);
1714 update();
1715 if ((shiftOrCtrl) || (d->selectedBySimpleMove))
1716 {
1717 emit selectionChanged();
1718 }
1719 return;
1720 }
1721 nextItem=nextItem->itemBelow();
1722 }
1723 break;
1724
1725 case Key_Prior:
1726 items=visibleHeight()/item->height();
1727 nextItem=item;
1728 if (d->selectedBySimpleMove)
1729 item->setSelected(false);
1730 if (shiftOrCtrl)
1731 {
1732 d->selectionDirection=-1;
1733 d->selectedBySimpleMove=false;
1734 };
1735
1736 for (int i=0; i<items; i++)
1737 {
1738 if ((nextItem!=item) &&(shiftOrCtrl))
1739 nextItem->setSelected(!nextItem->isSelected());
1740 //the end
1741 if ((i==items-1) || (nextItem->itemAbove()==0))
1742
1743 {
1744 if (d->selectedBySimpleMove)
1745 nextItem->setSelected(true);
1746 ensureItemVisible(nextItem);
1747 setCurrentItem(nextItem);
1748 update();
1749 if ((shiftOrCtrl) || (d->selectedBySimpleMove))
1750 {
1751 emit selectionChanged();
1752 }
1753 return;
1754 }
1755 nextItem=nextItem->itemAbove();
1756 }
1757 break;
1758
1759 case Key_Minus:
1760 if ( item->isOpen() )
1761 setOpen( item, FALSE );
1762 break;
1763 case Key_Plus:
1764 if ( !item->isOpen() && (item->isExpandable() || item->childCount()) )
1765 setOpen( item, TRUE );
1766 break;
1767 default:
1768 bool realKey = ((e->key()!=Key_Shift) && (e->key()!=Key_Control)
1769 && (e->key()!=Key_Meta) && (e->key()!=Key_Alt));
1770
1771 bool selectCurrentItem = (d->selectedBySimpleMove) && (item->isSelected());
1772 if (realKey && selectCurrentItem)
1773 item->setSelected(false);
1774 //this is mainly for the "goto filename beginning with pressed char" feature (aleXXX)
1775 QListView::SelectionMode oldSelectionMode = selectionMode();
1776 setSelectionMode (QListView::Multi);
1777 QListView::keyPressEvent (e);
1778 setSelectionMode (oldSelectionMode);
1779 if (realKey && selectCurrentItem)
1780 {
1781 currentItem()->setSelected(true);
1782 emitSelectionChanged=TRUE;
1783 }
1784 repaintItem2=currentItem();
1785 if (realKey)
1786 visItem=currentItem();
1787 break;
1788 }
1789
1790 if (visItem)
1791 ensureItemVisible(visItem);
1792
1793 QRect ir;
1794 if (repaintItem1)
1795 ir = ir.unite( itemRect(repaintItem1) );
1796 if (repaintItem2)
1797 ir = ir.unite( itemRect(repaintItem2) );
1798
1799 if ( !ir.isEmpty() )
1800 { // rectangle to be repainted
1801 if ( ir.x() < 0 )
1802 ir.moveBy( -ir.x(), 0 );
1803 viewport()->repaint( ir, FALSE );
1804 }
1805 /*if (repaintItem1)
1806 repaintItem1->repaint();
1807 if (repaintItem2)
1808 repaintItem2->repaint();*/
1809 update();
1810 if (emitSelectionChanged)
1811 emit selectionChanged();
1812}
1813
1814void KListView::setSelectionModeExt (SelectionModeExt mode)
1815{
1816 d->selectionMode = mode;
1817
1818 switch (mode)
1819 {
1820 case Single:
1821 case Multi:
1822 case Extended:
1823 case NoSelection:
1824 setSelectionMode (static_cast<QListView::SelectionMode>(static_cast<int>(mode)));
1825 break;
1826
1827 case FileManager:
1828 setSelectionMode (QListView::Extended);
1829 break;
1830
1831 default:
1832 kdWarning () << "Warning: illegal selection mode " << int(mode) << " set!" << endl;
1833 break;
1834 }
1835}
1836
1837KListView::SelectionModeExt KListView::selectionModeExt () const
1838{
1839 return d->selectionMode;
1840}
1841
1842int KListView::itemIndex( const QListViewItem *item ) const
1843{
1844 if ( !item )
1845 return -1;
1846
1847 if ( item == firstChild() )
1848 return 0;
1849 else {
1850 QListViewItemIterator it(firstChild());
1851 uint j = 0;
1852 for (; it.current() && it.current() != item; ++it, ++j );
1853
1854 if( !it.current() )
1855 return -1;
1856
1857 return j;
1858 }
1859}
1860
1861QListViewItem* KListView::itemAtIndex(int index)
1862{
1863 if (index<0)
1864 return 0;
1865
1866 int j(0);
1867 for (QListViewItemIterator it=firstChild(); it.current(); it++)
1868 {
1869 if (j==index)
1870 return it.current();
1871 j++;
1872 };
1873 return 0;
1874}
1875
1876
1877void KListView::emitContextMenu (KListView*, QListViewItem* i)
1878{
1879 QPoint p;
1880 qDebug("KListView::emitContextMenu ");
1881
1882 if (i)
1883 p = viewport()->mapToGlobal(itemRect(i).center());
1884 else
1885 p = mapToGlobal(rect().center());
1886
1887 emit contextMenu (this, i, p);
1888}
1889
1890void KListView::emitContextMenu (QListViewItem* i, const QPoint& p, int)
1891{
1892 qDebug("KListView::emitContextMenu ");
1893 emit contextMenu (this, i, p);
1894}
1895
1896void KListView::setAcceptDrops (bool val)
1897{
1898 QListView::setAcceptDrops (val);
1899 viewport()->setAcceptDrops (val);
1900}
1901
1902int KListView::dropVisualizerWidth () const
1903{
1904 return d->mDropVisualizerWidth;
1905}
1906
1907
1908void KListView::viewportPaintEvent(QPaintEvent *e)
1909{
1910 QListView::viewportPaintEvent(e);
1911
1912 if (d->mOldDropVisualizer.isValid() && e->rect().intersects(d->mOldDropVisualizer))
1913 {
1914 QPainter painter(viewport());
1915
1916 // This is where we actually draw the drop-visualizer
1917 painter.fillRect(d->mOldDropVisualizer, Dense4Pattern);
1918 }
1919 if (d->mOldDropHighlighter.isValid() && e->rect().intersects(d->mOldDropHighlighter))
1920 {
1921 QPainter painter(viewport());
1922
1923qDebug("KListView::viewportPaintEvent has to be verified");
1924
1925 // This is where we actually draw the drop-highlighter
1926//US style().drawPrimitive(QStyle::PE_FocusRect, &painter, d->mOldDropHighlighter, colorGroup(),
1927//US QStyle::Style_FocusAtBorder);
1928
1929//LR style().drawFocusRect(&painter, d->mOldDropHighlighter, colorGroup(), (const QColor*)0, true);
1930
1931
1932 }
1933}
1934
1935void KListView::setFullWidth()
1936{
1937 setFullWidth(true);
1938}
1939
1940void KListView::setFullWidth(bool fullWidth)
1941{
1942 d->fullWidth = fullWidth;
1943//US header()->setStretchEnabled(fullWidth, columns()-1);
1944}
1945
1946bool KListView::fullWidth() const
1947{
1948 return d->fullWidth;
1949}
1950
1951int KListView::addColumn(const QString& label, int width)
1952{
1953 int result = QListView::addColumn(label, width);
1954 if (d->fullWidth) {
1955//US header()->setStretchEnabled(false, columns()-2);
1956//US header()->setStretchEnabled(true, columns()-1);
1957 }
1958 return result;
1959}
1960
1961int KListView::addColumn(const QIconSet& iconset, const QString& label, int width)
1962{
1963 int result = QListView::addColumn(iconset, label, width);
1964 if (d->fullWidth) {
1965//US header()->setStretchEnabled(false, columns()-2);
1966//US header()->setStretchEnabled(true, columns()-1);
1967 }
1968 return result;
1969}
1970
1971void KListView::removeColumn(int index)
1972{
1973 QListView::removeColumn(index);
1974//US if (d->fullWidth && index == columns()) header()->setStretchEnabled(true, columns()-1);
1975}
1976
1977void KListView::viewportResizeEvent(QResizeEvent* e)
1978{
1979 QListView::viewportResizeEvent(e);
1980}
1981
1982const QColor &KListView::alternateBackground() const
1983{
1984 return d->alternateBackground;
1985}
1986
1987void KListView::setAlternateBackground(const QColor &c)
1988{
1989 d->alternateBackground = c;
1990 repaint();
1991}
1992
1993void KListView::saveLayout(KConfig *config, const QString &group) const
1994{
1995 KConfigGroupSaver saver(config, group);
1996 QStringList widths, order;
1997 for (int i = 0; i < columns(); ++i)
1998 {
1999 widths << QString::number(columnWidth(i));
2000 order << QString::number(header()->mapToIndex(i));
2001 }
2002 config->writeEntry("ColumnWidths", widths);
2003 config->writeEntry("ColumnOrder", order);
2004 config->writeEntry("SortColumn", d->sortColumn);
2005 config->writeEntry("SortAscending", d->sortAscending);
2006}
2007
2008void KListView::restoreLayout(KConfig *config, const QString &group)
2009{
2010 KConfigGroupSaver saver(config, group);
2011 QStringList cols = config->readListEntry("ColumnWidths");
2012 int i = 0;
2013 for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it)
2014 setColumnWidth(i++, (*it).toInt());
2015
2016 cols = config->readListEntry("ColumnOrder");
2017 i = 0;
2018 for (QStringList::ConstIterator it = cols.begin(); it != cols.end(); ++it)
2019 header()->moveSection(i++, (*it).toInt());
2020
2021/*US I changed the following code, because hasKey is not available.
2022!!! check if my version is correct
2023 if (config->hasKey("SortColumn"))
2024 setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true));
2025*/
2026 QStringList langLst = config->readListEntry( "SortColumn" );
2027 if (!langLst.isEmpty())
2028 setSorting(config->readNumEntry("SortColumn"), config->readBoolEntry("SortAscending", true));
2029}
2030
2031void KListView::setSorting(int column, bool ascending)
2032{
2033 d->sortColumn = column;
2034 d->sortAscending = ascending;
2035 QListView::setSorting(column, ascending);
2036}
2037
2038int KListView::columnSorted(void) const
2039{
2040 return d->sortColumn;
2041}
2042
2043bool KListView::ascendingSort(void) const
2044{
2045 return d->sortAscending;
2046}
2047
2048KListViewItem::KListViewItem(QListView *parent)
2049 : QListViewItem(parent)
2050{
2051 init();
2052}
2053
2054KListViewItem::KListViewItem(QListViewItem *parent)
2055 : QListViewItem(parent)
2056{
2057 init();
2058}
2059
2060KListViewItem::KListViewItem(QListView *parent, QListViewItem *after)
2061 : QListViewItem(parent, after)
2062{
2063 init();
2064}
2065
2066KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after)
2067 : QListViewItem(parent, after)
2068{
2069 init();
2070}
2071
2072KListViewItem::KListViewItem(QListView *parent,
2073 QString label1, QString label2, QString label3, QString label4,
2074 QString label5, QString label6, QString label7, QString label8)
2075 : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8)
2076{
2077 init();
2078}
2079
2080KListViewItem::KListViewItem(QListViewItem *parent,
2081 QString label1, QString label2, QString label3, QString label4,
2082 QString label5, QString label6, QString label7, QString label8)
2083 : QListViewItem(parent, label1, label2, label3, label4, label5, label6, label7, label8)
2084{
2085 init();
2086}
2087
2088KListViewItem::KListViewItem(QListView *parent, QListViewItem *after,
2089 QString label1, QString label2, QString label3, QString label4,
2090 QString label5, QString label6, QString label7, QString label8)
2091 : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8)
2092{
2093 init();
2094}
2095
2096KListViewItem::KListViewItem(QListViewItem *parent, QListViewItem *after,
2097 QString label1, QString label2, QString label3, QString label4,
2098 QString label5, QString label6, QString label7, QString label8)
2099 : QListViewItem(parent, after, label1, label2, label3, label4, label5, label6, label7, label8)
2100{
2101 init();
2102}
2103
2104KListViewItem::~KListViewItem()
2105{
2106}
2107
2108void KListViewItem::init()
2109{
2110 m_known = false;
2111}
2112
2113const QColor &KListViewItem::backgroundColor()
2114{
2115 if (isAlternate())
2116 return static_cast< KListView* >(listView())->alternateBackground();
2117 return listView()->viewport()->colorGroup().base();
2118}
2119
2120bool KListViewItem::isAlternate()
2121{
2122 KListView *lv = static_cast<KListView *>(listView());
2123 if (lv && lv->alternateBackground().isValid())
2124 {
2125 KListViewItem *above = 0;
2126//US above = dynamic_cast<KListViewItem *>(itemAbove());
2127 above = (KListViewItem *)(itemAbove());
2128 m_known = above ? above->m_known : true;
2129 if (m_known)
2130 {
2131 m_odd = above ? !above->m_odd : false;
2132 }
2133 else
2134 {
2135 KListViewItem *item;
2136 bool previous = true;
2137 if (parent())
2138 {
2139//US item = dynamic_cast<KListViewItem *>(parent());
2140 item = (KListViewItem *)(parent());
2141 if (item)
2142 previous = item->m_odd;
2143//US item = dynamic_cast<KListViewItem *>(parent()->firstChild());
2144 item = (KListViewItem *)(parent()->firstChild());
2145 }
2146 else
2147 {
2148//US item = dynamic_cast<KListViewItem *>(lv->firstChild());
2149 item = (KListViewItem *)(lv->firstChild());
2150 }
2151
2152 while(item)
2153 {
2154 item->m_odd = previous = !previous;
2155 item->m_known = true;
2156//US item = dynamic_cast<KListViewItem *>(item->nextSibling());
2157 item = (KListViewItem *)(item->nextSibling());
2158 }
2159 }
2160 return m_odd;
2161 }
2162 return false;
2163}
2164
2165void KListViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
2166{
2167 QColorGroup _cg = cg;
2168 const QPixmap *pm = listView()->viewport()->backgroundPixmap();
2169 if (pm && !pm->isNull())
2170 {
2171 _cg.setBrush(QColorGroup::Base, QBrush(backgroundColor(), *pm));
2172 QPoint o = p->brushOrigin();
2173 p->setBrushOrigin( o.x()-listView()->contentsX(), o.y()-listView()->contentsY() );
2174 }
2175 else if (isAlternate()) {
2176//US if (listView()->viewport()->backgroundMode()==Qt::FixedColor)
2177 if (listView()->viewport()->backgroundMode()==QWidget::PaletteBackground)
2178 _cg.setColor(QColorGroup::Background, static_cast< KListView* >(listView())->alternateBackground());
2179 else
2180 _cg.setColor(QColorGroup::Base, static_cast< KListView* >(listView())->alternateBackground());
2181 }
2182 QListViewItem::paintCell(p, _cg, column, width, alignment);
2183}
2184
2185void KListView::virtual_hook( int, void* )
2186{ /*BASE::virtual_hook( id, data );*/ }
2187
2188//US #include "klistview.moc"
2189//US #include "klistviewlineedit.moc"
2190
2191// vim: ts=2 sw=2 et