~ubuntu-branches/ubuntu/trusty/digikam/trusty

« back to all changes in this revision

Viewing changes to core/utilities/cameragui/q3support/iconview.cpp

  • Committer: Package Import Robot
  • Author(s): Rohan Garg
  • Date: 2012-11-26 18:24:20 UTC
  • mfrom: (1.9.1) (3.1.23 experimental)
  • Revision ID: package-import@ubuntu.com-20121126182420-qoy6z0nx4ai0wzcl
Tags: 4:3.0.0~beta3-0ubuntu1
* New upstream release
  - Add build-deps :  libhupnp-dev, libqtgstreamer-dev, libmagickcore-dev
* Merge from debian, remaining changes:
  - Make sure libqt4-opengl-dev, libgl1-mesa-dev and libglu1-mesa-dev only
    install on i386,amd64 and powerpc
  - Depend on libtiff-dev instead of libtiff4-dev
  - Drop digikam breaks/replaces kipi-plugins-common since we're past the
    LTS release now
  - digikam to recommend mplayerthumbs | ffmpegthumbs. We currently only
    have latter in the archives, even though former is also supposed to
    be part of kdemultimedia. (LP: #890059)
  - kipi-plugins to recommend www-browser rather than konqueror directly
    since 2.8 no direct usage of konqueror is present in the flickr
    plugin anymore (LP: #1011211)
  - Keep kubuntu_mysqld_executable_name.diff
  - Don't install libkipi translations
  - Keep deps on libcv-dev, libcvaux-dev
  - Keep split packaging of libraries
  - Replace icons from KDE 3 time in debian/xpm.d/*.xpm with the new
    versions (LP: #658047)
* Update debian/not-installed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* ============================================================
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-2011 by Gilles Caulier <caulier dot gilles at gmail dot com>
11
 
 *
12
 
 * This program is free software; you can redistribute it
13
 
 * and/or modify it under the terms of the GNU General
14
 
 * Public License as published by the Free Software Foundation;
15
 
 * either version 2, or (at your option)
16
 
 * any later version.
17
 
 *
18
 
 * This program is distributed in the hope that it will be useful,
19
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 
 * GNU General Public License for more details.
22
 
 *
23
 
 * ============================================================ */
24
 
 
25
 
#define RECT_EXTENSION 300
26
 
 
27
 
#include "iconview.moc"
28
 
 
29
 
// C++ includes
30
 
 
31
 
#include <climits>
32
 
#include <cstdlib>
33
 
 
34
 
// Qt includes
35
 
 
36
 
#include <QCache>
37
 
#include <QList>
38
 
#include <QSet>
39
 
#include <QTimer>
40
 
#include <QPainter>
41
 
#include <QStyle>
42
 
#include <QApplication>
43
 
#include <QPaintEvent>
44
 
#include <QDropEvent>
45
 
#include <QMouseEvent>
46
 
#include <QStyleOption>
47
 
#include <QRubberBand>
48
 
 
49
 
// KDE includes
50
 
 
51
 
 
52
 
#include <kcursor.h>
53
 
#include <kiconloader.h>
54
 
#include <kglobalsettings.h>
55
 
 
56
 
// Local includes
57
 
 
58
 
#include "ratingwidget.h"
59
 
#include "drubberband.h"
60
 
#include "thumbbar.h"
61
 
#include "iconitem.h"
62
 
#include "icongroupitem.h"
63
 
#include "albumsettings.h"
64
 
 
65
 
namespace Digikam
66
 
{
67
 
 
68
 
class IconView::IconViewPriv
69
 
{
70
 
public:
71
 
 
72
 
    IconViewPriv()
73
 
    {
74
 
        firstGroup               = 0;
75
 
        lastGroup                = 0;
76
 
        currItem                 = 0;
77
 
        highlightedItem          = 0;
78
 
        anchorItem               = 0;
79
 
        clearing                 = false;
80
 
        spacing                  = 10;
81
 
        ratingWidget             = 0;
82
 
        ratingItem               = 0;
83
 
 
84
 
        rubber                   = 0;
85
 
        dragging                 = false;
86
 
        pressedMoved             = false;
87
 
 
88
 
        firstContainer           = 0;
89
 
        lastContainer            = 0;
90
 
 
91
 
        showTips                 = false;
92
 
        toolTipItem              = 0;
93
 
        toolTipTimer             = 0;
94
 
        rearrangeTimer           = 0;
95
 
        rearrangeTimerInterval   = 0;
96
 
        storedVisibleItem        = 0;
97
 
        needEmitSelectionChanged = false;
98
 
 
99
 
        thumbnailBorderCache.setMaxCost(10);
100
 
 
101
 
        selectPix   = SmallIcon("list-add");
102
 
        deselectPix = SmallIcon("list-remove");
103
 
    }
104
 
 
105
 
    bool                      clearing;
106
 
    bool                      showTips;
107
 
    bool                      pressedMoved;
108
 
    bool                      dragging;
109
 
    bool                      needEmitSelectionChanged; // store for slotRearrange
110
 
 
111
 
    int                       rearrangeTimerInterval;
112
 
    int                       spacing;
113
 
 
114
 
    QSet<IconItem*>           selectedItems;
115
 
    QSet<IconItem*>           prevSelectedItems;
116
 
 
117
 
    QPixmap                   selectPix;
118
 
    QPixmap                   deselectPix;
119
 
 
120
 
    QCache<QString, QPixmap>  thumbnailBorderCache;
121
 
 
122
 
    DRubberBand*              rubber;
123
 
 
124
 
    QPoint                    dragStartPos;
125
 
 
126
 
    QTimer*                   rearrangeTimer;
127
 
    QTimer*                   toolTipTimer;
128
 
 
129
 
    IconItem*                 toolTipItem;
130
 
    IconItem*                 currItem;
131
 
    IconItem*                 anchorItem;
132
 
    IconItem*                 storedVisibleItem; // store position for slotRearrange
133
 
    IconItem*                 highlightedItem;
134
 
    IconItem*                 ratingItem;
135
 
 
136
 
    IconGroupItem*            firstGroup;
137
 
    IconGroupItem*            lastGroup;
138
 
 
139
 
    RatingWidget*             ratingWidget;
140
 
 
141
 
    struct ItemContainer
142
 
    {
143
 
        ItemContainer(ItemContainer* p, ItemContainer* n, const QRect& r)
144
 
            : prev(p), next(n), rect(r)
145
 
        {
146
 
            if (prev)
147
 
            {
148
 
                prev->next = this;
149
 
            }
150
 
 
151
 
            if (next)
152
 
            {
153
 
                next->prev = this;
154
 
            }
155
 
        }
156
 
 
157
 
        ItemContainer*        prev, *next;
158
 
        QRect                 rect;
159
 
        QList<IconItem*>      items;
160
 
    } *firstContainer, *lastContainer;
161
 
 
162
 
    struct SortableItem
163
 
    {
164
 
        IconGroupItem* group;
165
 
    };
166
 
};
167
 
 
168
 
// -----------------------------------------------------------------------
169
 
 
170
 
IconView::IconView(QWidget* parent, const char* name)
171
 
    : Q3ScrollView(parent), d(new IconViewPriv)
172
 
{
173
 
    setObjectName(name);
174
 
    setWindowFlags(Qt::WStaticContents | Qt::WNoAutoErase);
175
 
 
176
 
    viewport()->setFocusProxy(this);
177
 
    viewport()->setFocusPolicy(Qt::WheelFocus);
178
 
    viewport()->setMouseTracking(true);
179
 
 
180
 
    d->rearrangeTimer = new QTimer(this);
181
 
    d->toolTipTimer   = new QTimer(this);
182
 
    d->rubber         = new DRubberBand(this);
183
 
    d->ratingWidget   = new RatingWidget(viewport());
184
 
    d->ratingWidget->setTracking(false);
185
 
    d->ratingWidget->hide();
186
 
 
187
 
    connect(d->rearrangeTimer, SIGNAL(timeout()),
188
 
            this, SLOT(slotRearrange()));
189
 
 
190
 
    connect(d->toolTipTimer, SIGNAL(timeout()),
191
 
            this, SLOT(slotToolTip()));
192
 
 
193
 
    connect(AlbumSettings::instance(), SIGNAL(setupChanged()),
194
 
            this, SLOT(slotIconViewFontChanged()));
195
 
 
196
 
    connect(d->ratingWidget, SIGNAL(signalRatingChanged(int)),
197
 
            this, SLOT(slotEditRatingFromItem(int)));
198
 
 
199
 
    slotIconViewFontChanged();
200
 
    setEnableToolTips(true);
201
 
}
202
 
 
203
 
IconView::~IconView()
204
 
{
205
 
    clear(false);
206
 
 
207
 
    delete d->rearrangeTimer;
208
 
    delete d->toolTipTimer;
209
 
    delete d->rubber;
210
 
    delete d;
211
 
}
212
 
 
213
 
IconGroupItem* IconView::firstGroup() const
214
 
{
215
 
    return d->firstGroup;
216
 
}
217
 
 
218
 
IconGroupItem* IconView::lastGroup() const
219
 
{
220
 
    return d->lastGroup;
221
 
}
222
 
 
223
 
IconItem* IconView::firstItem() const
224
 
{
225
 
    if (!d->firstGroup)
226
 
    {
227
 
        return 0;
228
 
    }
229
 
 
230
 
    return d->firstGroup->firstItem();
231
 
}
232
 
 
233
 
IconItem* IconView::lastItem() const
234
 
{
235
 
    if (!d->lastGroup)
236
 
    {
237
 
        return 0;
238
 
    }
239
 
 
240
 
    return d->lastGroup->lastItem();
241
 
}
242
 
 
243
 
IconItem* IconView::currentItem() const
244
 
{
245
 
    return d->currItem;
246
 
}
247
 
 
248
 
void IconView::setCurrentItem(IconItem* item)
249
 
{
250
 
    d->currItem   = item;
251
 
    d->anchorItem = d->currItem;
252
 
 
253
 
    if (d->currItem)
254
 
    {
255
 
        d->currItem->setSelected(true, true);
256
 
        ensureItemVisible(d->currItem);
257
 
    }
258
 
}
259
 
 
260
 
IconItem* IconView::ratingItem() const
261
 
{
262
 
    return d->ratingItem;
263
 
}
264
 
 
265
 
IconItem* IconView::findItem(const QPoint& pos)
266
 
{
267
 
    IconViewPriv::ItemContainer* c = d->firstContainer;
268
 
 
269
 
    for (; c; c = c->next)
270
 
    {
271
 
        if (c->rect.contains(pos))
272
 
        {
273
 
            foreach(IconItem* item, c->items)
274
 
            {
275
 
                if (item->rect().contains(pos))
276
 
                {
277
 
                    return item;
278
 
                }
279
 
            }
280
 
        }
281
 
    }
282
 
 
283
 
    return 0;
284
 
}
285
 
 
286
 
IconGroupItem* IconView::findGroup(const QPoint& pos)
287
 
{
288
 
    QPoint p = viewportToContents(viewport()->mapFromGlobal(pos));
289
 
 
290
 
    for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
291
 
    {
292
 
        QRect rect = group->rect();
293
 
        int bottom;
294
 
 
295
 
        if (group == d->lastGroup)
296
 
        {
297
 
            bottom = contentsHeight();
298
 
        }
299
 
        else
300
 
        {
301
 
            bottom = group->nextGroup()->rect().top();
302
 
        }
303
 
 
304
 
        rect.setBottom(bottom);
305
 
 
306
 
        if (rect.contains(p))
307
 
        {
308
 
            return group;
309
 
        }
310
 
    }
311
 
 
312
 
    return 0;
313
 
}
314
 
 
315
 
int IconView::count() const
316
 
{
317
 
    int c = 0;
318
 
 
319
 
    for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
320
 
    {
321
 
        c += group->count();
322
 
    }
323
 
 
324
 
    return c;
325
 
}
326
 
 
327
 
 
328
 
int IconView::countSelected() const
329
 
{
330
 
    int c = 0;
331
 
 
332
 
    for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
333
 
    {
334
 
        for (IconItem* it = group->firstItem(); it; it = it->nextItem())
335
 
            if (it->isSelected())
336
 
            {
337
 
                ++c;
338
 
            }
339
 
    }
340
 
 
341
 
    return c;
342
 
}
343
 
 
344
 
int IconView::groupCount() const
345
 
{
346
 
    int c = 0;
347
 
 
348
 
    for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
349
 
    {
350
 
        ++c;
351
 
    }
352
 
 
353
 
    return c;
354
 
}
355
 
 
356
 
void IconView::clear(bool update)
357
 
{
358
 
    d->clearing        = true;
359
 
    d->highlightedItem = 0;
360
 
    d->toolTipItem     = 0;
361
 
    d->toolTipTimer->stop();
362
 
    slotToolTip();
363
 
 
364
 
    if (d->ratingItem)
365
 
    {
366
 
        d->ratingItem->setEditRating(false);
367
 
        d->ratingItem = 0;
368
 
        unsetCursor();
369
 
        d->ratingWidget->hide();
370
 
    }
371
 
 
372
 
    deleteContainers();
373
 
 
374
 
    d->selectedItems.clear();
375
 
 
376
 
    IconGroupItem* group = d->firstGroup;
377
 
 
378
 
    while (group)
379
 
    {
380
 
        IconGroupItem* tmp = group->m_next;
381
 
        delete group;
382
 
        group = tmp;
383
 
    }
384
 
 
385
 
    d->firstGroup = 0;
386
 
    d->lastGroup  = 0;
387
 
    d->currItem   = 0;
388
 
    d->anchorItem = 0;
389
 
 
390
 
    viewport()->setUpdatesEnabled(false);
391
 
    resizeContents(0, 0);
392
 
    setContentsPos(0, 0);
393
 
    viewport()->setUpdatesEnabled(true);
394
 
 
395
 
    if (update)
396
 
    {
397
 
        updateContents();
398
 
    }
399
 
 
400
 
    d->clearing = false;
401
 
 
402
 
    emit signalSelectionChanged();
403
 
}
404
 
 
405
 
void IconView::clearSelection()
406
 
{
407
 
    bool wasBlocked = signalsBlocked();
408
 
 
409
 
    if (!wasBlocked)
410
 
    {
411
 
        blockSignals(true);
412
 
    }
413
 
 
414
 
    QSet<IconItem*> selItems = d->selectedItems;
415
 
    foreach(IconItem* item, selItems)
416
 
    {
417
 
        item->setSelected(false, false);
418
 
    }
419
 
 
420
 
    d->selectedItems.clear();
421
 
 
422
 
    if (!wasBlocked)
423
 
    {
424
 
        blockSignals(false);
425
 
    }
426
 
 
427
 
    emit signalSelectionChanged();
428
 
}
429
 
 
430
 
void IconView::selectAll()
431
 
{
432
 
    bool wasBlocked = signalsBlocked();
433
 
 
434
 
    if (!wasBlocked)
435
 
    {
436
 
        blockSignals(true);
437
 
    }
438
 
 
439
 
    for (IconItem* item = firstItem(); item; item = item->nextItem())
440
 
    {
441
 
        if (!item->isSelected())
442
 
        {
443
 
            item->setSelected(true, false);
444
 
        }
445
 
    }
446
 
 
447
 
    if (!wasBlocked)
448
 
    {
449
 
        blockSignals(false);
450
 
    }
451
 
 
452
 
    emit signalSelectionChanged();
453
 
}
454
 
 
455
 
void IconView::invertSelection()
456
 
{
457
 
    bool wasBlocked = signalsBlocked();
458
 
 
459
 
    if (!wasBlocked)
460
 
    {
461
 
        blockSignals(true);
462
 
    }
463
 
 
464
 
    for (IconItem* item = firstItem(); item; item = item->nextItem())
465
 
    {
466
 
        if (!item->isSelected())
467
 
        {
468
 
            item->setSelected(true, false);
469
 
        }
470
 
        else
471
 
        {
472
 
            item->setSelected(false, false);
473
 
        }
474
 
    }
475
 
 
476
 
    if (!wasBlocked)
477
 
    {
478
 
        blockSignals(false);
479
 
    }
480
 
 
481
 
    emit signalSelectionChanged();
482
 
}
483
 
 
484
 
void IconView::selectItem(IconItem* item, bool select)
485
 
{
486
 
    if (!item)
487
 
    {
488
 
        return;
489
 
    }
490
 
 
491
 
    if (select)
492
 
    {
493
 
        d->selectedItems.insert(item);
494
 
    }
495
 
    else
496
 
    {
497
 
        d->selectedItems.remove(item);
498
 
    }
499
 
 
500
 
    emit signalSelectionChanged();
501
 
}
502
 
 
503
 
void IconView::setStoredVisibleItem(IconItem* item)
504
 
{
505
 
    d->storedVisibleItem = item;
506
 
}
507
 
 
508
 
void IconView::insertGroup(IconGroupItem* group)
509
 
{
510
 
    if (!group)
511
 
    {
512
 
        return;
513
 
    }
514
 
 
515
 
    if (!d->firstGroup)
516
 
    {
517
 
        d->firstGroup = group;
518
 
        d->lastGroup  = group;
519
 
        group->m_prev = 0;
520
 
        group->m_next = 0;
521
 
    }
522
 
    else
523
 
    {
524
 
        d->lastGroup->m_next = group;
525
 
        group->m_prev        = d->lastGroup;
526
 
        group->m_next        = 0;
527
 
        d->lastGroup         = group;
528
 
    }
529
 
 
530
 
    d->storedVisibleItem = findFirstVisibleItem();
531
 
    startRearrangeTimer();
532
 
}
533
 
 
534
 
void IconView::takeGroup(IconGroupItem* group)
535
 
{
536
 
    if (!group)
537
 
    {
538
 
        return;
539
 
    }
540
 
 
541
 
    // this is only to find an alternative visible item if all visible items
542
 
    // are removed
543
 
    IconGroupItem* alternativeVisibleGroup = 0;
544
 
    d->storedVisibleItem = 0;
545
 
 
546
 
    if (group == d->firstGroup)
547
 
    {
548
 
        d->firstGroup = d->firstGroup->m_next;
549
 
 
550
 
        if (d->firstGroup)
551
 
        {
552
 
            d->firstGroup->m_prev = 0;
553
 
        }
554
 
        else
555
 
        {
556
 
            d->firstGroup = d->lastGroup = 0;
557
 
        }
558
 
 
559
 
        alternativeVisibleGroup = d->firstGroup;
560
 
    }
561
 
    else if (group == d->lastGroup)
562
 
    {
563
 
        d->lastGroup = d->lastGroup->m_prev;
564
 
 
565
 
        if (d->lastGroup)
566
 
        {
567
 
            d->lastGroup->m_next = 0;
568
 
        }
569
 
        else
570
 
        {
571
 
            d->firstGroup = d->lastGroup = 0;
572
 
        }
573
 
 
574
 
        alternativeVisibleGroup = d->lastGroup->m_prev;
575
 
    }
576
 
    else
577
 
    {
578
 
        IconGroupItem* i = group;
579
 
 
580
 
        if (i)
581
 
        {
582
 
            if (i->m_prev)
583
 
            {
584
 
                i->m_prev->m_next = i->m_next;
585
 
            }
586
 
 
587
 
            if (i->m_next)
588
 
            {
589
 
                i->m_next->m_prev = i->m_prev;
590
 
            }
591
 
 
592
 
            if (i->m_prev)
593
 
            {
594
 
                alternativeVisibleGroup = i->m_prev;
595
 
            }
596
 
            else
597
 
            {
598
 
                alternativeVisibleGroup = i->m_next;
599
 
            }
600
 
        }
601
 
    }
602
 
 
603
 
    if (!d->clearing)
604
 
    {
605
 
        d->storedVisibleItem = findFirstVisibleItem();
606
 
 
607
 
        if (!d->storedVisibleItem && alternativeVisibleGroup)
608
 
        {
609
 
            // find an alternative visible item
610
 
            d->storedVisibleItem = alternativeVisibleGroup->lastItem();
611
 
        }
612
 
 
613
 
        startRearrangeTimer();
614
 
    }
615
 
}
616
 
 
617
 
void IconView::insertItem(IconItem* item)
618
 
{
619
 
    if (!item)
620
 
    {
621
 
        return;
622
 
    }
623
 
 
624
 
    d->storedVisibleItem = findFirstVisibleItem();
625
 
    startRearrangeTimer();
626
 
}
627
 
 
628
 
void IconView::takeItem(IconItem* item)
629
 
{
630
 
    if (!item)
631
 
    {
632
 
        return;
633
 
    }
634
 
 
635
 
    // First remove item from any containers holding it
636
 
    IconViewPriv::ItemContainer* tmp = d->firstContainer;
637
 
 
638
 
    while (tmp)
639
 
    {
640
 
        tmp->items.removeAll(item);
641
 
        tmp = tmp->next;
642
 
    }
643
 
 
644
 
    // Remove from selected item list
645
 
    d->selectedItems.remove(item);
646
 
 
647
 
    // See bug 161084
648
 
    if (d->selectedItems.count() || item->isSelected())
649
 
    {
650
 
        d->needEmitSelectionChanged = true;
651
 
    }
652
 
 
653
 
    if (d->toolTipItem == item)
654
 
    {
655
 
        d->toolTipItem = 0;
656
 
        d->toolTipTimer->stop();
657
 
        slotToolTip();
658
 
    }
659
 
 
660
 
    if (d->highlightedItem == item)
661
 
    {
662
 
        d->highlightedItem = 0;
663
 
    }
664
 
 
665
 
    if (d->ratingItem == item)
666
 
    {
667
 
        d->ratingItem->setEditRating(false);
668
 
        d->ratingItem = 0;
669
 
        unsetCursor();
670
 
        d->ratingWidget->hide();
671
 
    }
672
 
 
673
 
    // if it is current item, change the current item
674
 
    if (d->currItem == item)
675
 
    {
676
 
        d->currItem = item->nextItem();
677
 
 
678
 
        if (!d->currItem)
679
 
        {
680
 
            d->currItem = item->prevItem();
681
 
            // defer calling d->currItem->setSelected (and emitting the signals) to slotRearrange
682
 
        }
683
 
    }
684
 
 
685
 
    d->anchorItem = d->currItem;
686
 
 
687
 
    if (!d->clearing)
688
 
    {
689
 
        d->storedVisibleItem = findFirstVisibleItem();
690
 
 
691
 
        if (d->storedVisibleItem == item)
692
 
        {
693
 
            d->storedVisibleItem = d->currItem;
694
 
        }
695
 
 
696
 
        startRearrangeTimer();
697
 
    }
698
 
}
699
 
 
700
 
void IconView::triggerRearrangement()
701
 
{
702
 
    d->storedVisibleItem = findFirstVisibleItem();
703
 
    startRearrangeTimer();
704
 
}
705
 
 
706
 
void IconView::setDelayedRearrangement(bool delayed)
707
 
{
708
 
    // if it is known that e.g. several items will be added or deleted in the next time,
709
 
    // but not from the same event queue thread stack location, it may be desirable to delay
710
 
    // the rearrangeTimer a bit
711
 
    if (delayed)
712
 
    {
713
 
        d->rearrangeTimerInterval = 50;
714
 
    }
715
 
    else
716
 
    {
717
 
        d->rearrangeTimerInterval = 0;
718
 
    }
719
 
}
720
 
 
721
 
void IconView::startRearrangeTimer()
722
 
{
723
 
    // We want to reduce the number of updates, but not remove all updates
724
 
    if (!d->rearrangeTimer->isActive())
725
 
    {
726
 
        d->rearrangeTimer->setSingleShot(true);
727
 
        d->rearrangeTimer->start(d->rearrangeTimerInterval);
728
 
    }
729
 
}
730
 
 
731
 
void IconView::sort()
732
 
{
733
 
    // first sort the groups
734
 
    for (IconGroupItem* group = d->firstGroup; group;
735
 
         group = group->nextGroup())
736
 
    {
737
 
        group->sort();
738
 
    }
739
 
 
740
 
    int gcount = groupCount();
741
 
 
742
 
    // then sort the groups themselves
743
 
    QScopedArrayPointer<IconViewPriv::SortableItem> groups(new IconViewPriv::SortableItem[ gcount ]);
744
 
 
745
 
    IconGroupItem* group = d->firstGroup;
746
 
    int i = 0;
747
 
 
748
 
    for (; group; group = group->m_next)
749
 
    {
750
 
        groups[i++].group = group;
751
 
    }
752
 
 
753
 
    qsort(groups.data(), gcount, sizeof(IconViewPriv::SortableItem), cmpItems);
754
 
 
755
 
    IconGroupItem* prev = 0;
756
 
    group = 0;
757
 
 
758
 
    for (i = 0; i < (int) gcount; ++i)
759
 
    {
760
 
        group = groups[i].group;
761
 
 
762
 
        if (group)
763
 
        {
764
 
            group->m_prev = prev;
765
 
 
766
 
            if (group->m_prev)
767
 
            {
768
 
                group->m_prev->m_next = group;
769
 
            }
770
 
 
771
 
            group->m_next = 0;
772
 
        }
773
 
 
774
 
        if (i == 0)
775
 
        {
776
 
            d->firstGroup = group;
777
 
        }
778
 
 
779
 
        if (i == (int) gcount - 1)
780
 
        {
781
 
            d->lastGroup = group;
782
 
        }
783
 
 
784
 
        prev = group;
785
 
    }
786
 
}
787
 
 
788
 
void IconView::slotRearrange()
789
 
{
790
 
    if (d->highlightedItem)
791
 
    {
792
 
        d->highlightedItem->setHighlighted(false);
793
 
        d->highlightedItem = 0;
794
 
    }
795
 
 
796
 
    if (d->ratingItem)
797
 
    {
798
 
        d->ratingItem->setEditRating(false);
799
 
        d->ratingItem = 0;
800
 
        unsetCursor();
801
 
        d->ratingWidget->hide();
802
 
    }
803
 
 
804
 
    // hide tooltip
805
 
    d->toolTipItem = 0;
806
 
    d->toolTipTimer->stop();
807
 
    slotToolTip();
808
 
 
809
 
    sort();
810
 
    arrangeItems();
811
 
 
812
 
    // ensure there is a current item
813
 
    if (!d->currItem)
814
 
    {
815
 
        // set the currItem to first item
816
 
        if (d->firstGroup)
817
 
        {
818
 
            d->currItem = d->firstGroup->firstItem();
819
 
        }
820
 
    }
821
 
 
822
 
    d->anchorItem = d->currItem;
823
 
 
824
 
    // ensure there is a selection
825
 
    if (d->selectedItems.isEmpty() && d->currItem)
826
 
    {
827
 
        d->currItem->setSelected(true, true);
828
 
    }
829
 
    else if (d->needEmitSelectionChanged)
830
 
    {
831
 
        emit signalSelectionChanged();
832
 
    }
833
 
 
834
 
    d->needEmitSelectionChanged = false;
835
 
 
836
 
    // set first visible item if they where stored before update was triggered
837
 
    if (d->storedVisibleItem)
838
 
    {
839
 
        ensureItemVisible(d->storedVisibleItem);
840
 
        // reset to 0
841
 
        d->storedVisibleItem = 0;
842
 
    }
843
 
    else
844
 
    {
845
 
        ensureItemVisible(d->currItem);
846
 
    }
847
 
 
848
 
    viewport()->update();
849
 
    emit signalItemsRearranged();
850
 
}
851
 
 
852
 
bool IconView::arrangeItems()
853
 
{
854
 
    int  y     = 0;
855
 
    int  itemW = itemRect().width();
856
 
    int  itemH = itemRect().height();
857
 
    int  maxW  = 0;
858
 
 
859
 
    int numItemsPerRow = visibleWidth() / (itemW + d->spacing);
860
 
 
861
 
    bool changed = false;
862
 
 
863
 
    IconGroupItem* group = d->firstGroup;
864
 
    IconItem*      item  = 0;
865
 
 
866
 
    while (group)
867
 
    {
868
 
        changed = group->move(y) || changed;
869
 
        y      += group->rect().height() + d->spacing;
870
 
 
871
 
        item = group->firstItem();
872
 
 
873
 
        int col = 0;
874
 
        int x   = d->spacing;
875
 
 
876
 
        while (item)
877
 
        {
878
 
            changed = item->move(x, y) || changed;
879
 
            x       += itemW + d->spacing;
880
 
            ++col;
881
 
 
882
 
            if (col >= numItemsPerRow)
883
 
            {
884
 
                x  = d->spacing;
885
 
                y += itemH + d->spacing;
886
 
                col = 0;
887
 
            }
888
 
 
889
 
            maxW = qMax(maxW, x + itemW);
890
 
            item = item->m_next;
891
 
        }
892
 
 
893
 
        if (col != 0)
894
 
        {
895
 
            y += itemH + d->spacing;
896
 
        }
897
 
 
898
 
        y     += d->spacing;
899
 
        group = group->m_next;
900
 
    }
901
 
 
902
 
    viewport()->setUpdatesEnabled(false);
903
 
    resizeContents(maxW, y);
904
 
    viewport()->setUpdatesEnabled(true);
905
 
 
906
 
    rebuildContainers();
907
 
 
908
 
    return changed;
909
 
}
910
 
 
911
 
QRect IconView::itemRect() const
912
 
{
913
 
    return QRect(0, 0, 100, 100);
914
 
}
915
 
 
916
 
QRect IconView::bannerRect() const
917
 
{
918
 
    return QRect(0, 0, visibleWidth(), 0);
919
 
}
920
 
 
921
 
void IconView::viewportPaintEvent(QPaintEvent* pe)
922
 
{
923
 
    QRect contentsPaintRect(viewportToContents(pe->rect().topLeft()), viewportToContents(pe->rect().bottomRight()));
924
 
    QRegion unpaintedRegion(pe->region());
925
 
 
926
 
    QPainter painter(viewport());
927
 
 
928
 
    // paint any group banners which intersect this paintevent rect
929
 
    for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
930
 
    {
931
 
        if (contentsPaintRect.intersects(group->rect()))
932
 
        {
933
 
            QRect viewportRect = contentsRectToViewport(group->rect());
934
 
            //painter.save();
935
 
            painter.translate(viewportRect.x(), viewportRect.y());
936
 
            group->paintBanner(&painter);
937
 
            painter.translate(- viewportRect.x(), - viewportRect.y());
938
 
            //painter.restore();
939
 
            unpaintedRegion -= QRegion(viewportRect);
940
 
        }
941
 
    }
942
 
 
943
 
    // now paint any items which intersect
944
 
    QList<IconItem*> itemsToRepaint;
945
 
 
946
 
    for (IconViewPriv::ItemContainer* c = d->firstContainer; c;
947
 
         c = c->next)
948
 
    {
949
 
        if (contentsPaintRect.intersects(c->rect))
950
 
        {
951
 
            foreach(IconItem* item, c->items)
952
 
            {
953
 
                if (contentsPaintRect.intersects(item->rect()))
954
 
                {
955
 
                    itemsToRepaint << item;
956
 
                }
957
 
            }
958
 
        }
959
 
    }
960
 
 
961
 
    foreach(IconItem* item, itemsToRepaint)
962
 
    {
963
 
        QRect viewportRect = contentsRectToViewport(item->rect());
964
 
        //painter.save();
965
 
        painter.translate(viewportRect.x(), viewportRect.y());
966
 
        item->paintItem(&painter);
967
 
        painter.translate(- viewportRect.x(), - viewportRect.y());
968
 
        //painter.restore();
969
 
        unpaintedRegion -= QRegion(viewportRect);
970
 
    }
971
 
 
972
 
    painter.setClipRegion(unpaintedRegion);
973
 
    painter.fillRect(pe->rect(), palette().color(QPalette::Base));
974
 
}
975
 
 
976
 
QRect IconView::contentsRectToViewport(const QRect& r) const
977
 
{
978
 
    QRect vr = QRect(contentsToViewport(QPoint(r.x(), r.y())), r.size());
979
 
    return vr;
980
 
}
981
 
 
982
 
void IconView::resizeEvent(QResizeEvent* e)
983
 
{
984
 
    Q3ScrollView::resizeEvent(e);
985
 
    triggerRearrangement();
986
 
}
987
 
 
988
 
void IconView::rebuildContainers()
989
 
{
990
 
    deleteContainers();
991
 
 
992
 
    IconItem* item = 0;
993
 
    appendContainer();
994
 
 
995
 
    if (d->firstGroup)
996
 
    {
997
 
        item = d->firstGroup->firstItem();
998
 
    }
999
 
 
1000
 
    IconViewPriv::ItemContainer* c = d->lastContainer;
1001
 
 
1002
 
    while (item)
1003
 
    {
1004
 
        if (c->rect.contains(item->rect()))
1005
 
        {
1006
 
            c->items << item;
1007
 
            item = item->nextItem();
1008
 
        }
1009
 
        else if (c->rect.intersects(item->rect()))
1010
 
        {
1011
 
            c->items << item;
1012
 
            c = c->next;
1013
 
 
1014
 
            if (!c)
1015
 
            {
1016
 
                appendContainer();
1017
 
                c = d->lastContainer;
1018
 
            }
1019
 
 
1020
 
            c->items << item;
1021
 
            item = item->nextItem();
1022
 
            c = c->prev;
1023
 
        }
1024
 
        else
1025
 
        {
1026
 
            if (item->y() < c->rect.y() && c->prev)
1027
 
            {
1028
 
                c = c->prev;
1029
 
                continue;
1030
 
            }
1031
 
 
1032
 
            c = c->next;
1033
 
 
1034
 
            if (!c)
1035
 
            {
1036
 
                appendContainer();
1037
 
                c = d->lastContainer;
1038
 
            }
1039
 
        }
1040
 
    }
1041
 
}
1042
 
 
1043
 
void IconView::appendContainer()
1044
 
{
1045
 
    QSize s(INT_MAX - 1, RECT_EXTENSION);
1046
 
 
1047
 
    if (!d->firstContainer)
1048
 
    {
1049
 
        d->firstContainer = new IconViewPriv::ItemContainer(0, 0, QRect(QPoint(0, 0), s));
1050
 
        d->lastContainer = d->firstContainer;
1051
 
    }
1052
 
    else
1053
 
    {
1054
 
        d->lastContainer = new IconViewPriv::ItemContainer(
1055
 
            d->lastContainer, 0, QRect(d->lastContainer->rect.bottomLeft(), s));
1056
 
    }
1057
 
}
1058
 
 
1059
 
void IconView::deleteContainers()
1060
 
{
1061
 
    IconViewPriv::ItemContainer* c = d->firstContainer;
1062
 
    IconViewPriv::ItemContainer* tmp;
1063
 
 
1064
 
    while (c)
1065
 
    {
1066
 
        tmp = c->next;
1067
 
        delete c;
1068
 
        c = tmp;
1069
 
    }
1070
 
 
1071
 
    d->firstContainer = d->lastContainer = 0;
1072
 
}
1073
 
 
1074
 
void IconView::leaveEvent(QEvent* e)
1075
 
{
1076
 
 
1077
 
    // if the mouse leaves the widget we are not dragging
1078
 
    // anymore
1079
 
    d->dragging = false;
1080
 
 
1081
 
    Q3ScrollView::leaveEvent(e);
1082
 
}
1083
 
 
1084
 
void IconView::focusOutEvent(QFocusEvent* e)
1085
 
{
1086
 
    if (d->highlightedItem)
1087
 
    {
1088
 
        d->highlightedItem->setHighlighted(false);
1089
 
        d->highlightedItem = 0;
1090
 
    }
1091
 
 
1092
 
    if (d->ratingItem)
1093
 
    {
1094
 
        d->ratingItem->setEditRating(false);
1095
 
        d->ratingItem = 0;
1096
 
        unsetCursor();
1097
 
        d->ratingWidget->hide();
1098
 
    }
1099
 
 
1100
 
    // hide tooltip
1101
 
    d->toolTipItem = 0;
1102
 
    d->toolTipTimer->stop();
1103
 
    slotToolTip();
1104
 
 
1105
 
    Q3ScrollView::focusOutEvent(e);
1106
 
}
1107
 
 
1108
 
bool IconView::acceptToolTip(IconItem*, const QPoint&)
1109
 
{
1110
 
    return true;
1111
 
}
1112
 
 
1113
 
void IconView::contentsMousePressEvent(QMouseEvent* e)
1114
 
{
1115
 
    d->pressedMoved = false;
1116
 
 
1117
 
    // hide tooltip
1118
 
    d->toolTipItem = 0;
1119
 
    d->toolTipTimer->stop();
1120
 
    slotToolTip();
1121
 
 
1122
 
    // Clear any existing rubber -------------------------------
1123
 
    d->rubber->setActive(false);
1124
 
 
1125
 
    if (e->button() == Qt::RightButton)
1126
 
    {
1127
 
        IconItem* item = findItem(e->pos());
1128
 
 
1129
 
        if (item)
1130
 
        {
1131
 
            IconItem* prevCurrItem = d->currItem;
1132
 
            d->currItem            = item;
1133
 
            d->anchorItem          = item;
1134
 
 
1135
 
            if (prevCurrItem)
1136
 
            {
1137
 
                prevCurrItem->repaint();
1138
 
            }
1139
 
 
1140
 
            if (!item->isSelected())
1141
 
            {
1142
 
                item->setSelected(true, true);
1143
 
            }
1144
 
 
1145
 
            item->repaint();
1146
 
 
1147
 
            emit signalRightButtonClicked(item, e->globalPos());
1148
 
        }
1149
 
        else
1150
 
        {
1151
 
            clearSelection();
1152
 
            emit signalRightButtonClicked(e->globalPos());
1153
 
        }
1154
 
 
1155
 
        return;
1156
 
    }
1157
 
 
1158
 
    IconItem* item = findItem(e->pos());
1159
 
 
1160
 
    if (item)
1161
 
    {
1162
 
        if (e->modifiers() == Qt::ControlModifier)
1163
 
        {
1164
 
            item->setSelected(!item->isSelected(), false);
1165
 
        }
1166
 
        else if (e->modifiers() == Qt::ShiftModifier
1167
 
                 || e->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier))
1168
 
        {
1169
 
            blockSignals(true);
1170
 
 
1171
 
            if (d->currItem)
1172
 
            {
1173
 
                if (!(e->modifiers() & Qt::ControlModifier))
1174
 
                {
1175
 
                    clearSelection();
1176
 
                }
1177
 
 
1178
 
                // select all items from/upto the current item
1179
 
                bool bwdSelect = false;
1180
 
 
1181
 
                // find if the current item is before the clicked item
1182
 
                for (IconItem* it = item->prevItem(); it; it = it->prevItem())
1183
 
                {
1184
 
                    if (it == d->currItem)
1185
 
                    {
1186
 
                        bwdSelect = true;
1187
 
                        break;
1188
 
                    }
1189
 
                }
1190
 
 
1191
 
                if (bwdSelect)
1192
 
                {
1193
 
                    for (IconItem* it = item; it; it = it->prevItem())
1194
 
                    {
1195
 
                        it->setSelected(true, false);
1196
 
 
1197
 
                        if (it == d->currItem)
1198
 
                        {
1199
 
                            break;
1200
 
                        }
1201
 
                    }
1202
 
                }
1203
 
                else
1204
 
                {
1205
 
                    for (IconItem* it = item; it; it = it->nextItem())
1206
 
                    {
1207
 
                        it->setSelected(true, false);
1208
 
 
1209
 
                        if (it == d->currItem)
1210
 
                        {
1211
 
                            break;
1212
 
                        }
1213
 
                    }
1214
 
                }
1215
 
            }
1216
 
            else
1217
 
            {
1218
 
                item->setSelected(true, false);
1219
 
            }
1220
 
 
1221
 
            blockSignals(false);
1222
 
 
1223
 
            emit signalSelectionChanged();
1224
 
        }
1225
 
        else if (e->modifiers() == Qt::NoModifier)
1226
 
        {
1227
 
            if (item->clickToToggleSelectRect().contains(e->pos()))
1228
 
            {
1229
 
                item->setSelected(!item->isSelected(), false);
1230
 
            }
1231
 
            else if (!item->isSelected())
1232
 
            {
1233
 
                item->setSelected(true, true);
1234
 
            }
1235
 
        }
1236
 
 
1237
 
        IconItem* prevCurrItem = d->currItem;
1238
 
        d->currItem            = item;
1239
 
        d->anchorItem          = item;
1240
 
 
1241
 
        if (prevCurrItem)
1242
 
        {
1243
 
            prevCurrItem->repaint();
1244
 
        }
1245
 
 
1246
 
        d->currItem->repaint();
1247
 
 
1248
 
        d->dragging     = true;
1249
 
        d->dragStartPos = e->pos();
1250
 
 
1251
 
        return;
1252
 
    }
1253
 
 
1254
 
    // Press outside any item.
1255
 
    if (!(e->modifiers() & Qt::ControlModifier))
1256
 
    {
1257
 
        // unselect all if the ctrl button is not pressed
1258
 
        clearSelection();
1259
 
    }
1260
 
    else
1261
 
    {
1262
 
        // ctrl is pressed. make sure our current selection is not lost
1263
 
        d->prevSelectedItems = d->selectedItems;
1264
 
    }
1265
 
 
1266
 
    d->rubber->setFirstPointOnViewport(e->pos());
1267
 
}
1268
 
 
1269
 
void IconView::contentsMouseMoveEvent(QMouseEvent* e)
1270
 
{
1271
 
    if (e->buttons() == Qt::NoButton)
1272
 
    {
1273
 
        IconItem* item = findItem(e->pos());
1274
 
 
1275
 
        if (d->showTips)
1276
 
        {
1277
 
            if (!isActiveWindow())
1278
 
            {
1279
 
                d->toolTipItem = 0;
1280
 
                d->toolTipTimer->stop();
1281
 
                slotToolTip();
1282
 
                return;
1283
 
            }
1284
 
 
1285
 
            if (item != d->toolTipItem)
1286
 
            {
1287
 
                d->toolTipItem = 0;
1288
 
                d->toolTipTimer->stop();
1289
 
                slotToolTip();
1290
 
 
1291
 
                if (acceptToolTip(item, e->pos()))
1292
 
                {
1293
 
                    d->toolTipItem = item;
1294
 
                    d->toolTipTimer->setSingleShot(true);
1295
 
                    d->toolTipTimer->start(500);
1296
 
                }
1297
 
            }
1298
 
 
1299
 
            if (item == d->toolTipItem && !acceptToolTip(item, e->pos()))
1300
 
            {
1301
 
                d->toolTipItem = 0;
1302
 
                d->toolTipTimer->stop();
1303
 
                slotToolTip();
1304
 
            }
1305
 
        }
1306
 
 
1307
 
        if (item && KGlobalSettings::changeCursorOverIcon() && item->clickToOpenRect().contains(e->pos()))
1308
 
        {
1309
 
            setCursor(Qt::PointingHandCursor);
1310
 
            d->ratingWidget->hide();
1311
 
 
1312
 
            if (d->ratingItem)
1313
 
            {
1314
 
                d->ratingItem->setEditRating(false);
1315
 
            }
1316
 
 
1317
 
            d->ratingItem = 0;
1318
 
        }
1319
 
        else if (item && item->clickToRateRect().contains(e->pos()))
1320
 
        {
1321
 
            setCursor(Qt::CrossCursor);
1322
 
            d->ratingItem = item;
1323
 
 
1324
 
            if (d->ratingItem)
1325
 
            {
1326
 
                d->ratingItem->setEditRating(true);
1327
 
            }
1328
 
 
1329
 
            QRect rect = item->clickToRateRect();
1330
 
            rect.moveTopLeft(contentsToViewport(rect.topLeft()));
1331
 
            d->ratingWidget->setFixedSize(rect.width() + 1, rect.height() + 1);
1332
 
            d->ratingWidget->move(rect.topLeft().x(), rect.topLeft().y());
1333
 
            d->ratingWidget->setRating(item->rating());
1334
 
            d->ratingWidget->show();
1335
 
        }
1336
 
        else
1337
 
        {
1338
 
            unsetCursor();
1339
 
            d->ratingWidget->hide();
1340
 
 
1341
 
            if (d->ratingItem)
1342
 
            {
1343
 
                d->ratingItem->setEditRating(false);
1344
 
            }
1345
 
 
1346
 
            d->ratingItem = 0;
1347
 
        }
1348
 
 
1349
 
        // Draw item highlightment when mouse is over.
1350
 
 
1351
 
        if (item != d->highlightedItem)
1352
 
        {
1353
 
            if (d->highlightedItem)
1354
 
            {
1355
 
                d->highlightedItem->setHighlighted(false);
1356
 
            }
1357
 
 
1358
 
            d->highlightedItem = item;
1359
 
 
1360
 
            if (d->highlightedItem)
1361
 
            {
1362
 
                d->highlightedItem->setHighlighted(true);
1363
 
            }
1364
 
        }
1365
 
 
1366
 
        return;
1367
 
    }
1368
 
 
1369
 
    d->toolTipItem = 0;
1370
 
    d->toolTipTimer->stop();
1371
 
    slotToolTip();
1372
 
 
1373
 
    if (d->dragging && (e->buttons() & Qt::LeftButton))
1374
 
    {
1375
 
        if ((d->dragStartPos - e->pos()).manhattanLength()
1376
 
            > QApplication::startDragDistance())
1377
 
        {
1378
 
            startDrag();
1379
 
        }
1380
 
 
1381
 
        return;
1382
 
    }
1383
 
 
1384
 
    if (!d->rubber->isActive())
1385
 
    {
1386
 
        return;
1387
 
    }
1388
 
 
1389
 
    QRect oldArea = d->rubber->rubberBandAreaOnContents();
1390
 
 
1391
 
    d->rubber->setSecondPointOnViewport(e->pos());
1392
 
 
1393
 
    QRect newArea     = d->rubber->rubberBandAreaOnContents();
1394
 
    QRect rubberUnion = oldArea.unite(newArea);
1395
 
    bool changed      = false;
1396
 
 
1397
 
    QRegion paintRegion;
1398
 
    viewport()->setUpdatesEnabled(false);
1399
 
    blockSignals(true);
1400
 
 
1401
 
    IconViewPriv::ItemContainer* c = d->firstContainer;
1402
 
 
1403
 
    for (; c; c = c->next)
1404
 
    {
1405
 
        if (rubberUnion.intersects(c->rect))
1406
 
        {
1407
 
            foreach(IconItem* item, c->items)
1408
 
            {
1409
 
                if (newArea.intersects(item->rect()))
1410
 
                {
1411
 
                    if (!item->isSelected())
1412
 
                    {
1413
 
                        item->setSelected(true, false);
1414
 
                        changed = true;
1415
 
                        paintRegion += QRect(item->rect());
1416
 
                    }
1417
 
                }
1418
 
                else
1419
 
                {
1420
 
                    if (item->isSelected() &&  !d->prevSelectedItems.contains(item))
1421
 
                    {
1422
 
                        item->setSelected(false, false);
1423
 
                        changed = true;
1424
 
                        paintRegion += QRect(item->rect());
1425
 
                    }
1426
 
                }
1427
 
            }
1428
 
        }
1429
 
    }
1430
 
 
1431
 
    blockSignals(false);
1432
 
    viewport()->setUpdatesEnabled(true);
1433
 
 
1434
 
    if (changed)
1435
 
    {
1436
 
        paintRegion.translate(-contentsX(), -contentsY());
1437
 
        viewport()->repaint(paintRegion);
1438
 
    }
1439
 
 
1440
 
    ensureVisible(e->pos().x(), e->pos().y());
1441
 
 
1442
 
    d->pressedMoved = true;
1443
 
 
1444
 
    if (changed)
1445
 
    {
1446
 
        emit signalSelectionChanged();
1447
 
    }
1448
 
}
1449
 
 
1450
 
void IconView::contentsMouseReleaseEvent(QMouseEvent* e)
1451
 
{
1452
 
    d->dragging = false;
1453
 
    d->prevSelectedItems.clear();
1454
 
 
1455
 
    if (d->rubber->isActive())
1456
 
    {
1457
 
        d->rubber->setActive(false);
1458
 
    }
1459
 
 
1460
 
    if (e->button() == Qt::LeftButton
1461
 
        && e->buttons() == Qt::NoButton
1462
 
        && e->modifiers() == Qt::NoModifier)
1463
 
    {
1464
 
        if (d->pressedMoved)
1465
 
        {
1466
 
            emit signalSelectionChanged();
1467
 
            d->pressedMoved = false;
1468
 
            return;
1469
 
        }
1470
 
 
1471
 
        // click on item
1472
 
        IconItem* item = findItem(e->pos());
1473
 
 
1474
 
        if (item && !item->clickToToggleSelectRect().contains(e->pos()))
1475
 
        {
1476
 
            IconItem* prevCurrItem = d->currItem;
1477
 
            item->setSelected(true, true);
1478
 
            d->currItem   = item;
1479
 
            d->anchorItem = item;
1480
 
 
1481
 
            if (prevCurrItem)
1482
 
            {
1483
 
                prevCurrItem->repaint();
1484
 
            }
1485
 
 
1486
 
            if (KGlobalSettings::singleClick())
1487
 
            {
1488
 
                if (item->clickToOpenRect().contains(e->pos()))
1489
 
                {
1490
 
                    itemClickedToOpen(item);
1491
 
                }
1492
 
            }
1493
 
        }
1494
 
    }
1495
 
}
1496
 
 
1497
 
void IconView::contentsWheelEvent(QWheelEvent* e)
1498
 
{
1499
 
    e->accept();
1500
 
 
1501
 
    if (d->highlightedItem)
1502
 
    {
1503
 
        d->highlightedItem->setHighlighted(false);
1504
 
        d->highlightedItem = 0;
1505
 
    }
1506
 
 
1507
 
    if (d->ratingItem)
1508
 
    {
1509
 
        d->ratingItem->setEditRating(false);
1510
 
        d->ratingItem = 0;
1511
 
        unsetCursor();
1512
 
        d->ratingWidget->hide();
1513
 
    }
1514
 
 
1515
 
    d->toolTipItem = 0;
1516
 
    d->toolTipTimer->stop();
1517
 
    slotToolTip();
1518
 
    viewport()->update();
1519
 
 
1520
 
    if (e->modifiers() & Qt::ControlModifier)
1521
 
    {
1522
 
        if (e->delta() < 0)
1523
 
        {
1524
 
            emit signalZoomOut();
1525
 
        }
1526
 
        else if (e->delta() > 0)
1527
 
        {
1528
 
            emit signalZoomIn();
1529
 
        }
1530
 
 
1531
 
        // We don't want to scroll contents.
1532
 
        return;
1533
 
    }
1534
 
 
1535
 
    Q3ScrollView::contentsWheelEvent(e);
1536
 
}
1537
 
 
1538
 
void IconView::contentsMouseDoubleClickEvent(QMouseEvent* e)
1539
 
{
1540
 
    if (KGlobalSettings::singleClick())
1541
 
    {
1542
 
        return;
1543
 
    }
1544
 
 
1545
 
    IconItem* item = findItem(e->pos());
1546
 
 
1547
 
    if (item)
1548
 
    {
1549
 
        itemClickedToOpen(item);
1550
 
    }
1551
 
}
1552
 
 
1553
 
void IconView::keyPressEvent(QKeyEvent* e)
1554
 
{
1555
 
    bool handled = false;
1556
 
 
1557
 
    if (!firstItem())
1558
 
    {
1559
 
        return;
1560
 
    }
1561
 
 
1562
 
    switch (e->key())
1563
 
    {
1564
 
        case Qt::Key_Home:
1565
 
        {
1566
 
            if (e->modifiers() & Qt::ShiftModifier)
1567
 
            {
1568
 
                IconItem* const tmp = d->currItem;
1569
 
                d->currItem = firstItem();
1570
 
 
1571
 
                if (tmp)
1572
 
                {
1573
 
                    tmp->repaint();
1574
 
                }
1575
 
 
1576
 
                // select items: anchor until before firstItem
1577
 
                // block signals while selecting all except the firstItem
1578
 
                blockSignals(true);
1579
 
 
1580
 
                for (IconItem* i = d->anchorItem; i && (i != firstItem()); i = i->prevItem())
1581
 
                {
1582
 
                    i->setSelected(true, false);
1583
 
                }
1584
 
 
1585
 
                blockSignals(false);
1586
 
 
1587
 
                // select the firstItem with signals enabled to ensure updates
1588
 
                firstItem()->setSelected(true, false);
1589
 
            }
1590
 
            else
1591
 
            {
1592
 
                IconItem* const tmp = d->currItem;
1593
 
                d->currItem = firstItem();
1594
 
                d->anchorItem = d->currItem;
1595
 
 
1596
 
                if (tmp)
1597
 
                {
1598
 
                    tmp->repaint();
1599
 
                }
1600
 
 
1601
 
                // select only the first item
1602
 
                firstItem()->setSelected(true, true);
1603
 
            }
1604
 
 
1605
 
            ensureItemVisible(firstItem());
1606
 
            handled = true;
1607
 
            break;
1608
 
        }
1609
 
 
1610
 
        case Qt::Key_End:
1611
 
        {
1612
 
            if (e->modifiers() & Qt::ShiftModifier)
1613
 
            {
1614
 
                IconItem* const tmp = d->currItem;
1615
 
                d->currItem = lastItem();
1616
 
 
1617
 
                if (tmp)
1618
 
                {
1619
 
                    tmp->repaint();
1620
 
                }
1621
 
 
1622
 
                // select items: current until lastItem
1623
 
                // block signals while selecting all except the lastItem
1624
 
                blockSignals(true);
1625
 
 
1626
 
                for (IconItem* i = d->anchorItem; i && (i != lastItem()); i = i->nextItem())
1627
 
                {
1628
 
                    i->setSelected(true, false);
1629
 
                }
1630
 
 
1631
 
                blockSignals(false);
1632
 
 
1633
 
                // select the lastItem with signals enabled to ensure updates
1634
 
                lastItem()->setSelected(true, false);
1635
 
            }
1636
 
            else
1637
 
            {
1638
 
                IconItem* const tmp = d->currItem;
1639
 
                d->currItem = lastItem();
1640
 
                d->anchorItem = d->currItem;
1641
 
 
1642
 
                if (tmp)
1643
 
                {
1644
 
                    tmp->repaint();
1645
 
                }
1646
 
 
1647
 
                lastItem()->setSelected(true, true);
1648
 
            }
1649
 
 
1650
 
            ensureItemVisible(lastItem());
1651
 
            handled = true;
1652
 
            break;
1653
 
        }
1654
 
 
1655
 
        case Qt::Key_Enter:
1656
 
        case Qt::Key_Return:
1657
 
        {
1658
 
            if (d->currItem)
1659
 
            {
1660
 
                emit signalReturnPressed(d->currItem);
1661
 
                handled = true;
1662
 
            }
1663
 
 
1664
 
            break;
1665
 
        }
1666
 
 
1667
 
        case Qt::Key_Right:
1668
 
        {
1669
 
            IconItem* item = 0;
1670
 
 
1671
 
            if (d->currItem)
1672
 
            {
1673
 
                if (d->currItem->nextItem())
1674
 
                {
1675
 
                    if (e->modifiers() & Qt::ControlModifier)
1676
 
                    {
1677
 
                        IconItem* tmp = d->currItem;
1678
 
                        d->currItem   = d->currItem->nextItem();
1679
 
                        d->anchorItem = d->currItem;
1680
 
                        tmp->repaint();
1681
 
                        d->currItem->repaint();
1682
 
 
1683
 
                        item = d->currItem;
1684
 
                    }
1685
 
                    else if (e->modifiers() & Qt::ShiftModifier)
1686
 
                    {
1687
 
                        IconItem* tmp = d->currItem;
1688
 
                        d->currItem   = d->currItem->nextItem();
1689
 
                        tmp->repaint();
1690
 
 
1691
 
                        // if the anchor is behind us, move forward preserving
1692
 
                        // the previously selected item. otherwise unselect the
1693
 
                        // previously selected item
1694
 
                        if (!anchorIsBehind())
1695
 
                        {
1696
 
                            tmp->setSelected(false, false);
1697
 
                        }
1698
 
 
1699
 
                        d->currItem->setSelected(true, false);
1700
 
 
1701
 
                        item = d->currItem;
1702
 
                    }
1703
 
                    else
1704
 
                    {
1705
 
                        IconItem* tmp = d->currItem;
1706
 
                        d->currItem   = d->currItem->nextItem();
1707
 
                        d->anchorItem = d->currItem;
1708
 
                        d->currItem->setSelected(true, true);
1709
 
                        tmp->repaint();
1710
 
 
1711
 
                        item = d->currItem;
1712
 
                    }
1713
 
                }
1714
 
            }
1715
 
            else
1716
 
            {
1717
 
                d->currItem   = firstItem();
1718
 
                d->anchorItem = d->currItem;
1719
 
                d->currItem->setSelected(true, true);
1720
 
                item = d->currItem;
1721
 
            }
1722
 
 
1723
 
            ensureItemVisible(item);
1724
 
            handled = true;
1725
 
            break;
1726
 
        }
1727
 
 
1728
 
        case Qt::Key_Left:
1729
 
        {
1730
 
            IconItem* item = 0;
1731
 
 
1732
 
            if (d->currItem)
1733
 
            {
1734
 
                if (d->currItem->prevItem())
1735
 
                {
1736
 
                    if (e->modifiers() & Qt::ControlModifier)
1737
 
                    {
1738
 
                        IconItem* tmp = d->currItem;
1739
 
                        d->currItem   = d->currItem->prevItem();
1740
 
                        d->anchorItem = d->currItem;
1741
 
                        tmp->repaint();
1742
 
                        d->currItem->repaint();
1743
 
 
1744
 
                        item = d->currItem;
1745
 
                    }
1746
 
                    else if (e->modifiers() & Qt::ShiftModifier)
1747
 
                    {
1748
 
                        IconItem* tmp = d->currItem;
1749
 
                        d->currItem   = d->currItem->prevItem();
1750
 
                        tmp->repaint();
1751
 
 
1752
 
                        // if the anchor is ahead of us, move forward preserving
1753
 
                        // the previously selected item. otherwise unselect the
1754
 
                        // previously selected item
1755
 
                        if (anchorIsBehind())
1756
 
                        {
1757
 
                            tmp->setSelected(false, false);
1758
 
                        }
1759
 
 
1760
 
                        d->currItem->setSelected(true, false);
1761
 
 
1762
 
                        item = d->currItem;
1763
 
                    }
1764
 
                    else
1765
 
                    {
1766
 
                        IconItem* tmp = d->currItem;
1767
 
                        d->currItem   = d->currItem->prevItem();
1768
 
                        d->anchorItem = d->currItem;
1769
 
                        d->currItem->setSelected(true, true);
1770
 
                        tmp->repaint();
1771
 
 
1772
 
                        item = d->currItem;
1773
 
                    }
1774
 
                }
1775
 
            }
1776
 
            else
1777
 
            {
1778
 
                d->currItem   = firstItem();
1779
 
                d->anchorItem = d->currItem;
1780
 
                d->currItem->setSelected(true, true);
1781
 
                item = d->currItem;
1782
 
            }
1783
 
 
1784
 
            ensureItemVisible(item);
1785
 
            handled = true;
1786
 
            break;
1787
 
        }
1788
 
 
1789
 
        case Qt::Key_Up:
1790
 
        {
1791
 
            IconItem* item = 0;
1792
 
 
1793
 
            if (d->currItem)
1794
 
            {
1795
 
                int x = d->currItem->x() + itemRect().width() / 2;
1796
 
                int y = d->currItem->y() - d->spacing * 2;
1797
 
 
1798
 
                IconItem* it = 0;
1799
 
 
1800
 
                while (!it && y > 0)
1801
 
                {
1802
 
                    it  = findItem(QPoint(x, y));
1803
 
                    y  -= d->spacing * 2;
1804
 
                }
1805
 
 
1806
 
                if (it)
1807
 
                {
1808
 
                    if (e->modifiers() & Qt::ControlModifier)
1809
 
                    {
1810
 
                        IconItem* tmp = d->currItem;
1811
 
                        d->currItem   = it;
1812
 
                        d->anchorItem = it;
1813
 
                        tmp->repaint();
1814
 
                        d->currItem->repaint();
1815
 
 
1816
 
                        item = d->currItem;
1817
 
                    }
1818
 
                    else if (e->modifiers() & Qt::ShiftModifier)
1819
 
                    {
1820
 
                        IconItem* tmp = d->currItem;
1821
 
                        d->currItem   = it;
1822
 
                        tmp->repaint();
1823
 
 
1824
 
                        clearSelection();
1825
 
 
1826
 
                        if (anchorIsBehind())
1827
 
                        {
1828
 
                            for (IconItem* i = d->currItem; i; i = i->prevItem())
1829
 
                            {
1830
 
                                i->setSelected(true, false);
1831
 
 
1832
 
                                if (i == d->anchorItem)
1833
 
                                {
1834
 
                                    break;
1835
 
                                }
1836
 
                            }
1837
 
                        }
1838
 
                        else
1839
 
                        {
1840
 
                            for (IconItem* i = d->currItem; i; i = i->nextItem())
1841
 
                            {
1842
 
                                i->setSelected(true, false);
1843
 
 
1844
 
                                if (i == d->anchorItem)
1845
 
                                {
1846
 
                                    break;
1847
 
                                }
1848
 
                            }
1849
 
                        }
1850
 
 
1851
 
                        item = d->currItem;
1852
 
                    }
1853
 
                    else
1854
 
                    {
1855
 
                        IconItem* tmp = d->currItem;
1856
 
                        d->currItem   = it;
1857
 
                        d->anchorItem = it;
1858
 
                        d->currItem->setSelected(true, true);
1859
 
                        tmp->repaint();
1860
 
 
1861
 
                        item = d->currItem;
1862
 
                    }
1863
 
                }
1864
 
            }
1865
 
            else
1866
 
            {
1867
 
                d->currItem   = firstItem();
1868
 
                d->anchorItem = d->currItem;
1869
 
                d->currItem->setSelected(true, true);
1870
 
                item = d->currItem;
1871
 
            }
1872
 
 
1873
 
            ensureItemVisible(item);
1874
 
            handled = true;
1875
 
            break;
1876
 
        }
1877
 
 
1878
 
        case Qt::Key_Down:
1879
 
        {
1880
 
            IconItem* item = 0;
1881
 
 
1882
 
            if (d->currItem)
1883
 
            {
1884
 
                int x = d->currItem->x() + itemRect().width() / 2;
1885
 
                int y = d->currItem->y() + itemRect().height() + d->spacing * 2;
1886
 
 
1887
 
                IconItem* it = 0;
1888
 
 
1889
 
                while (!it && y < contentsHeight())
1890
 
                {
1891
 
                    it  = findItem(QPoint(x, y));
1892
 
                    y  += d->spacing * 2;
1893
 
                }
1894
 
 
1895
 
                if (it)
1896
 
                {
1897
 
                    if (e->modifiers() & Qt::ControlModifier)
1898
 
                    {
1899
 
                        IconItem* tmp = d->currItem;
1900
 
                        d->currItem   = it;
1901
 
                        d->anchorItem = it;
1902
 
                        tmp->repaint();
1903
 
                        d->currItem->repaint();
1904
 
 
1905
 
                        item = d->currItem;
1906
 
                    }
1907
 
                    else if (e->modifiers() & Qt::ShiftModifier)
1908
 
                    {
1909
 
                        IconItem* tmp = d->currItem;
1910
 
                        d->currItem   = it;
1911
 
                        tmp->repaint();
1912
 
 
1913
 
                        clearSelection();
1914
 
 
1915
 
                        if (anchorIsBehind())
1916
 
                        {
1917
 
                            for (IconItem* i = d->currItem; i; i = i->prevItem())
1918
 
                            {
1919
 
                                i->setSelected(true, false);
1920
 
 
1921
 
                                if (i == d->anchorItem)
1922
 
                                {
1923
 
                                    break;
1924
 
                                }
1925
 
                            }
1926
 
                        }
1927
 
                        else
1928
 
                        {
1929
 
                            for (IconItem* i = d->currItem; i; i = i->nextItem())
1930
 
                            {
1931
 
                                i->setSelected(true, false);
1932
 
 
1933
 
                                if (i == d->anchorItem)
1934
 
                                {
1935
 
                                    break;
1936
 
                                }
1937
 
                            }
1938
 
                        }
1939
 
 
1940
 
                        item = d->currItem;
1941
 
                    }
1942
 
                    else
1943
 
                    {
1944
 
                        IconItem* tmp = d->currItem;
1945
 
                        d->currItem   = it;
1946
 
                        d->anchorItem = it;
1947
 
                        d->currItem->setSelected(true, true);
1948
 
                        tmp->repaint();
1949
 
 
1950
 
                        item = d->currItem;
1951
 
                    }
1952
 
                }
1953
 
            }
1954
 
            else
1955
 
            {
1956
 
                d->currItem   = firstItem();
1957
 
                d->anchorItem = d->currItem;
1958
 
                d->currItem->setSelected(true, true);
1959
 
                item = d->currItem;
1960
 
            }
1961
 
 
1962
 
            ensureItemVisible(item);
1963
 
            handled = true;
1964
 
            break;
1965
 
        }
1966
 
 
1967
 
        case Qt::Key_PageDown:
1968
 
        {
1969
 
            IconItem* item = 0;
1970
 
 
1971
 
            if (d->currItem)
1972
 
            {
1973
 
                QRect r(0, d->currItem->y() + visibleHeight(),
1974
 
                        contentsWidth(), visibleHeight());
1975
 
                IconItem* ni = findFirstVisibleItem(r, false);
1976
 
 
1977
 
                if (!ni)
1978
 
                {
1979
 
                    r = QRect(0, d->currItem->y() + itemRect().height(),
1980
 
                              contentsWidth(), contentsHeight());
1981
 
                    ni = findLastVisibleItem(r, false);
1982
 
                }
1983
 
 
1984
 
                if (ni)
1985
 
                {
1986
 
                    IconItem* tmp = d->currItem;
1987
 
                    d->currItem   = ni;
1988
 
                    d->anchorItem = ni;
1989
 
                    item          = ni;
1990
 
                    tmp->repaint();
1991
 
                    d->currItem->setSelected(true, true);
1992
 
                }
1993
 
            }
1994
 
            else
1995
 
            {
1996
 
                d->currItem   = firstItem();
1997
 
                d->anchorItem = d->currItem;
1998
 
                d->currItem->setSelected(true, true);
1999
 
                item = d->currItem;
2000
 
            }
2001
 
 
2002
 
            ensureItemVisible(item);
2003
 
            handled = true;
2004
 
            break;
2005
 
        }
2006
 
 
2007
 
        case Qt::Key_PageUp:
2008
 
        {
2009
 
            IconItem* item = 0;
2010
 
 
2011
 
            if (d->currItem)
2012
 
            {
2013
 
                QRect r(0, d->currItem->y() - visibleHeight(),
2014
 
                        contentsWidth(), visibleHeight());
2015
 
 
2016
 
                IconItem* ni = findFirstVisibleItem(r, false);
2017
 
 
2018
 
                if (!ni)
2019
 
                {
2020
 
                    r = QRect(0, 0, contentsWidth(), d->currItem->y());
2021
 
                    ni = findFirstVisibleItem(r, false);
2022
 
                }
2023
 
 
2024
 
                if (ni)
2025
 
                {
2026
 
                    IconItem* tmp = d->currItem;
2027
 
                    d->currItem   = ni;
2028
 
                    d->anchorItem = ni;
2029
 
                    item          = ni;
2030
 
                    tmp->repaint();
2031
 
                    d->currItem->setSelected(true, true);
2032
 
                }
2033
 
            }
2034
 
            else
2035
 
            {
2036
 
                d->currItem   = firstItem();
2037
 
                d->anchorItem = d->currItem;
2038
 
                d->currItem->setSelected(true, true);
2039
 
                item = d->currItem;
2040
 
            }
2041
 
 
2042
 
            ensureItemVisible(item);
2043
 
            handled = true;
2044
 
            break;
2045
 
        }
2046
 
 
2047
 
        // Qt::Key_Space is used as a global shortcut in DigikamApp.
2048
 
        // Ctrl+Space comes through, Shift+Space is filtered out.
2049
 
        case Qt::Key_Space:
2050
 
        {
2051
 
            if (d->currItem)
2052
 
            {
2053
 
                if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier))
2054
 
                {
2055
 
                    d->currItem->setSelected(!d->currItem->isSelected(), false);
2056
 
                }
2057
 
                else
2058
 
                {
2059
 
                    if (!d->currItem->isSelected())
2060
 
                    {
2061
 
                        d->currItem->setSelected(true, true);
2062
 
                    }
2063
 
                }
2064
 
 
2065
 
                handled = true;
2066
 
            }
2067
 
 
2068
 
            break;
2069
 
        }
2070
 
 
2071
 
        case Qt::Key_Menu:
2072
 
        {
2073
 
            if (d->currItem)
2074
 
            {
2075
 
                if (!d->currItem->isSelected())
2076
 
                {
2077
 
                    d->currItem->setSelected(true, false);
2078
 
                }
2079
 
 
2080
 
                ensureItemVisible(d->currItem);
2081
 
 
2082
 
                QRect r(itemRect());
2083
 
                int w = r.width();
2084
 
                int h = r.height();
2085
 
                QPoint p(d->currItem->x() + w / 2, d->currItem->y() + h / 2);
2086
 
 
2087
 
                emit signalRightButtonClicked(d->currItem, mapToGlobal(contentsToViewport(p)));
2088
 
            }
2089
 
 
2090
 
            break;
2091
 
        }
2092
 
 
2093
 
        default:
2094
 
            break;
2095
 
    }
2096
 
 
2097
 
    if (!handled)
2098
 
    {
2099
 
        e->ignore();
2100
 
    }
2101
 
    else
2102
 
    {
2103
 
        if (d->highlightedItem)
2104
 
        {
2105
 
            d->highlightedItem->setHighlighted(false);
2106
 
            d->highlightedItem = 0;
2107
 
        }
2108
 
 
2109
 
        if (d->ratingItem)
2110
 
        {
2111
 
            d->ratingItem->setEditRating(false);
2112
 
            d->ratingItem = 0;
2113
 
            unsetCursor();
2114
 
            d->ratingWidget->hide();
2115
 
        }
2116
 
 
2117
 
        emit signalSelectionChanged();
2118
 
        viewport()->update();
2119
 
        d->toolTipItem = 0;
2120
 
        d->toolTipTimer->stop();
2121
 
        slotToolTip();
2122
 
    }
2123
 
}
2124
 
 
2125
 
bool IconView::anchorIsBehind() const
2126
 
{
2127
 
    if (!d->anchorItem || !d->currItem)
2128
 
    {
2129
 
        return false;
2130
 
    }
2131
 
 
2132
 
    for (IconItem* it = d->anchorItem; it; it = it->nextItem())
2133
 
    {
2134
 
        if (it == d->currItem)
2135
 
        {
2136
 
            return true;
2137
 
        }
2138
 
    }
2139
 
 
2140
 
    return false;
2141
 
}
2142
 
 
2143
 
 
2144
 
void IconView::startDrag()
2145
 
{
2146
 
}
2147
 
 
2148
 
void IconView::ensureItemVisible(IconItem* item)
2149
 
{
2150
 
    if (!item)
2151
 
    {
2152
 
        return;
2153
 
    }
2154
 
 
2155
 
    if (item->y() == firstItem()->y())
2156
 
    {
2157
 
        QRect r(itemRect());
2158
 
        int w = r.width();
2159
 
        ensureVisible(item->x() + w / 2, 0, w / 2 + 1, 0);
2160
 
    }
2161
 
    else
2162
 
    {
2163
 
        QRect r(itemRect());
2164
 
        int w = r.width();
2165
 
        int h = r.height();
2166
 
        ensureVisible(item->x() + w / 2, item->y() + h / 2,
2167
 
                      w / 2 + 1, h / 2 + 1);
2168
 
    }
2169
 
}
2170
 
 
2171
 
IconItem* IconView::findFirstVisibleItem(bool useThumbnailRect) const
2172
 
{
2173
 
    QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
2174
 
    return findFirstVisibleItem(r, useThumbnailRect);
2175
 
}
2176
 
 
2177
 
IconItem* IconView::findLastVisibleItem(bool useThumbnailRect) const
2178
 
{
2179
 
    QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
2180
 
    return findLastVisibleItem(r, useThumbnailRect);
2181
 
}
2182
 
 
2183
 
IconItem* IconView::findFirstVisibleItem(const QRect& r, bool useThumbnailRect) const
2184
 
{
2185
 
    IconViewPriv::ItemContainer* c = d->firstContainer;
2186
 
    bool alreadyIntersected = false;
2187
 
    IconItem* i = 0;
2188
 
 
2189
 
    for (; c; c = c->next)
2190
 
    {
2191
 
        if (c->rect.intersects(r))
2192
 
        {
2193
 
            alreadyIntersected = true;
2194
 
            foreach(IconItem* item, c->items)
2195
 
            {
2196
 
                // if useThumbnailRect, we only check for the clickToOpenRect, which is the thumbnail,
2197
 
                // otherwise, we take the whole item rect
2198
 
                if (r.intersects(useThumbnailRect ? item->clickToOpenRect() : item->rect()))
2199
 
                {
2200
 
                    if (!i)
2201
 
                    {
2202
 
                        i = item;
2203
 
                    }
2204
 
                    else
2205
 
                    {
2206
 
                        QRect r2 = item->rect();
2207
 
                        QRect r3 = i->rect();
2208
 
 
2209
 
                        if (r2.y() < r3.y())
2210
 
                        {
2211
 
                            i = item;
2212
 
                        }
2213
 
                        else if (r2.y() == r3.y() &&
2214
 
                                 r2.x() < r3.x())
2215
 
                        {
2216
 
                            i = item;
2217
 
                        }
2218
 
                    }
2219
 
                }
2220
 
            }
2221
 
        }
2222
 
        else
2223
 
        {
2224
 
            if (alreadyIntersected)
2225
 
            {
2226
 
                break;
2227
 
            }
2228
 
        }
2229
 
    }
2230
 
 
2231
 
    return i;
2232
 
}
2233
 
 
2234
 
IconItem* IconView::findLastVisibleItem(const QRect& r, bool useThumbnailRect) const
2235
 
{
2236
 
    IconViewPriv::ItemContainer* c = d->firstContainer;
2237
 
    IconItem* i = 0;
2238
 
    bool alreadyIntersected = false;
2239
 
 
2240
 
    for (; c; c = c->next)
2241
 
    {
2242
 
        if (c->rect.intersects(r))
2243
 
        {
2244
 
            alreadyIntersected = true;
2245
 
            foreach(IconItem* item, c->items)
2246
 
            {
2247
 
                if (r.intersects(useThumbnailRect ? item->clickToOpenRect() : item->rect()))
2248
 
                {
2249
 
                    if (!i)
2250
 
                    {
2251
 
                        i = item;
2252
 
                    }
2253
 
                    else
2254
 
                    {
2255
 
                        QRect r2 = item->rect();
2256
 
                        QRect r3 = i->rect();
2257
 
 
2258
 
                        if (r2.y() > r3.y())
2259
 
                        {
2260
 
                            i = item;
2261
 
                        }
2262
 
                        else if (r2.y() == r3.y() &&
2263
 
                                 r2.x() > r3.x())
2264
 
                        {
2265
 
                            i = item;
2266
 
                        }
2267
 
                    }
2268
 
                }
2269
 
            }
2270
 
        }
2271
 
        else
2272
 
        {
2273
 
            if (alreadyIntersected)
2274
 
            {
2275
 
                break;
2276
 
            }
2277
 
        }
2278
 
    }
2279
 
 
2280
 
    return i;
2281
 
}
2282
 
 
2283
 
void IconView::drawFrameRaised(QPainter* p)
2284
 
{
2285
 
    QRect r               = frameRect();
2286
 
    int lwidth            = lineWidth();
2287
 
    const QColorGroup& g = QColorGroup(palette());
2288
 
    qDrawShadeRect(p, r, g, false, lwidth, midLineWidth());
2289
 
}
2290
 
 
2291
 
void IconView::drawFrameSunken(QPainter* p)
2292
 
{
2293
 
    QRect r               = frameRect();
2294
 
    int lwidth            = lineWidth();
2295
 
    const QColorGroup& g = QColorGroup(palette());
2296
 
    qDrawShadeRect(p, r, g, true, lwidth, midLineWidth());
2297
 
}
2298
 
 
2299
 
void IconView::setEnableToolTips(bool val)
2300
 
{
2301
 
    d->showTips = val;
2302
 
 
2303
 
    if (!val)
2304
 
    {
2305
 
        d->toolTipItem = 0;
2306
 
        d->toolTipTimer->stop();
2307
 
        slotToolTip();
2308
 
    }
2309
 
}
2310
 
 
2311
 
void IconView::slotToolTip()
2312
 
{
2313
 
    emit signalShowToolTip(d->toolTipItem);
2314
 
}
2315
 
 
2316
 
void IconView::itemClickedToOpen(IconItem* item)
2317
 
{
2318
 
    if (!item)
2319
 
    {
2320
 
        return;
2321
 
    }
2322
 
 
2323
 
    IconItem* prevCurrItem = d->currItem;
2324
 
    d->currItem            = item;
2325
 
    d->anchorItem          = item;
2326
 
 
2327
 
    if (prevCurrItem)
2328
 
    {
2329
 
        prevCurrItem->repaint();
2330
 
    }
2331
 
 
2332
 
    item->setSelected(true);
2333
 
    emit signalDoubleClicked(item);
2334
 
}
2335
 
 
2336
 
int IconView::cmpItems(const void* n1, const void* n2)
2337
 
{
2338
 
    if (!n1 || !n2)
2339
 
    {
2340
 
        return 0;
2341
 
    }
2342
 
 
2343
 
    IconViewPriv::SortableItem* i1 = (IconViewPriv::SortableItem*)n1;
2344
 
    IconViewPriv::SortableItem* i2 = (IconViewPriv::SortableItem*)n2;
2345
 
 
2346
 
    return i1->group->compare(i2->group);
2347
 
}
2348
 
 
2349
 
QPixmap IconView::thumbnailBorderPixmap(const QSize& pixSize)
2350
 
{
2351
 
    const int radius         = 3;
2352
 
    const QColor borderColor = QColor(0, 0, 0, 128);
2353
 
 
2354
 
    QString cacheKey  = QString::number(pixSize.width()) + '-' + QString::number(pixSize.height());
2355
 
    QPixmap* cachePix = d->thumbnailBorderCache.object(cacheKey);
2356
 
 
2357
 
    if (!cachePix)
2358
 
    {
2359
 
        QPixmap pix = ThumbBarView::generateFuzzyRect(QSize(pixSize.width()  + 2 * radius,
2360
 
                                                            pixSize.height() + 2 * radius),
2361
 
                                                      borderColor, radius);
2362
 
        d->thumbnailBorderCache.insert(cacheKey, new QPixmap(pix));
2363
 
        return pix;
2364
 
    }
2365
 
 
2366
 
    return *cachePix;
2367
 
}
2368
 
 
2369
 
void IconView::clearThumbnailBorderCache()
2370
 
{
2371
 
    d->thumbnailBorderCache.clear();
2372
 
}
2373
 
 
2374
 
QPixmap IconView::selectPixmap() const
2375
 
{
2376
 
    return d->selectPix;
2377
 
}
2378
 
 
2379
 
QPixmap IconView::deselectPixmap() const
2380
 
{
2381
 
    return d->deselectPix;
2382
 
}
2383
 
 
2384
 
void IconView::slotIconViewFontChanged()
2385
 
{
2386
 
    setFont(AlbumSettings::instance()->getIconViewFont());
2387
 
}
2388
 
 
2389
 
}  // namespace Digikam