~ubuntu-branches/ubuntu/intrepid/digikam/intrepid

« back to all changes in this revision

Viewing changes to digikam/digikam/iconview.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2008-07-17 20:25:39 UTC
  • mfrom: (1.3.2 upstream) (37 hardy)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20080717202539-1bw3w3nrsso7yj4z
* New upstream release
  - digiKam 0.9.4 Release Plan (KDE3) ~ 13 July 08 (Closes: #490144)
* DEB_CONFIGURE_EXTRA_FLAGS := --without-included-sqlite3
* Debhelper compatibility level V7
* Install pixmaps in debian/*.install
* Add debian/digikam.lintian-overrides

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* ============================================================
2
 
 * File  : iconview.cpp
3
 
 * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
4
 
 * Date  : 2005-04-24
5
 
 * Description : 
6
 
 * 
7
 
 * Copyright 2005 by Renchi Raju
8
 
 
 
2
 *
 
3
 * This file is a part of digiKam project
 
4
 * http://www.digikam.org
 
5
 *
 
6
 * Date        : 2005-04-24
 
7
 * Description : icons view.
 
8
 *
 
9
 * Copyright (C) 2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
 
10
 * Copyright (C) 2006-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
 
11
 *
9
12
 * This program is free software; you can redistribute it
10
13
 * and/or modify it under the terms of the GNU General
11
14
 * Public License as published by the Free Software Foundation;
19
22
 * 
20
23
 * ============================================================ */
21
24
 
 
25
#define RECT_EXTENSION 300
 
26
 
 
27
// C++ includes.
 
28
 
 
29
#include <cstdlib>
 
30
 
 
31
// Qt includes.
 
32
 
22
33
#include <qtimer.h>
23
34
#include <qpainter.h>
24
35
#include <qvaluelist.h>
27
38
#include <qapplication.h>
28
39
#include <qdrawutil.h>
29
40
 
30
 
#include <kdebug.h>
 
41
// KDE includes.
 
42
 
31
43
#include <kcursor.h>
32
44
#include <kglobalsettings.h>
33
45
 
34
 
extern "C"
35
 
{
36
 
#include <stdlib.h>
37
 
}
 
46
// Local includes.
38
47
 
 
48
#include "ddebug.h"
39
49
#include "iconitem.h"
40
50
#include "icongroupitem.h"
41
51
#include "iconview.h"
 
52
#include "iconview.moc"
42
53
 
43
 
#define RECT_EXTENSION 300
 
54
namespace Digikam
 
55
{
44
56
 
45
57
class IconViewPriv
46
58
{
48
60
 
49
61
    IconViewPriv()
50
62
    {
51
 
        firstGroup = 0;
52
 
        lastGroup  = 0;
53
 
        currItem   = 0;
54
 
        anchorItem = 0;
55
 
        clearing   = false;
56
 
        spacing    = 10;
57
 
 
58
 
        rubber       = 0;
59
 
        dragging     = false;
60
 
        pressedMoved = false;
61
 
        
62
 
        firstContainer = 0;
63
 
        lastContainer  = 0;
64
 
 
65
 
        showTips       = false;
66
 
        toolTipItem    = 0;
67
 
        toolTipTimer   = 0;
68
 
        updateTimer    = 0;
 
63
        firstGroup          = 0;
 
64
        lastGroup           = 0;
 
65
        currItem            = 0;
 
66
        anchorItem          = 0;
 
67
        clearing            = false;
 
68
        spacing             = 10;
 
69
 
 
70
        rubber              = 0;
 
71
        dragging            = false;
 
72
        pressedMoved        = false;
 
73
 
 
74
        firstContainer      = 0;
 
75
        lastContainer       = 0;
 
76
 
 
77
        showTips                 = false;
 
78
        toolTipItem              = 0;
 
79
        toolTipTimer             = 0;
 
80
        rearrangeTimer           = 0;
 
81
        rearrangeTimerInterval   = 0;
 
82
        storedVisibleItem        = 0;
 
83
        needEmitSelectionChanged = false;
69
84
    }
70
 
    
71
 
    IconGroupItem*  firstGroup;
72
 
    IconGroupItem*  lastGroup;
73
 
    IconItem*       currItem;
74
 
    IconItem*       anchorItem;
75
 
 
76
 
    bool            clearing;
77
 
    QTimer*         updateTimer;
78
 
    int             spacing;
 
85
 
 
86
    bool               clearing;
 
87
    bool               showTips;
 
88
    bool               pressedMoved;
 
89
    bool               dragging;
 
90
    bool               needEmitSelectionChanged; // store for slotRearrange
 
91
 
 
92
    int                spacing;
79
93
 
80
94
    QPtrDict<IconItem> selectedItems;
81
95
    QPtrDict<IconItem> prevSelectedItems;
82
96
 
83
97
    QRect*             rubber;
84
 
    bool               dragging;
 
98
 
85
99
    QPoint             dragStartPos;
86
 
    bool               pressedMoved;
87
 
    
 
100
 
 
101
    QTimer*            rearrangeTimer;
 
102
    QTimer*            toolTipTimer;
 
103
 
88
104
    IconItem*          toolTipItem;
89
 
    QTimer*            toolTipTimer;
90
 
    bool               showTips;
 
105
    IconItem*          currItem;
 
106
    IconItem*          anchorItem;
 
107
    IconItem*          storedVisibleItem; // store position for slotRearrange
 
108
 
 
109
    IconGroupItem*     firstGroup;
 
110
    IconGroupItem*     lastGroup;
 
111
 
 
112
    int                rearrangeTimerInterval;
91
113
 
92
114
    struct ItemContainer 
93
115
    {
111
133
    };
112
134
};
113
135
 
114
 
static int cmpItems( const void *n1, const void *n2 )
115
 
{
116
 
    if ( !n1 || !n2 )
117
 
        return 0;
118
 
 
119
 
    IconViewPriv::SortableItem *i1 = (IconViewPriv::SortableItem *)n1;
120
 
    IconViewPriv::SortableItem *i2 = (IconViewPriv::SortableItem *)n2;
121
 
 
122
 
    return i1->group->compare( i2->group );
123
 
}
124
 
 
125
 
 
126
136
IconView::IconView(QWidget* parent, const char* name)
127
 
    : QScrollView(parent, name, Qt::WStaticContents|Qt::WNoAutoErase)
 
137
        : QScrollView(parent, name, Qt::WStaticContents|Qt::WNoAutoErase)
128
138
{
129
139
    viewport()->setBackgroundMode(Qt::NoBackground);
130
 
    
131
140
    viewport()->setFocusProxy(this);
132
141
    viewport()->setFocusPolicy(QWidget::WheelFocus);
133
142
    viewport()->setMouseTracking(true);
134
143
 
135
144
    d = new IconViewPriv;
136
 
    d->updateTimer = new QTimer(this);
 
145
    d->rearrangeTimer  = new QTimer(this);
137
146
    d->toolTipTimer = new QTimer(this);
138
147
    
139
 
    connect(d->updateTimer, SIGNAL(timeout()),
140
 
            SLOT(slotUpdate()));
 
148
    connect(d->rearrangeTimer, SIGNAL(timeout()),
 
149
            this, SLOT(slotRearrange()));
 
150
            
141
151
    connect(d->toolTipTimer, SIGNAL(timeout()),
142
 
            SLOT(slotToolTip()));
 
152
            this, SLOT(slotToolTip()));
143
153
 
144
154
    setEnableToolTips(true);
145
155
}
148
158
{
149
159
    clear(false);
150
160
 
151
 
    delete d->updateTimer;
 
161
    delete d->rearrangeTimer;
152
162
    delete d->toolTipTimer;
153
 
 
154
163
    delete d->rubber;
155
 
    
156
164
    delete d;
157
165
}
158
166
 
189
197
 
190
198
void IconView::setCurrentItem(IconItem* item)
191
199
{
192
 
    d->currItem = item;
 
200
    d->currItem   = item;
193
201
    d->anchorItem = d->currItem;
 
202
    
194
203
    if (d->currItem)
195
204
    {
196
205
        d->currItem->setSelected(true, true);
218
227
    return 0;
219
228
}
220
229
 
 
230
IconGroupItem* IconView::findGroup(const QPoint& pos)
 
231
{
 
232
    QPoint p = viewportToContents(viewport()->mapFromGlobal(pos));
 
233
    for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
 
234
    {
 
235
        QRect rect = group->rect();
 
236
        int bottom;
 
237
        if (group == d->lastGroup)
 
238
            bottom = contentsHeight();
 
239
        else
 
240
            bottom = group->nextGroup()->rect().top();
 
241
 
 
242
        rect.setBottom(bottom);
 
243
 
 
244
        if ( rect.contains(p) ) 
 
245
        {
 
246
            return group;
 
247
        }
 
248
    }
 
249
 
 
250
    return 0;
 
251
}
 
252
 
221
253
int IconView::count() const
222
254
{
223
255
    int c = 0;
229
261
    return c;
230
262
}
231
263
 
 
264
 
 
265
int IconView::countSelected() const
 
266
{
 
267
    int c = 0;
 
268
    for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
 
269
    {
 
270
        for (IconItem *it = group->firstItem(); it; it = it->nextItem())
 
271
            if (it->isSelected())
 
272
                c++;
 
273
    }
 
274
 
 
275
    return c;
 
276
}
 
277
 
232
278
int IconView::groupCount() const
233
279
{
234
280
    int c = 0;
300
346
 
301
347
void IconView::selectAll()
302
348
{
303
 
    bool wasBlocked = signalsBlocked();;
 
349
    bool wasBlocked = signalsBlocked();
304
350
 
305
351
    if (!wasBlocked)
306
352
        blockSignals(true);
321
367
 
322
368
void IconView::invertSelection()
323
369
{
324
 
    bool wasBlocked = signalsBlocked();;
 
370
    bool wasBlocked = signalsBlocked();
325
371
 
326
372
    if (!wasBlocked)
327
373
        blockSignals(true);
361
407
    emit signalSelectionChanged();
362
408
}
363
409
 
 
410
void IconView::setStoredVisibleItem(IconItem *item) 
 
411
 
412
    d->storedVisibleItem = item; 
 
413
}
 
414
 
364
415
void IconView::insertGroup(IconGroupItem* group)
365
416
{
366
417
    if (!group)
381
432
        d->lastGroup         = group;
382
433
    }
383
434
 
384
 
    d->updateTimer->start(0, true);
 
435
    d->storedVisibleItem = findFirstVisibleItem();
 
436
    startRearrangeTimer();
385
437
}
386
438
 
387
439
void IconView::takeGroup(IconGroupItem* group)
389
441
    if (!group)
390
442
        return;
391
443
 
392
 
    if (group == d->firstGroup) 
 
444
    // this is only to find an alternative visible item if all visible items
 
445
    // are removed
 
446
    IconGroupItem *alternativeVisibleGroup = 0;
 
447
    d->storedVisibleItem = 0;
 
448
 
 
449
    if (group == d->firstGroup)
393
450
    {
394
451
        d->firstGroup = d->firstGroup->m_next;
395
452
        if (d->firstGroup)
396
453
            d->firstGroup->m_prev = 0;
397
454
        else
398
455
            d->firstGroup = d->lastGroup = 0;
 
456
        alternativeVisibleGroup = d->firstGroup;
399
457
    }
400
458
    else if (group == d->lastGroup) 
401
459
    {
402
460
        d->lastGroup = d->lastGroup->m_prev;
403
461
        if ( d->lastGroup )
404
 
            d->lastGroup->m_next = 0;
 
462
            d->lastGroup->m_next = 0;
405
463
        else
406
464
            d->firstGroup = d->lastGroup = 0;
 
465
        alternativeVisibleGroup = d->lastGroup->m_prev;
407
466
    }
408
467
    else 
409
468
    {
414
473
                i->m_prev->m_next = i->m_next;
415
474
            if ( i->m_next )
416
475
                i->m_next->m_prev = i->m_prev;
 
476
 
 
477
            if (i->m_prev)
 
478
                alternativeVisibleGroup = i->m_prev;
 
479
            else
 
480
                alternativeVisibleGroup = i->m_next;
417
481
        }
418
482
    }
419
483
 
420
484
    if (!d->clearing)
421
485
    {
422
 
        d->updateTimer->start(0, true);
 
486
        d->storedVisibleItem = findFirstVisibleItem();
 
487
        if (!d->storedVisibleItem && alternativeVisibleGroup)
 
488
        {
 
489
            // find an alternative visible item
 
490
            d->storedVisibleItem = alternativeVisibleGroup->lastItem();
 
491
        }
 
492
        startRearrangeTimer();
423
493
    }
424
494
}
425
495
 
428
498
    if (!item)
429
499
        return;
430
500
 
431
 
    d->updateTimer->start(0, true);
 
501
    d->storedVisibleItem = findFirstVisibleItem();
 
502
    startRearrangeTimer();
432
503
}
433
504
 
434
505
void IconView::takeItem(IconItem* item)
438
509
 
439
510
    // First remove item from any containers holding it
440
511
    IconViewPriv::ItemContainer *tmp = d->firstContainer;
441
 
    while (tmp) {
 
512
    while (tmp) 
 
513
    {
442
514
        tmp->items.remove(item);
443
515
        tmp = tmp->next;
444
516
    }
445
517
 
446
518
    // Remove from selected item list
447
519
    d->selectedItems.remove(item);
 
520
    // See bug 161084
 
521
    if (d->selectedItems.count() || item->isSelected())
 
522
        d->needEmitSelectionChanged = true;
448
523
 
449
524
    if (d->toolTipItem == item)
450
525
    {
459
534
        d->currItem = item->nextItem();
460
535
        if (!d->currItem)
461
536
            d->currItem = item->prevItem();
 
537
        // defer calling d->currItem->setSelected (and emitting the signals) to slotRearrange
462
538
    }
463
539
 
464
540
    d->anchorItem = d->currItem;
465
541
    
466
542
    if (!d->clearing)
467
543
    {
468
 
        d->updateTimer->start(0, true);
 
544
        d->storedVisibleItem = findFirstVisibleItem();
 
545
        if (d->storedVisibleItem == item)
 
546
            d->storedVisibleItem = d->currItem;
 
547
        startRearrangeTimer();
469
548
    }
470
549
}
471
550
 
472
 
void IconView::triggerUpdate()
473
 
{
474
 
    d->updateTimer->start(0, true);    
 
551
void IconView::triggerRearrangement()
 
552
{
 
553
    d->storedVisibleItem = findFirstVisibleItem();
 
554
    startRearrangeTimer();
 
555
}
 
556
 
 
557
void IconView::setDelayedRearrangement(bool delayed)
 
558
{
 
559
    // if it is known that e.g. several items will be added or deleted in the next time,
 
560
    // but not from the same event queue thread stack location, it may be desirable to delay
 
561
    // the rearrangeTimer a bit
 
562
    if (delayed)
 
563
        d->rearrangeTimerInterval = 50;
 
564
    else
 
565
        d->rearrangeTimerInterval = 0;
 
566
}
 
567
 
 
568
void IconView::startRearrangeTimer()
 
569
{
 
570
    // We want to reduce the number of updates, but not remove all updates
 
571
    if (!d->rearrangeTimer->isActive())
 
572
        d->rearrangeTimer->start(d->rearrangeTimerInterval, true);
475
573
}
476
574
 
477
575
void IconView::sort()
486
584
    int gcount = groupCount();
487
585
    
488
586
    // then sort the groups themselves
489
 
   IconViewPriv::SortableItem *groups
490
 
        = new IconViewPriv::SortableItem[ gcount ];
 
587
    IconViewPriv::SortableItem *groups = new IconViewPriv::SortableItem[ gcount ];
491
588
 
492
589
    IconGroupItem *group = d->firstGroup;
493
590
    int i = 0;
 
591
    
494
592
    for ( ; group; group = group->m_next )
495
593
        groups[ i++ ].group = group;
496
594
 
497
 
    qsort( groups, gcount, sizeof( IconViewPriv::SortableItem ),
498
 
           cmpItems );
 
595
    qsort( groups, gcount, sizeof( IconViewPriv::SortableItem ), cmpItems );
499
596
 
500
597
    IconGroupItem *prev = 0;
501
598
    group = 0;
502
 
    for ( i = 0; i < (int)gcount; ++i ) {
 
599
    
 
600
    for ( i = 0; i < (int)gcount; ++i ) 
 
601
    {
503
602
        group = groups[ i ].group;
504
 
        if ( group ) {
 
603
        if ( group ) 
 
604
        {
505
605
            group->m_prev = prev;
 
606
            
506
607
            if ( group->m_prev )
507
608
                group->m_prev->m_next = group;
 
609
            
508
610
            group->m_next = 0;
509
611
        }
 
612
        
510
613
        if ( i == 0 )
511
614
            d->firstGroup = group;
 
615
            
512
616
        if ( i == (int)gcount - 1 )
513
617
            d->lastGroup = group;
514
618
        prev = group;
515
619
    }
516
620
    
517
621
    delete [] groups;
518
 
 
 
622
}
 
623
 
 
624
void IconView::slotRearrange()
 
625
{
 
626
    sort();
 
627
    arrangeItems();
 
628
 
 
629
    // ensure there is a current item
519
630
    if (!d->currItem)
520
631
    {
521
632
        // set the currItem to first item
524
635
    }
525
636
    d->anchorItem = d->currItem;
526
637
 
527
 
    if (d->currItem)
 
638
    // ensure there is a selection
 
639
    if (d->selectedItems.isEmpty() && d->currItem)
528
640
    {
529
641
        d->currItem->setSelected(true, true);
 
642
    }
 
643
    else if (d->needEmitSelectionChanged)
 
644
    {
 
645
        emit signalSelectionChanged();
 
646
    }
 
647
    d->needEmitSelectionChanged = false;
 
648
 
 
649
    // set first visible item if they where stored before update was triggered
 
650
    if (d->storedVisibleItem)
 
651
    {
 
652
        ensureItemVisible(d->storedVisibleItem);
 
653
        // reset to 0
 
654
        d->storedVisibleItem = 0;
 
655
    }
 
656
    else
 
657
    {
530
658
        ensureItemVisible(d->currItem);
531
659
    }
532
 
}
533
660
 
534
 
void IconView::slotUpdate()
535
 
{
536
 
    sort();
537
 
    rearrangeItems();
538
661
    viewport()->update();
539
662
}
540
663
 
541
 
void IconView::rearrangeItems(bool update)
 
664
bool IconView::arrangeItems()
542
665
{
543
 
    if (!d->firstGroup || !d->lastGroup)
544
 
        return;
545
 
 
546
666
    int  y   = 0;
547
667
    int  itemW = itemRect().width();
548
668
    int  itemH = itemRect().height();
597
717
 
598
718
    rebuildContainers();
599
719
 
600
 
    if (changed && update)
601
 
        viewport()->update();
 
720
    return changed;
602
721
}
603
722
 
604
723
QRect IconView::itemRect() const
660
779
 
661
780
QRect IconView::contentsRectToViewport(const QRect& r) const
662
781
{
663
 
    QRect vr = QRect(contentsToViewport(QPoint(r.x(), r.y())),
664
 
                     r.size());
 
782
    QRect vr = QRect(contentsToViewport(QPoint(r.x(), r.y())), r.size());
665
783
    return vr;
666
784
}
667
785
 
668
786
void IconView::resizeEvent(QResizeEvent* e)
669
787
{
670
788
    QScrollView::resizeEvent(e);
671
 
    rearrangeItems();
 
789
    triggerRearrangement();
672
790
}
673
791
 
674
792
void IconView::rebuildContainers()
693
811
        {
694
812
            c->items.append( item );
695
813
            c = c->next;
 
814
            
696
815
            if (!c) 
697
816
            {
698
817
                appendContainer();
699
818
                c = d->lastContainer;
700
819
            }
 
820
            
701
821
            c->items.append(item);
702
822
            item = item->nextItem();
703
823
            c = c->prev;
840
960
        else if (e->state() & Qt::ShiftButton)
841
961
        {
842
962
            blockSignals(true);
843
 
            
 
963
 
844
964
            if (d->currItem)
845
965
            {
846
966
                clearSelection();
847
 
                
 
967
 
848
968
                // select all items from/upto the current item
849
969
                bool bwdSelect = false;
850
970
 
883
1003
            }
884
1004
 
885
1005
            blockSignals(false);
 
1006
 
886
1007
            emit signalSelectionChanged();
887
1008
        }
888
1009
        else
894
1015
        IconItem* prevCurrItem = d->currItem;
895
1016
        d->currItem   = item;
896
1017
        d->anchorItem = item;
 
1018
        
897
1019
        if (prevCurrItem)
898
1020
            prevCurrItem->repaint();
 
1021
        
899
1022
        d->currItem->repaint();
900
1023
 
901
1024
        d->dragging = true;
915
1038
        // ctrl is pressed. make sure our current selection is not lost
916
1039
        d->prevSelectedItems.clear();
917
1040
        QPtrDictIterator<IconItem> it( d->selectedItems );
 
1041
        
918
1042
        for ( ; it.current(); ++it )
919
1043
        {
920
1044
            d->prevSelectedItems.insert(it.current(), it.current());
1011
1135
        return;
1012
1136
    }
1013
1137
 
1014
 
 
1015
1138
    if (!d->rubber)
1016
1139
        return;
1017
1140
 
1076
1199
 
1077
1200
    if (changed)
1078
1201
    {
1079
 
        emit signalSelectionChanged();
1080
1202
        paintRegion.translate(-contentsX(), -contentsY());
1081
1203
        viewport()->repaint(paintRegion);
1082
1204
    }
1093
1215
    p.end();
1094
1216
 
1095
1217
    d->pressedMoved = true;
 
1218
 
 
1219
    if (changed)
 
1220
        emit signalSelectionChanged();
1096
1221
}
1097
1222
 
1098
1223
void IconView::contentsMouseReleaseEvent(QMouseEvent* e)
1119
1244
    {
1120
1245
        if (d->pressedMoved)
1121
1246
        {
 
1247
            emit signalSelectionChanged();
1122
1248
            d->pressedMoved = false;
1123
1249
            return;
1124
1250
        }
1150
1276
    d->toolTipTimer->stop();
1151
1277
    slotToolTip();
1152
1278
    viewport()->update();
1153
 
    
 
1279
 
1154
1280
    QScrollView::contentsWheelEvent(e);
1155
1281
}
1156
1282
 
1160
1286
        return;
1161
1287
 
1162
1288
    IconItem *item = findItem(e->pos());
1163
 
    if (item) {
 
1289
    if (item) 
 
1290
    {
1164
1291
        itemClickedToOpen(item);
1165
1292
    }
1166
1293
}
1172
1299
    if (!firstItem())
1173
1300
        return;
1174
1301
 
1175
 
    switch ( e->key() ) 
1176
 
    {
1177
 
    case Key_Home: 
1178
 
    {
1179
 
        IconItem* tmp = d->currItem;
1180
 
        d->currItem = firstItem();
1181
 
        d->anchorItem = d->currItem;
1182
 
        if (tmp)
1183
 
            tmp->repaint();
1184
 
 
1185
 
        firstItem()->setSelected(true, true);
1186
 
        ensureItemVisible(firstItem());
1187
 
        handled = true;
1188
 
        break;
1189
 
    }
1190
 
 
1191
 
    case Key_End: 
1192
 
    {
1193
 
        IconItem* tmp = d->currItem;
1194
 
        d->currItem   = lastItem();
1195
 
        d->anchorItem = d->currItem;
1196
 
        if (tmp)
1197
 
            tmp->repaint();
1198
 
 
1199
 
        lastItem()->setSelected(true, true);
1200
 
        ensureItemVisible(lastItem());
1201
 
        handled = true;
1202
 
        break;
1203
 
    }
1204
 
 
1205
 
    case Key_Enter:
1206
 
    case Key_Return: 
1207
 
    {
1208
 
        if (d->currItem)
1209
 
        {
1210
 
            emit signalReturnPressed(d->currItem);
1211
 
            handled = true;
1212
 
        }
1213
 
        break;
1214
 
    }
1215
 
 
1216
 
    case Key_Right: 
1217
 
    {
1218
 
        IconItem *item = 0;
1219
 
        
1220
 
        if (d->currItem)
1221
 
        {
1222
 
            if (d->currItem->nextItem())
1223
 
            {
1224
 
                if (e->state() & Qt::ControlButton)
1225
 
                {
1226
 
                    IconItem* tmp = d->currItem;
1227
 
                    d->currItem   = d->currItem->nextItem();
1228
 
                    d->anchorItem = d->currItem;
1229
 
                    tmp->repaint();
1230
 
                    d->currItem->repaint();
1231
 
 
1232
 
                    item = d->currItem;
1233
 
                }
1234
 
                else if (e->state() & Qt::ShiftButton)
1235
 
                {
1236
 
                    IconItem* tmp = d->currItem;
1237
 
                    d->currItem   = d->currItem->nextItem();
1238
 
                    tmp->repaint();
1239
 
 
1240
 
                    // if the anchor is behind us, move forward preserving
1241
 
                    // the previously selected item. otherwise unselect the
1242
 
                    // previously selected item
1243
 
                    if (!anchorIsBehind())
1244
 
                        tmp->setSelected(false, false);
1245
 
 
1246
 
                    d->currItem->setSelected(true, false);
1247
 
                    
1248
 
                    item = d->currItem;
1249
 
                }
1250
 
                else
1251
 
                {
1252
 
                    IconItem* tmp = d->currItem;
1253
 
                    d->currItem   = d->currItem->nextItem();
1254
 
                    d->anchorItem = d->currItem;
1255
 
                    d->currItem->setSelected(true, true);
1256
 
                    tmp->repaint();
1257
 
                    
1258
 
                    item = d->currItem;
1259
 
                }
1260
 
            }
1261
 
        }
1262
 
        else
1263
 
        {
1264
 
            d->currItem   = firstItem();
1265
 
            d->anchorItem = d->currItem;
1266
 
            d->currItem->setSelected(true, true);
1267
 
            item = d->currItem;
1268
 
        }
1269
 
 
1270
 
        ensureItemVisible(item);
1271
 
        handled = true;
1272
 
        break;
1273
 
    }
1274
 
 
1275
 
    case Key_Left: 
1276
 
    {
1277
 
        IconItem *item = 0;
1278
 
        
1279
 
        if (d->currItem)
1280
 
        {
1281
 
            if (d->currItem->prevItem())
1282
 
            {
1283
 
                if (e->state() & Qt::ControlButton)
1284
 
                {
1285
 
                    IconItem* tmp = d->currItem;
1286
 
                    d->currItem   = d->currItem->prevItem();
1287
 
                    d->anchorItem = d->currItem;
1288
 
                    tmp->repaint();
1289
 
                    d->currItem->repaint();
1290
 
 
1291
 
                    item = d->currItem;
1292
 
                }
1293
 
                else if (e->state() & Qt::ShiftButton)
1294
 
                {
1295
 
                    IconItem* tmp = d->currItem;
1296
 
                    d->currItem   = d->currItem->prevItem();
1297
 
                    tmp->repaint();
1298
 
 
1299
 
                    // if the anchor is ahead of us, move forward preserving
1300
 
                    // the previously selected item. otherwise unselect the
1301
 
                    // previously selected item
1302
 
                    if (anchorIsBehind())
1303
 
                        tmp->setSelected(false, false);
1304
 
 
1305
 
                    d->currItem->setSelected(true, false);
1306
 
                    
1307
 
                    item = d->currItem;
1308
 
                }
1309
 
                else
1310
 
                {
1311
 
                    IconItem* tmp = d->currItem;
1312
 
                    d->currItem   = d->currItem->prevItem();
1313
 
                    d->anchorItem = d->currItem;
1314
 
                    d->currItem->setSelected(true, true);
1315
 
                    tmp->repaint();
1316
 
                    
1317
 
                    item = d->currItem;
1318
 
                }
1319
 
            }
1320
 
        }
1321
 
        else
1322
 
        {
1323
 
            d->currItem   = firstItem();
1324
 
            d->anchorItem = d->currItem;
1325
 
            d->currItem->setSelected(true, true);
1326
 
            item = d->currItem;
1327
 
        }
1328
 
 
1329
 
        ensureItemVisible(item);
1330
 
        handled = true;
1331
 
        break;
1332
 
    }
1333
 
 
1334
 
    case Key_Up:
1335
 
    {
1336
 
        IconItem *item = 0;
1337
 
        
1338
 
        if (d->currItem)
1339
 
        {
1340
 
            int x = d->currItem->x() + itemRect().width()/2;
1341
 
            int y = d->currItem->y() - d->spacing*2;
1342
 
 
1343
 
            IconItem *it = 0;
1344
 
 
1345
 
            while (!it && y > 0)
1346
 
            {
1347
 
                it  = findItem(QPoint(x,y));
1348
 
                y  -= d->spacing * 2;
1349
 
            }
1350
 
 
1351
 
            if (it)            
1352
 
            {
1353
 
                if (e->state() & Qt::ControlButton)
1354
 
                {
1355
 
                    IconItem* tmp = d->currItem;
1356
 
                    d->currItem   = it;
1357
 
                    d->anchorItem = it;
1358
 
                    tmp->repaint();
1359
 
                    d->currItem->repaint();
1360
 
 
1361
 
                    item = d->currItem;
1362
 
                }
1363
 
                else if (e->state() & Qt::ShiftButton)
1364
 
                {
1365
 
                    IconItem* tmp = d->currItem;
1366
 
                    d->currItem   = it;
1367
 
                    tmp->repaint();
1368
 
 
1369
 
                    clearSelection();
1370
 
                    if (anchorIsBehind())
1371
 
                    {
1372
 
                        for (IconItem* i = d->currItem; i; i = i->prevItem())
1373
 
                        {
1374
 
                            i->setSelected(true, false);
1375
 
                            if (i == d->anchorItem)
1376
 
                                break;
1377
 
                        }
1378
 
                    }
1379
 
                    else
1380
 
                    {
1381
 
                        for (IconItem* i = d->currItem; i; i = i->nextItem())
1382
 
                        {
1383
 
                            i->setSelected(true, false);
1384
 
                            if (i == d->anchorItem)
1385
 
                                break;
1386
 
                        }
1387
 
                    }
1388
 
 
1389
 
                    item = d->currItem; 
1390
 
                }
1391
 
                else
1392
 
                {
1393
 
                    IconItem* tmp = d->currItem;
1394
 
                    d->currItem   = it;
1395
 
                    d->anchorItem = it;
1396
 
                    d->currItem->setSelected(true, true);
1397
 
                    tmp->repaint();
1398
 
                    
1399
 
                    item = d->currItem;
1400
 
                }
1401
 
            }
1402
 
        }
1403
 
        else
1404
 
        {
1405
 
            d->currItem   = firstItem();
1406
 
            d->anchorItem = d->currItem;
1407
 
            d->currItem->setSelected(true, true);
1408
 
            item = d->currItem;
1409
 
        }
1410
 
 
1411
 
        ensureItemVisible(item);
1412
 
        handled = true;
1413
 
        break;
1414
 
    }
1415
 
 
1416
 
    case Key_Down:
1417
 
    {
1418
 
        IconItem *item = 0;
1419
 
        
1420
 
        if (d->currItem)
1421
 
        {
1422
 
            int x = d->currItem->x() + itemRect().width()/2;
1423
 
            int y = d->currItem->y() + itemRect().height() + d->spacing*2;
1424
 
 
1425
 
            IconItem *it = 0;
1426
 
 
1427
 
            while (!it && y < contentsHeight())
1428
 
            {
1429
 
                it  = findItem(QPoint(x,y));
1430
 
                y  += d->spacing * 2;
1431
 
            }
1432
 
 
1433
 
            if (it)            
1434
 
            {
1435
 
                if (e->state() & Qt::ControlButton)
1436
 
                {
1437
 
                    IconItem* tmp = d->currItem;
1438
 
                    d->currItem   = it;
1439
 
                    d->anchorItem = it;
1440
 
                    tmp->repaint();
1441
 
                    d->currItem->repaint();
1442
 
 
1443
 
                    item = d->currItem;
1444
 
                }
1445
 
                else if (e->state() & Qt::ShiftButton)
1446
 
                {
1447
 
                    IconItem* tmp = d->currItem;
1448
 
                    d->currItem   = it;
1449
 
                    tmp->repaint();
1450
 
 
1451
 
                    clearSelection();
1452
 
                    if (anchorIsBehind())
1453
 
                    {
1454
 
                        for (IconItem* i = d->currItem; i; i = i->prevItem())
1455
 
                        {
1456
 
                            i->setSelected(true, false);
1457
 
                            if (i == d->anchorItem)
1458
 
                                break;
1459
 
                        }
1460
 
                    }
1461
 
                    else
1462
 
                    {
1463
 
                        for (IconItem* i = d->currItem; i; i = i->nextItem())
1464
 
                        {
1465
 
                            i->setSelected(true, false);
1466
 
                            if (i == d->anchorItem)
1467
 
                                break;
1468
 
                        }
1469
 
                    }
1470
 
 
1471
 
                    item = d->currItem; 
1472
 
                }
1473
 
                else
1474
 
                {
1475
 
                    IconItem* tmp = d->currItem;
1476
 
                    d->currItem   = it;
1477
 
                    d->anchorItem = it;
1478
 
                    d->currItem->setSelected(true, true);
1479
 
                    tmp->repaint();
1480
 
                    
1481
 
                    item = d->currItem;
1482
 
                }
1483
 
            }
1484
 
        }
1485
 
        else
1486
 
        {
1487
 
            d->currItem   = firstItem();
1488
 
            d->anchorItem = d->currItem;
1489
 
            d->currItem->setSelected(true, true);
1490
 
            item = d->currItem;
1491
 
        }
1492
 
 
1493
 
        ensureItemVisible(item);
1494
 
        handled = true;
1495
 
        break;
1496
 
    }
1497
 
 
1498
 
    case Key_Next: 
1499
 
    {
1500
 
        IconItem *item = 0;
1501
 
 
1502
 
        if (d->currItem)
1503
 
        {
1504
 
            QRect r( 0, d->currItem->y() + visibleHeight(),
1505
 
                     contentsWidth(), visibleHeight() );
1506
 
            IconItem *ni = findFirstVisibleItem(r);
1507
 
 
1508
 
            if (!ni) 
1509
 
            {
1510
 
                r = QRect( 0, d->currItem->y() + itemRect().height(),
1511
 
                           contentsWidth(), contentsHeight() );
1512
 
                ni = findLastVisibleItem( r );
1513
 
            }
1514
 
 
1515
 
            if (ni) 
1516
 
            {
1517
 
                IconItem* tmp = d->currItem;
1518
 
                d->currItem   = ni;
1519
 
                d->anchorItem = ni;
1520
 
                item          = ni;
1521
 
                tmp->repaint();
1522
 
                d->currItem->setSelected(true, true);
1523
 
            }
1524
 
        }
1525
 
        else
1526
 
        {
1527
 
            d->currItem   = firstItem();
1528
 
            d->anchorItem = d->currItem;
1529
 
            d->currItem->setSelected(true, true);
1530
 
            item = d->currItem;
1531
 
        }
1532
 
 
1533
 
        ensureItemVisible(item);
1534
 
        handled = true;
1535
 
        break;
1536
 
    }
1537
 
 
1538
 
    case Key_Prior: 
1539
 
    {
1540
 
        IconItem *item = 0;
1541
 
 
1542
 
        if (d->currItem)
1543
 
        {
1544
 
            QRect r(0, d->currItem->y() - visibleHeight(),
1545
 
                    contentsWidth(), visibleHeight() );
1546
 
 
1547
 
            IconItem *ni = findFirstVisibleItem(r);
1548
 
 
1549
 
            if (!ni) 
1550
 
            {
1551
 
                r = QRect( 0, 0, contentsWidth(), d->currItem->y() );
1552
 
                ni = findFirstVisibleItem( r );
1553
 
            }
1554
 
 
1555
 
            if (ni) 
1556
 
            {
1557
 
                IconItem* tmp = d->currItem;
1558
 
                d->currItem   = ni;
1559
 
                d->anchorItem = ni;
1560
 
                item          = ni;
1561
 
                tmp->repaint();
1562
 
                d->currItem->setSelected(true, true);
1563
 
            }
1564
 
        }
1565
 
        else
1566
 
        {
1567
 
            d->currItem   = firstItem();
1568
 
            d->anchorItem = d->currItem;
1569
 
            d->currItem->setSelected(true, true);
1570
 
            item = d->currItem;
1571
 
        }
1572
 
 
1573
 
        ensureItemVisible(item);
1574
 
        handled = true;
1575
 
        break;
1576
 
    }
1577
 
    
1578
 
    default:
1579
 
        break;
 
1302
    switch ( e->key() )
 
1303
    {
 
1304
        case Key_Home: 
 
1305
        {
 
1306
            IconItem* tmp = d->currItem;
 
1307
            d->currItem = firstItem();
 
1308
            d->anchorItem = d->currItem;
 
1309
            if (tmp)
 
1310
                tmp->repaint();
 
1311
    
 
1312
            firstItem()->setSelected(true, true);
 
1313
            ensureItemVisible(firstItem());
 
1314
            handled = true;
 
1315
            break;
 
1316
        }
 
1317
    
 
1318
        case Key_End: 
 
1319
        {
 
1320
            IconItem* tmp = d->currItem;
 
1321
            d->currItem   = lastItem();
 
1322
            d->anchorItem = d->currItem;
 
1323
            if (tmp)
 
1324
                tmp->repaint();
 
1325
    
 
1326
            lastItem()->setSelected(true, true);
 
1327
            ensureItemVisible(lastItem());
 
1328
            handled = true;
 
1329
            break;
 
1330
        }
 
1331
    
 
1332
        case Key_Enter:
 
1333
        case Key_Return: 
 
1334
        {
 
1335
            if (d->currItem)
 
1336
            {
 
1337
                emit signalReturnPressed(d->currItem);
 
1338
                handled = true;
 
1339
            }
 
1340
            break;
 
1341
        }
 
1342
 
 
1343
        case Key_Right: 
 
1344
        {
 
1345
            IconItem *item = 0;
 
1346
            
 
1347
            if (d->currItem)
 
1348
            {
 
1349
                if (d->currItem->nextItem())
 
1350
                {
 
1351
                    if (e->state() & Qt::ControlButton)
 
1352
                    {
 
1353
                        IconItem* tmp = d->currItem;
 
1354
                        d->currItem   = d->currItem->nextItem();
 
1355
                        d->anchorItem = d->currItem;
 
1356
                        tmp->repaint();
 
1357
                        d->currItem->repaint();
 
1358
    
 
1359
                        item = d->currItem;
 
1360
                    }
 
1361
                    else if (e->state() & Qt::ShiftButton)
 
1362
                    {
 
1363
                        IconItem* tmp = d->currItem;
 
1364
                        d->currItem   = d->currItem->nextItem();
 
1365
                        tmp->repaint();
 
1366
    
 
1367
                        // if the anchor is behind us, move forward preserving
 
1368
                        // the previously selected item. otherwise unselect the
 
1369
                        // previously selected item
 
1370
                        if (!anchorIsBehind())
 
1371
                            tmp->setSelected(false, false);
 
1372
    
 
1373
                        d->currItem->setSelected(true, false);
 
1374
                        
 
1375
                        item = d->currItem;
 
1376
                    }
 
1377
                    else
 
1378
                    {
 
1379
                        IconItem* tmp = d->currItem;
 
1380
                        d->currItem   = d->currItem->nextItem();
 
1381
                        d->anchorItem = d->currItem;
 
1382
                        d->currItem->setSelected(true, true);
 
1383
                        tmp->repaint();
 
1384
                        
 
1385
                        item = d->currItem;
 
1386
                    }
 
1387
                }
 
1388
            }
 
1389
            else
 
1390
            {
 
1391
                d->currItem   = firstItem();
 
1392
                d->anchorItem = d->currItem;
 
1393
                d->currItem->setSelected(true, true);
 
1394
                item = d->currItem;
 
1395
            }
 
1396
    
 
1397
            ensureItemVisible(item);
 
1398
            handled = true;
 
1399
            break;
 
1400
        }
 
1401
    
 
1402
        case Key_Left: 
 
1403
        {
 
1404
            IconItem *item = 0;
 
1405
            
 
1406
            if (d->currItem)
 
1407
            {
 
1408
                if (d->currItem->prevItem())
 
1409
                {
 
1410
                    if (e->state() & Qt::ControlButton)
 
1411
                    {
 
1412
                        IconItem* tmp = d->currItem;
 
1413
                        d->currItem   = d->currItem->prevItem();
 
1414
                        d->anchorItem = d->currItem;
 
1415
                        tmp->repaint();
 
1416
                        d->currItem->repaint();
 
1417
    
 
1418
                        item = d->currItem;
 
1419
                    }
 
1420
                    else if (e->state() & Qt::ShiftButton)
 
1421
                    {
 
1422
                        IconItem* tmp = d->currItem;
 
1423
                        d->currItem   = d->currItem->prevItem();
 
1424
                        tmp->repaint();
 
1425
    
 
1426
                        // if the anchor is ahead of us, move forward preserving
 
1427
                        // the previously selected item. otherwise unselect the
 
1428
                        // previously selected item
 
1429
                        if (anchorIsBehind())
 
1430
                            tmp->setSelected(false, false);
 
1431
    
 
1432
                        d->currItem->setSelected(true, false);
 
1433
                        
 
1434
                        item = d->currItem;
 
1435
                    }
 
1436
                    else
 
1437
                    {
 
1438
                        IconItem* tmp = d->currItem;
 
1439
                        d->currItem   = d->currItem->prevItem();
 
1440
                        d->anchorItem = d->currItem;
 
1441
                        d->currItem->setSelected(true, true);
 
1442
                        tmp->repaint();
 
1443
                        
 
1444
                        item = d->currItem;
 
1445
                    }
 
1446
                }
 
1447
            }
 
1448
            else
 
1449
            {
 
1450
                d->currItem   = firstItem();
 
1451
                d->anchorItem = d->currItem;
 
1452
                d->currItem->setSelected(true, true);
 
1453
                item = d->currItem;
 
1454
            }
 
1455
    
 
1456
            ensureItemVisible(item);
 
1457
            handled = true;
 
1458
            break;
 
1459
        }
 
1460
    
 
1461
        case Key_Up:
 
1462
        {
 
1463
            IconItem *item = 0;
 
1464
            
 
1465
            if (d->currItem)
 
1466
            {
 
1467
                int x = d->currItem->x() + itemRect().width()/2;
 
1468
                int y = d->currItem->y() - d->spacing*2;
 
1469
    
 
1470
                IconItem *it = 0;
 
1471
    
 
1472
                while (!it && y > 0)
 
1473
                {
 
1474
                    it  = findItem(QPoint(x,y));
 
1475
                    y  -= d->spacing * 2;
 
1476
                }
 
1477
    
 
1478
                if (it)            
 
1479
                {
 
1480
                    if (e->state() & Qt::ControlButton)
 
1481
                    {
 
1482
                        IconItem* tmp = d->currItem;
 
1483
                        d->currItem   = it;
 
1484
                        d->anchorItem = it;
 
1485
                        tmp->repaint();
 
1486
                        d->currItem->repaint();
 
1487
    
 
1488
                        item = d->currItem;
 
1489
                    }
 
1490
                    else if (e->state() & Qt::ShiftButton)
 
1491
                    {
 
1492
                        IconItem* tmp = d->currItem;
 
1493
                        d->currItem   = it;
 
1494
                        tmp->repaint();
 
1495
    
 
1496
                        clearSelection();
 
1497
                        if (anchorIsBehind())
 
1498
                        {
 
1499
                            for (IconItem* i = d->currItem; i; i = i->prevItem())
 
1500
                            {
 
1501
                                i->setSelected(true, false);
 
1502
                                if (i == d->anchorItem)
 
1503
                                    break;
 
1504
                            }
 
1505
                        }
 
1506
                        else
 
1507
                        {
 
1508
                            for (IconItem* i = d->currItem; i; i = i->nextItem())
 
1509
                            {
 
1510
                                i->setSelected(true, false);
 
1511
                                if (i == d->anchorItem)
 
1512
                                    break;
 
1513
                            }
 
1514
                        }
 
1515
    
 
1516
                        item = d->currItem; 
 
1517
                    }
 
1518
                    else
 
1519
                    {
 
1520
                        IconItem* tmp = d->currItem;
 
1521
                        d->currItem   = it;
 
1522
                        d->anchorItem = it;
 
1523
                        d->currItem->setSelected(true, true);
 
1524
                        tmp->repaint();
 
1525
                        
 
1526
                        item = d->currItem;
 
1527
                    }
 
1528
                }
 
1529
            }
 
1530
            else
 
1531
            {
 
1532
                d->currItem   = firstItem();
 
1533
                d->anchorItem = d->currItem;
 
1534
                d->currItem->setSelected(true, true);
 
1535
                item = d->currItem;
 
1536
            }
 
1537
    
 
1538
            ensureItemVisible(item);
 
1539
            handled = true;
 
1540
            break;
 
1541
        }
 
1542
    
 
1543
        case Key_Down:
 
1544
        {
 
1545
            IconItem *item = 0;
 
1546
            
 
1547
            if (d->currItem)
 
1548
            {
 
1549
                int x = d->currItem->x() + itemRect().width()/2;
 
1550
                int y = d->currItem->y() + itemRect().height() + d->spacing*2;
 
1551
    
 
1552
                IconItem *it = 0;
 
1553
    
 
1554
                while (!it && y < contentsHeight())
 
1555
                {
 
1556
                    it  = findItem(QPoint(x,y));
 
1557
                    y  += d->spacing * 2;
 
1558
                }
 
1559
    
 
1560
                if (it)            
 
1561
                {
 
1562
                    if (e->state() & Qt::ControlButton)
 
1563
                    {
 
1564
                        IconItem* tmp = d->currItem;
 
1565
                        d->currItem   = it;
 
1566
                        d->anchorItem = it;
 
1567
                        tmp->repaint();
 
1568
                        d->currItem->repaint();
 
1569
    
 
1570
                        item = d->currItem;
 
1571
                    }
 
1572
                    else if (e->state() & Qt::ShiftButton)
 
1573
                    {
 
1574
                        IconItem* tmp = d->currItem;
 
1575
                        d->currItem   = it;
 
1576
                        tmp->repaint();
 
1577
    
 
1578
                        clearSelection();
 
1579
                        if (anchorIsBehind())
 
1580
                        {
 
1581
                            for (IconItem* i = d->currItem; i; i = i->prevItem())
 
1582
                            {
 
1583
                                i->setSelected(true, false);
 
1584
                                if (i == d->anchorItem)
 
1585
                                    break;
 
1586
                            }
 
1587
                        }
 
1588
                        else
 
1589
                        {
 
1590
                            for (IconItem* i = d->currItem; i; i = i->nextItem())
 
1591
                            {
 
1592
                                i->setSelected(true, false);
 
1593
                                if (i == d->anchorItem)
 
1594
                                    break;
 
1595
                            }
 
1596
                        }
 
1597
    
 
1598
                        item = d->currItem; 
 
1599
                    }
 
1600
                    else
 
1601
                    {
 
1602
                        IconItem* tmp = d->currItem;
 
1603
                        d->currItem   = it;
 
1604
                        d->anchorItem = it;
 
1605
                        d->currItem->setSelected(true, true);
 
1606
                        tmp->repaint();
 
1607
                        
 
1608
                        item = d->currItem;
 
1609
                    }
 
1610
                }
 
1611
            }
 
1612
            else
 
1613
            {
 
1614
                d->currItem   = firstItem();
 
1615
                d->anchorItem = d->currItem;
 
1616
                d->currItem->setSelected(true, true);
 
1617
                item = d->currItem;
 
1618
            }
 
1619
    
 
1620
            ensureItemVisible(item);
 
1621
            handled = true;
 
1622
            break;
 
1623
        }
 
1624
    
 
1625
        case Key_Next: 
 
1626
        {
 
1627
            IconItem *item = 0;
 
1628
    
 
1629
            if (d->currItem)
 
1630
            {
 
1631
                QRect r( 0, d->currItem->y() + visibleHeight(),
 
1632
                        contentsWidth(), visibleHeight() );
 
1633
                IconItem *ni = findFirstVisibleItem(r, false);
 
1634
    
 
1635
                if (!ni) 
 
1636
                {
 
1637
                    r = QRect( 0, d->currItem->y() + itemRect().height(),
 
1638
                              contentsWidth(), contentsHeight() );
 
1639
                    ni = findLastVisibleItem(r, false);
 
1640
                }
 
1641
    
 
1642
                if (ni) 
 
1643
                {
 
1644
                    IconItem* tmp = d->currItem;
 
1645
                    d->currItem   = ni;
 
1646
                    d->anchorItem = ni;
 
1647
                    item          = ni;
 
1648
                    tmp->repaint();
 
1649
                    d->currItem->setSelected(true, true);
 
1650
                }
 
1651
            }
 
1652
            else
 
1653
            {
 
1654
                d->currItem   = firstItem();
 
1655
                d->anchorItem = d->currItem;
 
1656
                d->currItem->setSelected(true, true);
 
1657
                item = d->currItem;
 
1658
            }
 
1659
    
 
1660
            ensureItemVisible(item);
 
1661
            handled = true;
 
1662
            break;
 
1663
        }
 
1664
    
 
1665
        case Key_Prior: 
 
1666
        {
 
1667
            IconItem *item = 0;
 
1668
    
 
1669
            if (d->currItem)
 
1670
            {
 
1671
                QRect r(0, d->currItem->y() - visibleHeight(),
 
1672
                        contentsWidth(), visibleHeight() );
 
1673
    
 
1674
                IconItem *ni = findFirstVisibleItem(r, false);
 
1675
    
 
1676
                if (!ni) 
 
1677
                {
 
1678
                    r = QRect( 0, 0, contentsWidth(), d->currItem->y() );
 
1679
                    ni = findFirstVisibleItem(r, false);
 
1680
                }
 
1681
    
 
1682
                if (ni) 
 
1683
                {
 
1684
                    IconItem* tmp = d->currItem;
 
1685
                    d->currItem   = ni;
 
1686
                    d->anchorItem = ni;
 
1687
                    item          = ni;
 
1688
                    tmp->repaint();
 
1689
                    d->currItem->setSelected(true, true);
 
1690
                }
 
1691
            }
 
1692
            else
 
1693
            {
 
1694
                d->currItem   = firstItem();
 
1695
                d->anchorItem = d->currItem;
 
1696
                d->currItem->setSelected(true, true);
 
1697
                item = d->currItem;
 
1698
            }
 
1699
    
 
1700
            ensureItemVisible(item);
 
1701
            handled = true;
 
1702
            break;
 
1703
        }
 
1704
 
 
1705
        // Key_Space is used as a global shortcut in DigikamApp.
 
1706
        // Ctrl+Space comes through, Shift+Space is filtered out.
 
1707
        case Key_Space:
 
1708
        {
 
1709
            if (d->currItem)
 
1710
            {
 
1711
                if ( (e->state() & Qt::ControlButton) || (e->state() & Qt::ShiftButton) )
 
1712
                {
 
1713
                    d->currItem->setSelected(!d->currItem->isSelected(), false);
 
1714
                }
 
1715
                else
 
1716
                {
 
1717
                    if (!d->currItem->isSelected())
 
1718
                        d->currItem->setSelected(true, true);
 
1719
                }
 
1720
                handled = true;
 
1721
            }
 
1722
            break;
 
1723
        }
 
1724
 
 
1725
        case Key_Menu:
 
1726
        {
 
1727
            if (d->currItem)
 
1728
            {
 
1729
                if (!d->currItem->isSelected())
 
1730
                    d->currItem->setSelected(true, false);
 
1731
 
 
1732
                ensureItemVisible(d->currItem);
 
1733
 
 
1734
                QRect r(itemRect());
 
1735
                int w = r.width();
 
1736
                int h = r.height();
 
1737
                QPoint p(d->currItem->x() + w / 2, d->currItem->y() + h / 2);
 
1738
 
 
1739
                emit signalRightButtonClicked(d->currItem, mapToGlobal(contentsToViewport(p)));
 
1740
            }
 
1741
            break;
 
1742
        }
 
1743
 
 
1744
        default:
 
1745
            break;
1580
1746
    }
1581
1747
 
1582
1748
    if (!handled)
1589
1755
        viewport()->update();
1590
1756
        d->toolTipItem = 0;
1591
1757
        d->toolTipTimer->stop();
1592
 
        slotToolTip();        
 
1758
        slotToolTip();
1593
1759
    }
1594
1760
}
1595
1761
 
1610
1776
 
1611
1777
void IconView::startDrag()
1612
1778
{
1613
 
    
1614
1779
}
1615
1780
 
1616
1781
void IconView::ensureItemVisible(IconItem *item)
1634
1799
    }
1635
1800
}
1636
1801
 
1637
 
IconItem* IconView::findFirstVisibleItem(const QRect& r) const
 
1802
IconItem* IconView::findFirstVisibleItem(bool useThumbnailRect) const
 
1803
{
 
1804
    QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
 
1805
    return findFirstVisibleItem(r, useThumbnailRect);
 
1806
}
 
1807
 
 
1808
IconItem* IconView::findLastVisibleItem(bool useThumbnailRect) const
 
1809
{
 
1810
    QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
 
1811
    return findLastVisibleItem(r, useThumbnailRect);
 
1812
}
 
1813
 
 
1814
IconItem* IconView::findFirstVisibleItem(const QRect& r, bool useThumbnailRect) const
1638
1815
{
1639
1816
    IconViewPriv::ItemContainer *c = d->firstContainer;
1640
1817
    bool alreadyIntersected = false;
1648
1825
                 it != c->items.end(); ++it)
1649
1826
            {
1650
1827
                IconItem *item = *it;
1651
 
                
1652
 
                if ( r.intersects( item->rect() ) )
 
1828
 
 
1829
                // if useThumbnailRect, we only check for the clickToOpenRect, which is the thumbnail,
 
1830
                // otherwise, we take the whole item rect
 
1831
                if ( r.intersects( useThumbnailRect ? item->clickToOpenRect() : item->rect() ) )
1653
1832
                {
1654
1833
                    if ( !i )
1655
1834
                    {
1678
1857
    return i;
1679
1858
}
1680
1859
 
1681
 
IconItem* IconView::findLastVisibleItem(const QRect& r) const
 
1860
IconItem* IconView::findLastVisibleItem(const QRect& r, bool useThumbnailRect) const
1682
1861
{
1683
1862
    IconViewPriv::ItemContainer *c = d->firstContainer;
1684
1863
    IconItem *i = 0;
1685
1864
    bool alreadyIntersected = false;
1686
1865
    for ( ; c; c = c->next ) 
1687
1866
    {
1688
 
        if ( c->rect.intersects( r ) ) 
 
1867
        if ( c->rect.intersects( r ) )
1689
1868
        {
1690
1869
            alreadyIntersected = true;
1691
1870
            for (QValueList<IconItem*>::iterator it = c->items.begin();
1692
1871
                 it != c->items.end(); ++it)
1693
1872
            {
1694
1873
                IconItem *item = *it;
1695
 
                
1696
 
                if ( r.intersects( item->rect() ) ) 
 
1874
 
 
1875
                if ( r.intersects( useThumbnailRect ? item->clickToOpenRect() : item->rect() ) ) 
1697
1876
                {
1698
 
                    if ( !i ) {
 
1877
                    if ( !i ) 
 
1878
                    {
1699
1879
                        i = item;
1700
1880
                    }
1701
 
                    else {
 
1881
                    else 
 
1882
                    {
1702
1883
                        QRect r2 = item->rect();
1703
1884
                        QRect r3 = i->rect();
1704
1885
                        if ( r2.y() > r3.y() )
1765
1946
    IconItem* prevCurrItem = d->currItem;
1766
1947
    d->currItem   = item;
1767
1948
    d->anchorItem = item;
 
1949
    
1768
1950
    if (prevCurrItem)
1769
1951
        prevCurrItem->repaint();
1770
1952
 
1772
1954
    emit signalDoubleClicked(item);
1773
1955
}
1774
1956
 
1775
 
#include "iconview.moc"
 
1957
int IconView::cmpItems(const void *n1, const void *n2)
 
1958
{
 
1959
    if ( !n1 || !n2 )
 
1960
        return 0;
 
1961
 
 
1962
    IconViewPriv::SortableItem *i1 = (IconViewPriv::SortableItem *)n1;
 
1963
    IconViewPriv::SortableItem *i2 = (IconViewPriv::SortableItem *)n2;
 
1964
 
 
1965
    return i1->group->compare( i2->group );
 
1966
}
 
1967
 
 
1968
}  // namespace Digikam
 
1969