~ubuntu-branches/ubuntu/feisty/digikam/feisty

« back to all changes in this revision

Viewing changes to digikam/digikam/thumbview.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Achim Bohnet
  • Date: 2005-03-10 02:39:02 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050310023902-023nymfst5mg696c
Tags: 0.7.2-2
* debian/TODO: clean
* digikam manpage: better --detect-camera description

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ============================================================
 
2
 * Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
 
3
 * Copyright 2002-2004 by Renchi Raju
 
4
 *
 
5
 * This program is free software; you can redistribute it
 
6
 * and/or modify it under the terms of the GNU General
 
7
 * Public License as published by the Free Software Foundation;
 
8
 * either version 2, or (at your option)
 
9
 * any later version.
 
10
 * 
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 * ============================================================ */
 
16
 
 
17
#include <qpainter.h>
 
18
#include <qrect.h>
 
19
#include <qpoint.h>
 
20
#include <qsize.h>
 
21
#include <qevent.h>
 
22
#include <qstring.h>
 
23
#include <qstyle.h>
 
24
#include <qpixmap.h>
 
25
#include <qptrlist.h>
 
26
#include <qcursor.h>
 
27
#include <qtimer.h>
 
28
#include <qdragobject.h>
 
29
#include <qstrlist.h>
 
30
#include <qapplication.h>
 
31
#include <qdrawutil.h>
 
32
 
 
33
#include <kdebug.h>
 
34
#include <kcursor.h>
 
35
#include <kglobalsettings.h>
 
36
 
 
37
#include <stdlib.h>
 
38
#include <iostream>
 
39
 
 
40
// To get INT_MAX
 
41
extern "C" {
 
42
#include <limits.h>
 
43
}
 
44
 
 
45
#include "thumbitem.h"
 
46
#include "thumbview.h"
 
47
 
 
48
 
 
49
#define RECT_EXTENSION 300
 
50
 
 
51
class ThumbViewPrivate {
 
52
 
 
53
public:
 
54
 
 
55
    ThumbItem *firstItem;
 
56
    ThumbItem *lastItem;
 
57
 
 
58
    int spacing;
 
59
    int count;
 
60
    
 
61
    bool clearing;
 
62
    bool pressedMoved;
 
63
    
 
64
    QRect banner;
 
65
    QRect *rubber;
 
66
    QPoint dragStartPos;
 
67
 
 
68
    QPtrList<ThumbItem>    selectedItems;
 
69
    QPtrList<ThumbItem>    prevSelectedItems;
 
70
 
 
71
    QTimer* updateTimer;
 
72
 
 
73
    struct ItemContainer {
 
74
        ItemContainer(ItemContainer *p, ItemContainer *n,
 
75
                      const QRect &r)
 
76
            : prev(p), next(n), rect(r) {
 
77
 
 
78
            items.setAutoDelete(false);
 
79
            if (prev)
 
80
                prev->next = this;
 
81
            if (next)
 
82
                next->prev = this;
 
83
        }
 
84
        
 
85
        ItemContainer *prev, *next;
 
86
        QRect rect;
 
87
        QPtrList<ThumbItem> items;
 
88
 
 
89
    } *firstContainer, *lastContainer;
 
90
 
 
91
    ThumbItem *startDragItem;
 
92
 
 
93
    struct SortableItem {
 
94
        ThumbItem *item;
 
95
    };   
 
96
 
 
97
    ThumbItem* toolTipItem;
 
98
    QTimer*    toolTipTimer;
 
99
    bool       showTips;
 
100
};
 
101
 
 
102
 
 
103
static int cmpItems( const void *n1, const void *n2 )
 
104
{
 
105
    if ( !n1 || !n2 )
 
106
        return 0;
 
107
 
 
108
    ThumbViewPrivate::SortableItem *i1 = (ThumbViewPrivate::SortableItem *)n1;
 
109
    ThumbViewPrivate::SortableItem *i2 = (ThumbViewPrivate::SortableItem *)n2;
 
110
 
 
111
    return i1->item->compare( i2->item );
 
112
}
 
113
 
 
114
 
 
115
ThumbView::ThumbView(QWidget* parent, const char* name,
 
116
                     WFlags fl)
 
117
    : QScrollView(parent, name, Qt::WStaticContents | fl)
 
118
{
 
119
    setBackgroundMode(Qt::NoBackground);
 
120
    viewport()->setBackgroundMode(Qt::NoBackground);
 
121
    viewport()->setFocusProxy(this);
 
122
    viewport()->setFocusPolicy(QWidget::WheelFocus);
 
123
    viewport()->setMouseTracking(true);
 
124
    
 
125
    renamingItem = 0;
 
126
    
 
127
    d = new ThumbViewPrivate;
 
128
    d->firstItem = 0;
 
129
    d->lastItem  = 0;
 
130
    d->spacing = 5;
 
131
    d->count = 0;
 
132
    d->clearing = false;
 
133
    d->pressedMoved = false;
 
134
 
 
135
    d->rubber = 0;
 
136
    d->banner = QRect(0, 0, 0, 0);
 
137
 
 
138
    d->firstContainer = 0;
 
139
    d->lastContainer  = 0;
 
140
    d->selectedItems.setAutoDelete(false);
 
141
    d->updateTimer = new QTimer(this);
 
142
    d->startDragItem = 0;
 
143
 
 
144
    d->toolTipTimer = new QTimer();
 
145
    d->toolTipItem  = 0;
 
146
    
 
147
    connect(d->updateTimer, SIGNAL(timeout()),
 
148
            SLOT(slotUpdate()));
 
149
    connect(d->toolTipTimer, SIGNAL(timeout()),
 
150
            SLOT(slotToolTip()));
 
151
 
 
152
    setEnableToolTips(true);
 
153
}
 
154
 
 
155
ThumbView::~ThumbView()
 
156
{
 
157
    clear(false);
 
158
 
 
159
    if (d->rubber)
 
160
        delete d->rubber;
 
161
    
 
162
    delete d->updateTimer;
 
163
    delete d->toolTipTimer;
 
164
    delete d;
 
165
}
 
166
 
 
167
void ThumbView::clear(bool update)
 
168
{
 
169
    d->clearing = true;
 
170
 
 
171
    renamingItem = 0;
 
172
 
 
173
    d->toolTipItem = 0;
 
174
    d->toolTipTimer->stop();
 
175
    slotToolTip();
 
176
 
 
177
    deleteContainers();
 
178
    d->selectedItems.clear();
 
179
    emit signalSelectionChanged();
 
180
 
 
181
    ThumbItem *item = d->firstItem;
 
182
    while (item) {
 
183
        ThumbItem *tmp = item->next;
 
184
        delete item;
 
185
        item = tmp;
 
186
    }
 
187
 
 
188
    d->firstItem = 0;
 
189
    d->lastItem = 0;
 
190
 
 
191
    d->banner = QRect(0, 0, 0, 0);
 
192
 
 
193
    viewport()->setUpdatesEnabled(false);
 
194
    resizeContents(0, 0);
 
195
    setContentsPos(0, 0);
 
196
    viewport()->setUpdatesEnabled(true);
 
197
 
 
198
    if (update)
 
199
        updateContents();
 
200
 
 
201
    d->clearing = false;
 
202
}
 
203
 
 
204
int ThumbView::count()
 
205
{
 
206
    return d->count;    
 
207
}
 
208
 
 
209
int ThumbView::index(ThumbItem* item)
 
210
{
 
211
    if ( !item )
 
212
        return -1;
 
213
 
 
214
    if ( item == d->firstItem )
 
215
        return 0;
 
216
    else if ( item == d->lastItem )
 
217
        return d->count - 1;
 
218
    else {
 
219
        ThumbItem *i = d->firstItem;
 
220
        int j = 0;
 
221
        while ( i && i != item ) {
 
222
            i = i->next;
 
223
            ++j;
 
224
        }
 
225
 
 
226
        return i ? j : -1;
 
227
    }
 
228
}
 
229
 
 
230
ThumbItem* ThumbView::firstItem()
 
231
{
 
232
    return d->firstItem;
 
233
}
 
234
 
 
235
ThumbItem* ThumbView::lastItem()
 
236
{
 
237
    return d->lastItem;
 
238
}
 
239
 
 
240
void ThumbView::insertItem(ThumbItem *item)
 
241
{
 
242
    if (!item) return;
 
243
 
 
244
    if (!d->firstItem) {
 
245
        d->firstItem = item;
 
246
        d->lastItem = item;
 
247
        item->prev = 0;
 
248
        item->next = 0;
 
249
    }
 
250
    else {
 
251
        d->lastItem->next = item;
 
252
        item->prev = d->lastItem;
 
253
        item->next = 0;
 
254
        d->lastItem = item;
 
255
    }
 
256
 
 
257
    d->count++;
 
258
    
 
259
    // this way one can insert items in a loop
 
260
    // without too many paintevents
 
261
    d->updateTimer->start(0, true);
 
262
    
 
263
}
 
264
 
 
265
void ThumbView::takeItem(ThumbItem *item)
 
266
{
 
267
    if (!item) return;
 
268
 
 
269
    d->count--;
 
270
    
 
271
    // First remove item from any containers holding it
 
272
    ThumbViewPrivate::ItemContainer *tmp = d->firstContainer;
 
273
    while (tmp) {
 
274
        tmp->items.remove(item);
 
275
        tmp = tmp->next;
 
276
    }
 
277
 
 
278
    // Remove from selected item list
 
279
    d->selectedItems.remove(item);
 
280
 
 
281
    if (d->toolTipItem == item)
 
282
    {
 
283
        d->toolTipItem = 0;
 
284
        d->toolTipTimer->stop();
 
285
        slotToolTip();
 
286
    }
 
287
    
 
288
    if (item == d->firstItem) {
 
289
        d->firstItem = d->firstItem->next;
 
290
        if (d->firstItem)
 
291
            d->firstItem->prev = 0;
 
292
        else
 
293
            d->firstItem = d->lastItem = 0;
 
294
    }
 
295
    else if (item == d->lastItem) {
 
296
        d->lastItem = d->lastItem->prev;
 
297
        if ( d->lastItem )
 
298
            d->lastItem->next = 0;
 
299
        else
 
300
            d->firstItem = d->lastItem = 0;
 
301
    } else {
 
302
        ThumbItem *i = item;
 
303
        if (i) {
 
304
            if (i->prev )
 
305
                i->prev->next = i->next;
 
306
            if ( i->next )
 
307
                i->next->prev = i->prev;
 
308
        }
 
309
    }
 
310
 
 
311
    if (!d->clearing) {
 
312
        QRect r(contentsRectToViewport(item->rect())); 
 
313
        viewport()->repaint(r);
 
314
    }
 
315
    
 
316
}
 
317
 
 
318
void ThumbView::slotUpdate()
 
319
{
 
320
    d->updateTimer->stop();
 
321
    sort();
 
322
    rearrangeItems();
 
323
}
 
324
 
 
325
void ThumbView::sort()
 
326
{
 
327
    ThumbViewPrivate::SortableItem *items
 
328
        = new ThumbViewPrivate::SortableItem[ count() ];
 
329
 
 
330
    ThumbItem *item = d->firstItem;
 
331
    int i = 0;
 
332
    for ( ; item; item = item->next )
 
333
        items[ i++ ].item = item;
 
334
 
 
335
    qsort( items, count(), sizeof( ThumbViewPrivate::SortableItem ), cmpItems );
 
336
 
 
337
    ThumbItem *prev = 0;
 
338
    item = 0;
 
339
    for ( i = 0; i < (int)count(); ++i ) {
 
340
        item = items[ i ].item;
 
341
        if ( item ) {
 
342
            item->prev = prev;
 
343
            if ( item->prev )
 
344
                item->prev->next = item;
 
345
            item->next = 0;
 
346
        }
 
347
        if ( i == 0 )
 
348
            d->firstItem = item;
 
349
        if ( i == (int)count() - 1 )
 
350
            d->lastItem = item;
 
351
        prev = item;
 
352
    }
 
353
 
 
354
    delete [] items;
 
355
    
 
356
}
 
357
 
 
358
void ThumbView::setEnableToolTips(bool val)
 
359
{
 
360
    d->showTips = val;
 
361
    if (!val) {
 
362
        d->toolTipItem = 0;
 
363
        d->toolTipTimer->stop();
 
364
        slotToolTip();
 
365
    }
 
366
}
 
367
 
 
368
void ThumbView::slotToolTip()
 
369
{
 
370
    emit signalShowToolTip(d->toolTipItem);
 
371
}
 
372
 
 
373
void ThumbView::viewportPaintEvent(QPaintEvent *pe)
 
374
{
 
375
    QRect r(pe->rect());
 
376
    QRegion paintRegion(pe->region());
 
377
 
 
378
    QPainter painter(viewport());
 
379
    painter.setClipRegion(paintRegion);
 
380
 
 
381
    QRect br(contentsRectToViewport(d->banner));
 
382
 
 
383
 
 
384
    if (br.intersects(r)) {
 
385
        painter.save();
 
386
        QRegion clip(br.intersect(r));
 
387
        painter.setClipRegion(clip);
 
388
        paintBanner(&painter);
 
389
        painter.restore();
 
390
        paintRegion -= QRect(br);
 
391
    }
 
392
 
 
393
    ThumbViewPrivate::ItemContainer *c = d->firstContainer;
 
394
    for ( ; c; c = c->next) {
 
395
 
 
396
        QRect cr(contentsRectToViewport(c->rect));
 
397
        
 
398
        if (r.intersects(cr)) {
 
399
        
 
400
            ThumbItem *item = c->items.first();
 
401
            for ( ; item; item = c->items.next()) {
 
402
 
 
403
                QRect ir(contentsRectToViewport(item->rect()));
 
404
 
 
405
                if (r.intersects(ir)) {
 
406
 
 
407
                    item->paintItem(&painter, colorGroup());
 
408
 
 
409
                    paintRegion -= QRegion(ir);
 
410
                }
 
411
            }
 
412
        }
 
413
    }
 
414
 
 
415
 
 
416
        
 
417
    painter.setClipRegion(paintRegion);
 
418
    painter.fillRect(r, colorGroup().base());
 
419
 
 
420
 
 
421
    painter.end();
 
422
 
 
423
}
 
424
 
 
425
void ThumbView::resizeEvent(QResizeEvent* e)
 
426
{
 
427
    QScrollView::resizeEvent(e);
 
428
    rearrangeItems();
 
429
}
 
430
 
 
431
void ThumbView::rearrangeItems(bool update)
 
432
{
 
433
    if (!d->firstItem || !d->lastItem)
 
434
        return;
 
435
 
 
436
    calcBanner();
 
437
    int w = 0, h = 0, y = d->banner.height() + d->spacing;
 
438
 
 
439
    ThumbItem *item = d->firstItem;
 
440
    bool changedLayout = false;
 
441
 
 
442
    while (item) {
 
443
        bool changed;
 
444
        ThumbItem *next = makeRow(item, y, changed);
 
445
        changedLayout = changed || changedLayout;
 
446
        item = next;
 
447
        w = QMAX(w, item->x() + item->width());
 
448
        h = QMAX(h, item->y() + item->height());
 
449
        h = QMAX(h, y);
 
450
 
 
451
        if ( !item || !item->next )
 
452
            break;
 
453
 
 
454
        item = item->next;
 
455
    }
 
456
 
 
457
    w = QMAX(w, d->lastItem->x() + d->lastItem->width());
 
458
    h = QMAX(h, d->lastItem->y() + d->lastItem->height());
 
459
 
 
460
    int vw = visibleWidth();
 
461
 
 
462
    viewport()->setUpdatesEnabled(false);
 
463
    resizeContents( w, h );
 
464
    bool doAgain = visibleWidth() != vw;
 
465
    if (doAgain)
 
466
        rearrangeItems(false);
 
467
    viewport()->setUpdatesEnabled(true);
 
468
 
 
469
    
 
470
    rebuildContainers();
 
471
 
 
472
    if (changedLayout && update) {
 
473
        viewport()->update();
 
474
    }
 
475
    else 
 
476
        repaintBanner();
 
477
 
 
478
}
 
479
 
 
480
void ThumbView::triggerUpdate()
 
481
{
 
482
    d->updateTimer->start(0, true);    
 
483
}
 
484
 
 
485
ThumbItem* ThumbView::makeRow(ThumbItem *begin, int &y, bool &changed)
 
486
{
 
487
    ThumbItem *end = 0;
 
488
 
 
489
    changed = false;
 
490
 
 
491
 
 
492
    // first calculate the row height
 
493
    int h = 0;
 
494
    int x = 0;
 
495
 
 
496
    ThumbItem *item = begin;
 
497
    for (;;) {
 
498
        x += d->spacing + item->width();
 
499
        //int maxW = visibleWidth();
 
500
        int maxW = frameRect().width() - 20;
 
501
        if (x  > maxW && item != begin) {
 
502
            item = item->prev;
 
503
            break;
 
504
        }
 
505
        h = QMAX(h, item->height());
 
506
 
 
507
        ThumbItem *old = item;
 
508
        item = item->next;
 
509
        if (!item) {
 
510
            item = old;
 
511
            break;
 
512
        }
 
513
    }
 
514
    end = item;
 
515
 
 
516
 
 
517
    // now move the items
 
518
    item = begin;
 
519
    for (;;) {
 
520
        int x;
 
521
        if ( item == begin ) {
 
522
            x = d->spacing;
 
523
        }
 
524
        else {
 
525
            x = item->prev->x() + item->prev->width() + d->spacing;
 
526
        }
 
527
        changed = item->move(x, y) || changed;
 
528
        if ( item == end )
 
529
            break;
 
530
        item = item->next;
 
531
    }
 
532
 
 
533
    y += h + d->spacing;
 
534
    return end;
 
535
 
 
536
}
 
537
 
 
538
void ThumbView::repaintBanner()
 
539
{
 
540
    if (d->banner.isEmpty() || d->banner.isNull())
 
541
         return;
 
542
    QRect br(contentsRectToViewport(d->banner));
 
543
                                
 
544
    viewport()->repaint(br);
 
545
}
 
546
 
 
547
void ThumbView::calcBanner()
 
548
{
 
549
    d->banner.setRect(0, 0, 0, 0);
 
550
    
 
551
}
 
552
 
 
553
void ThumbView::paintBanner(QPainter *)
 
554
{
 
555
    return;
 
556
}
 
557
 
 
558
void ThumbView::setBannerRect(const QRect& r)
 
559
{
 
560
    d->banner = r;
 
561
}
 
562
 
 
563
QRect ThumbView::bannerRect()
 
564
{
 
565
    return d->banner;
 
566
}
 
567
 
 
568
 
 
569
void ThumbView::drawRubber(QPainter *p)
 
570
{
 
571
    if ( !p || !d->rubber )
 
572
        return;
 
573
 
 
574
    QRect r(d->rubber->normalize());
 
575
 
 
576
    r = contentsRectToViewport(r);
 
577
 
 
578
    QPoint pnt(r.x(), r.y());
 
579
 
 
580
    style().drawPrimitive(QStyle::PE_FocusRect, p,
 
581
                          QRect( pnt.x(), pnt.y(),
 
582
                                 r.width(), r.height() ),
 
583
                          colorGroup(), QStyle::Style_Default,
 
584
                          QStyleOption(colorGroup().base()));
 
585
 
 
586
}
 
587
 
 
588
void ThumbView::leaveEvent(QEvent *e)
 
589
{
 
590
    // hide tooltip
 
591
 
 
592
    d->toolTipItem = 0;
 
593
    d->toolTipTimer->stop();
 
594
    slotToolTip();
 
595
 
 
596
    // nullify the d->startDragItem if the mouse
 
597
    // leaves the widget
 
598
    
 
599
    d->startDragItem = 0;
 
600
    
 
601
    QScrollView::leaveEvent(e);
 
602
}
 
603
 
 
604
void ThumbView::focusOutEvent(QFocusEvent *e)
 
605
{
 
606
    // hide tooltip
 
607
 
 
608
    d->toolTipItem = 0;
 
609
    d->toolTipTimer->stop();
 
610
    slotToolTip();
 
611
 
 
612
    QScrollView::focusOutEvent(e);
 
613
}
 
614
 
 
615
void ThumbView::drawFrameRaised(QPainter* p)
 
616
{
 
617
    QRect       r      = frameRect();
 
618
    int         lwidth = lineWidth();
 
619
 
 
620
    const QColorGroup & g = colorGroup();
 
621
 
 
622
    qDrawShadeRect( p, r, g, false, lwidth,
 
623
                    midLineWidth() );
 
624
}
 
625
 
 
626
void ThumbView::drawFrameSunken(QPainter* p)
 
627
{
 
628
    QRect       r      = frameRect();
 
629
    int         lwidth = lineWidth();
 
630
 
 
631
    const QColorGroup & g = colorGroup();
 
632
 
 
633
    qDrawShadeRect( p, r, g, true, lwidth,
 
634
                    midLineWidth() );
 
635
}
 
636
 
 
637
void ThumbView::contentsMousePressEvent(QMouseEvent *e)
 
638
{
 
639
 
 
640
    // If renaming any item, cancel it --------------------------
 
641
    if (renamingItem)
 
642
        renamingItem->cancelRenameItem();
 
643
 
 
644
    // hide tooltip
 
645
 
 
646
    d->toolTipItem = 0;
 
647
    d->toolTipTimer->stop();
 
648
    slotToolTip();
 
649
 
 
650
    
 
651
    // Delete any existing rubber -------------------------------
 
652
 
 
653
    if ( d->rubber ) {
 
654
           QPainter p;
 
655
           p.begin(viewport());
 
656
           p.setRasterOp(NotROP);
 
657
           p.setPen(QPen(color0, 1));
 
658
           p.setBrush(NoBrush);
 
659
    
 
660
           drawRubber(&p);
 
661
           p.end();
 
662
           delete d->rubber;
 
663
           d->rubber = 0;
 
664
    }
 
665
 
 
666
    d->dragStartPos = e->pos();
 
667
    
 
668
    ThumbItem *item = findItem(e->pos());
 
669
    if (item) {
 
670
 
 
671
        if (e->state() & Qt::ControlButton) {
 
672
            
 
673
            item->setSelected(!item->isSelected(), false);
 
674
                
 
675
        }
 
676
        else if (e->state() & Qt::ShiftButton) {
 
677
 
 
678
            // different selection mode than the Trolls
 
679
 
 
680
            ThumbItem *lastSelectedItem = 0;
 
681
 
 
682
            bool bwdSelection = false;
 
683
                
 
684
            // first go backwards
 
685
            for (ThumbItem *it = item->prev; it; it = it->prev) {
 
686
                if (it->isSelected()) {
 
687
                    lastSelectedItem = it;
 
688
                    bwdSelection = true;
 
689
                    break;
 
690
                }
 
691
            }
 
692
                
 
693
            bool fwdSelection = false;
 
694
                
 
695
            if (!lastSelectedItem) {
 
696
                // Now go forward
 
697
                for (ThumbItem *it = item->next; it; it = it->next) {
 
698
                    if (it->isSelected()) {
 
699
                        lastSelectedItem = it;
 
700
                        fwdSelection = true;
 
701
                        break;
 
702
                    }
 
703
                }
 
704
            }
 
705
 
 
706
            blockSignals(true);
 
707
            
 
708
            if (bwdSelection) {
 
709
                for (ThumbItem *it = lastSelectedItem;
 
710
                     it && it != item->next; it = it->next) {
 
711
                    if (!it->isSelected()) {
 
712
                        it->setSelected(true, false);
 
713
                    }
 
714
                }
 
715
            }
 
716
            else if (fwdSelection) {
 
717
                for (ThumbItem *it = item;
 
718
                     it && it != lastSelectedItem->next; it = it->next) {
 
719
                    if (!it->isSelected()) {
 
720
                        it->setSelected(true, false);
 
721
                    }
 
722
                }
 
723
            }
 
724
            else {
 
725
                item->setSelected(!item->isSelected(), false);
 
726
            }
 
727
 
 
728
            blockSignals(false);
 
729
            emit signalSelectionChanged();
 
730
 
 
731
        }
 
732
        else {
 
733
            if (!item->isSelected()) {
 
734
                item->setSelected(true, true);
 
735
            }
 
736
        }
 
737
 
 
738
        d->startDragItem = item;
 
739
        return;
 
740
    }
 
741
 
 
742
    // Press outside any item. unselect all if the ctrl button is not pressed
 
743
    if (!(e->state() & Qt::ControlButton))
 
744
    {
 
745
        clearSelection();
 
746
    }
 
747
    else
 
748
    {
 
749
        d->prevSelectedItems.clear();
 
750
        for (ThumbItem* item = d->selectedItems.first();
 
751
             item; item = d->selectedItems.next())
 
752
        {
 
753
            d->prevSelectedItems.append(item);
 
754
        }
 
755
    }
 
756
 
 
757
    // If not item then initiate rubber
 
758
    if ( d->rubber ) {
 
759
        delete d->rubber;
 
760
        d->rubber = 0;
 
761
    }
 
762
    d->rubber = new QRect( e->x(), e->y(), 0, 0 );
 
763
 
 
764
    QPainter p;
 
765
    p.begin( viewport() );
 
766
    p.setRasterOp( NotROP );
 
767
    p.setPen( QPen( color0, 1 ) );
 
768
    p.setBrush( NoBrush );
 
769
    drawRubber( &p );
 
770
    p.end();
 
771
 
 
772
    d->pressedMoved = false;
 
773
}
 
774
 
 
775
bool ThumbView::acceptToolTip(ThumbItem *, const QPoint &)
 
776
{
 
777
    return true;
 
778
}
 
779
 
 
780
void ThumbView::contentsMouseMoveEvent(QMouseEvent *e)
 
781
{
 
782
 
 
783
    if (!e) return;
 
784
    
 
785
    if (e->state() == NoButton )
 
786
    {
 
787
        ThumbItem* item = findItem(e->pos());
 
788
        
 
789
        if(d->showTips)
 
790
        {
 
791
            if (!isActiveWindow())
 
792
            {
 
793
                d->toolTipItem = 0;
 
794
                d->toolTipTimer->stop();
 
795
                slotToolTip();
 
796
                return;
 
797
            }
 
798
            
 
799
            if (item != d->toolTipItem)
 
800
            {
 
801
                d->toolTipItem = 0;
 
802
                d->toolTipTimer->stop();
 
803
                slotToolTip();
 
804
                
 
805
                if(acceptToolTip(item, e->pos()))
 
806
                {
 
807
                    d->toolTipItem = item;
 
808
                    d->toolTipTimer->start(500, true);
 
809
                }
 
810
            }
 
811
            
 
812
            if(item == d->toolTipItem && !acceptToolTip(item, e->pos()))
 
813
            {
 
814
                d->toolTipItem = 0;
 
815
                d->toolTipTimer->stop();
 
816
                slotToolTip();                
 
817
            }
 
818
        }
 
819
                
 
820
        if(KGlobalSettings::changeCursorOverIcon())
 
821
        {
 
822
            if(item)
 
823
                setCursor(KCursor::handCursor());
 
824
            else
 
825
                unsetCursor();
 
826
        }
 
827
        return;
 
828
    }
 
829
 
 
830
    d->toolTipItem  = 0;
 
831
    d->toolTipTimer->stop();
 
832
    slotToolTip();
 
833
    
 
834
    // Dragging ?
 
835
    if (d->startDragItem && 
 
836
       (e->state() ==  LeftButton || 
 
837
        e->state() == (LeftButton | ControlButton) ||
 
838
        e->state() == (LeftButton | ShiftButton) ))
 
839
    {
 
840
        if ( (d->dragStartPos - e->pos() ).manhattanLength()
 
841
             > QApplication::startDragDistance() ) 
 
842
        {
 
843
            startDrag();
 
844
        }
 
845
        return;
 
846
    }
 
847
    
 
848
    if (!d->rubber) return;
 
849
 
 
850
    QRect oldRubber = QRect(*d->rubber);
 
851
 
 
852
    d->rubber->setRight( e->pos().x() );
 
853
    d->rubber->setBottom( e->pos().y() );
 
854
 
 
855
    QRegion paintRegion;
 
856
 
 
857
    viewport()->setUpdatesEnabled(false);
 
858
 
 
859
    QRect nr(d->rubber->normalize());
 
860
    QRect rubberUnion = nr.unite(oldRubber.normalize());
 
861
 
 
862
 
 
863
    bool changed = false;
 
864
 
 
865
    blockSignals(true);
 
866
    
 
867
    ThumbViewPrivate::ItemContainer *c = d->lastContainer;
 
868
    for (; c; c = c->prev) {
 
869
        if ( rubberUnion.intersects(c->rect) ) {
 
870
            ThumbItem *item = c->items.last();
 
871
            for ( ; item; item = c->items.prev() ) {
 
872
                if (nr.intersects(item->rect())) {
 
873
                    if (!item->isSelected())
 
874
                    {
 
875
                        item->setSelected(true, false);
 
876
                        changed = true;
 
877
                        paintRegion += QRect(item->rect());
 
878
                    }
 
879
                }
 
880
                else {
 
881
                    if (item->isSelected() &&
 
882
                        d->prevSelectedItems.containsRef(item) == 0)
 
883
                    {
 
884
                        item->setSelected(false, false);
 
885
                        changed = true;
 
886
                        paintRegion += QRect(item->rect());
 
887
                    }
 
888
                }
 
889
            }
 
890
        }
 
891
    }
 
892
    
 
893
    blockSignals(false);
 
894
    viewport()->setUpdatesEnabled(true);
 
895
 
 
896
    QRect r = *d->rubber;
 
897
    *d->rubber = oldRubber;
 
898
 
 
899
    QPainter p;
 
900
    p.begin( viewport() );
 
901
    p.setRasterOp( NotROP );
 
902
    p.setPen( QPen( color0, 1 ) );
 
903
    p.setBrush( NoBrush );
 
904
    drawRubber( &p );
 
905
    p.end();
 
906
    
 
907
 
 
908
    if (changed) {
 
909
        emit signalSelectionChanged();
 
910
        paintRegion.translate(-contentsX(), -contentsY());
 
911
        viewport()->repaint(paintRegion);
 
912
    }
 
913
 
 
914
    ensureVisible(e->pos().x(), e->pos().y());
 
915
    
 
916
    *d->rubber = r;
 
917
 
 
918
    p.begin(viewport());
 
919
    p.setRasterOp(NotROP);
 
920
    p.setPen(QPen(color0, 1));
 
921
    p.setBrush(NoBrush);
 
922
    drawRubber(&p);
 
923
    p.end();
 
924
 
 
925
    d->pressedMoved = true;
 
926
}
 
927
 
 
928
void ThumbView::contentsMouseReleaseEvent(QMouseEvent *e)
 
929
{
 
930
    if (!e) return;
 
931
 
 
932
    d->startDragItem = 0;
 
933
 
 
934
    if (d->rubber) {
 
935
 
 
936
        QPainter p;
 
937
        p.begin( viewport() );
 
938
        p.setRasterOp( NotROP );
 
939
        p.setPen( QPen( color0, 1 ) );
 
940
        p.setBrush( NoBrush );
 
941
    
 
942
        drawRubber( &p );
 
943
        p.end();
 
944
 
 
945
        delete d->rubber;
 
946
        d->rubber = 0;
 
947
    }
 
948
 
 
949
    d->prevSelectedItems.clear();
 
950
    
 
951
    if (e->button() == Qt::RightButton) {
 
952
        ThumbItem *item = findItem(e->pos());
 
953
        if (item) 
 
954
            emit signalRightButtonClicked(item, e->globalPos());
 
955
        else
 
956
            emit signalRightButtonClicked(e->globalPos());
 
957
    }
 
958
    else if ((e->button() == Qt::LeftButton) &&
 
959
             !(e->state() & Qt::ShiftButton) &&
 
960
             !(e->state() & Qt::ControlButton)) {
 
961
        if (d->pressedMoved) {
 
962
            d->pressedMoved = false;
 
963
            return;
 
964
        }
 
965
        ThumbItem *item = findItem(e->pos());
 
966
        if (item)
 
967
        {
 
968
            item->setSelected(true, true);
 
969
            if(KGlobalSettings::singleClick())
 
970
                itemClickedToOpen(item);
 
971
        }
 
972
    }
 
973
}
 
974
 
 
975
void ThumbView::contentsMouseDoubleClickEvent(QMouseEvent *e)
 
976
{
 
977
    if(KGlobalSettings::singleClick())
 
978
        return;
 
979
    
 
980
    ThumbItem *item = findItem(e->pos());
 
981
    if (item) {
 
982
        itemClickedToOpen(item);
 
983
    }
 
984
}
 
985
 
 
986
void ThumbView::itemClickedToOpen(ThumbItem *item)
 
987
{
 
988
    if(!item)
 
989
        return;
 
990
    
 
991
    blockSignals(true);
 
992
    clearSelection();
 
993
    if (renamingItem)
 
994
        renamingItem->cancelRenameItem();
 
995
    blockSignals(false);
 
996
    item->setSelected(true);
 
997
    emit signalDoubleClicked(item);    
 
998
}
 
999
 
 
1000
void ThumbView::contentsWheelEvent(QWheelEvent *e)
 
1001
{
 
1002
    d->toolTipItem = 0;
 
1003
    d->toolTipTimer->stop();
 
1004
    slotToolTip();
 
1005
 
 
1006
    QScrollView::contentsWheelEvent(e);
 
1007
    viewport()->update();
 
1008
}
 
1009
 
 
1010
void ThumbView::rebuildContainers()
 
1011
{
 
1012
    deleteContainers();
 
1013
 
 
1014
    ThumbItem *item = d->firstItem;
 
1015
    appendContainer();
 
1016
 
 
1017
    ThumbViewPrivate::ItemContainer* c = d->lastContainer;
 
1018
    while (item) {
 
1019
        if (c->rect.contains(item->rect())) {
 
1020
            c->items.append(item);
 
1021
            item = item->next;
 
1022
        }
 
1023
        else if (c->rect.intersects(item->rect())) {
 
1024
            c->items.append( item );
 
1025
            c = c->next;
 
1026
            if (!c) {
 
1027
                appendContainer();
 
1028
                c = d->lastContainer;
 
1029
            }
 
1030
            c->items.append(item);
 
1031
            item = item->next;
 
1032
            c = c->prev;
 
1033
        }
 
1034
        else {
 
1035
            if (item->y() < c->rect.y() && c->prev) {
 
1036
                c = c->prev;
 
1037
                continue;
 
1038
            }
 
1039
 
 
1040
            c = c->next;
 
1041
            if (!c) {
 
1042
                appendContainer();
 
1043
                c = d->lastContainer;
 
1044
            }
 
1045
        }
 
1046
    }
 
1047
}
 
1048
 
 
1049
void ThumbView::appendContainer()
 
1050
{
 
1051
 
 
1052
    QSize s;
 
1053
    s = QSize( INT_MAX - 1, RECT_EXTENSION );
 
1054
 
 
1055
    if (!d->firstContainer) {
 
1056
        d->firstContainer =
 
1057
            new ThumbViewPrivate::ItemContainer(0, 0, QRect(QPoint(0, 0), s));
 
1058
        d->lastContainer = d->firstContainer;
 
1059
    }
 
1060
    else {
 
1061
        d->lastContainer = new ThumbViewPrivate::ItemContainer(
 
1062
            d->lastContainer, 0, QRect(d->lastContainer->rect.bottomLeft(), s));
 
1063
    }  
 
1064
}
 
1065
 
 
1066
void ThumbView::deleteContainers()
 
1067
{
 
1068
    ThumbViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
 
1069
    while (c) {
 
1070
        tmpc = c->next;
 
1071
        delete c;
 
1072
        c = tmpc;
 
1073
    }
 
1074
    d->firstContainer = d->lastContainer = 0;
 
1075
}
 
1076
 
 
1077
void ThumbView::updateItemContainer(ThumbItem *item)
 
1078
{
 
1079
    if (!item)  return;
 
1080
 
 
1081
    // First remove item from any containers holding it
 
1082
    ThumbViewPrivate::ItemContainer *tmp = d->firstContainer;
 
1083
    while (tmp) {
 
1084
        tmp->items.remove(item);
 
1085
        tmp = tmp->next;
 
1086
    }
 
1087
 
 
1088
    ThumbViewPrivate::ItemContainer *c = d->firstContainer;
 
1089
    if (!c) {
 
1090
        appendContainer();
 
1091
        c = d->firstContainer;
 
1092
    }
 
1093
 
 
1094
    const QRect ir = item->rect();
 
1095
    bool contains = false;
 
1096
    for (;;) {
 
1097
        if (c->rect.intersects(ir)) {
 
1098
            contains = c->rect.contains(ir);
 
1099
            break;
 
1100
        }
 
1101
 
 
1102
        c = c->next;
 
1103
        if (!c) {
 
1104
            appendContainer();
 
1105
            c = d->lastContainer;
 
1106
        }
 
1107
    }
 
1108
 
 
1109
    if ( !c ) {
 
1110
        return;
 
1111
    }
 
1112
 
 
1113
    c->items.append(item);
 
1114
 
 
1115
    if (!contains) {
 
1116
        c = c->next;
 
1117
        if (!c) {
 
1118
            appendContainer();
 
1119
            c = d->lastContainer;
 
1120
        }
 
1121
        c->items.append( item );
 
1122
    }
 
1123
 
 
1124
    if (contentsWidth() < ir.right() ||
 
1125
        contentsHeight() < ir.bottom())
 
1126
        resizeContents(QMAX(contentsWidth(), ir.right()),
 
1127
                       QMAX(contentsHeight(), ir.bottom()));
 
1128
    
 
1129
}
 
1130
 
 
1131
ThumbItem* ThumbView::findItem(const QPoint& pos)
 
1132
{
 
1133
    if ( !d->firstItem )
 
1134
        return 0;
 
1135
 
 
1136
    ThumbViewPrivate::ItemContainer *c = d->lastContainer;
 
1137
    for (; c; c = c->prev) {
 
1138
        if ( c->rect.contains(pos) ) {
 
1139
            ThumbItem *item = c->items.last();
 
1140
            for ( ; item; item = c->items.prev() )
 
1141
                if ( item->rect().contains( pos ) )
 
1142
                    return item;
 
1143
        }
 
1144
    }
 
1145
 
 
1146
    return 0;
 
1147
}
 
1148
 
 
1149
ThumbItem* ThumbView::findItem(const QString& text)
 
1150
{
 
1151
    if (!d->firstItem)
 
1152
        return 0;
 
1153
 
 
1154
    bool found = false;
 
1155
    
 
1156
    ThumbItem *item = 0;
 
1157
    for (item = d->firstItem; item; item = item->next) {
 
1158
        if (item->text() == text) {
 
1159
            found = true;
 
1160
            break;
 
1161
        }
 
1162
    }
 
1163
 
 
1164
    if (found)
 
1165
        return item;
 
1166
    else
 
1167
        return 0;
 
1168
    
 
1169
}
 
1170
 
 
1171
QRect ThumbView::contentsRectToViewport(const QRect& r)
 
1172
{
 
1173
    QRect vr = QRect(contentsToViewport(QPoint(r.x(), r.y())),
 
1174
                     r.size());
 
1175
    return vr;
 
1176
}
 
1177
 
 
1178
void ThumbView::clearSelection()
 
1179
{
 
1180
    blockSignals(true);
 
1181
    for (ThumbItem* item = d->firstItem; item; item = item->next) {
 
1182
        if (item->isSelected()) {
 
1183
            item->setSelected(false, false);
 
1184
            d->selectedItems.remove(item);
 
1185
        }
 
1186
    }
 
1187
    blockSignals(false);
 
1188
    emit signalSelectionChanged();
 
1189
}
 
1190
 
 
1191
void ThumbView::selectAll()
 
1192
{
 
1193
    blockSignals(true);
 
1194
    for (ThumbItem* item = d->firstItem; item; item = item->next) {
 
1195
        if (!item->isSelected()) {
 
1196
            item->setSelected(true, false);
 
1197
            d->selectedItems.append(item);
 
1198
        }
 
1199
    }
 
1200
    blockSignals(false);
 
1201
    emit signalSelectionChanged();
 
1202
}
 
1203
 
 
1204
void ThumbView::invertSelection()
 
1205
{
 
1206
    blockSignals(true);
 
1207
    for (ThumbItem* item = d->firstItem; item; item = item->next) {
 
1208
        if (!item->isSelected()) {
 
1209
            item->setSelected(true, false);
 
1210
            d->selectedItems.append(item);
 
1211
        }
 
1212
        else {
 
1213
            item->setSelected(false, false);
 
1214
            d->selectedItems.remove(item);
 
1215
        }
 
1216
    }
 
1217
    blockSignals(false);
 
1218
    emit signalSelectionChanged();
 
1219
}
 
1220
 
 
1221
void ThumbView::selectItem(ThumbItem* item, bool select)
 
1222
{
 
1223
    if (!item) return;
 
1224
 
 
1225
    if (select)
 
1226
    {
 
1227
        d->selectedItems.prepend(item);
 
1228
    }
 
1229
    else
 
1230
    {
 
1231
        d->selectedItems.remove(item);
 
1232
    }
 
1233
    
 
1234
    emit signalSelectionChanged();
 
1235
}
 
1236
 
 
1237
void ThumbView::emitRenamed(ThumbItem *item)
 
1238
{
 
1239
    if (!item) return;
 
1240
 
 
1241
    emit signalItemRenamed(item);
 
1242
}
 
1243
 
 
1244
void ThumbView::startDrag()
 
1245
{
 
1246
    if (!d->startDragItem) return;
 
1247
 
 
1248
    QStrList uris;
 
1249
    for (ThumbItem *it = firstItem(); it; it=it->nextItem()) {
 
1250
        if (it->isSelected()) {
 
1251
            uris.append(it->text().utf8());
 
1252
        }
 
1253
    }
 
1254
 
 
1255
    QUriDrag* drag = new QUriDrag(uris, this);
 
1256
    if (!drag) return;
 
1257
    drag->setPixmap(*d->startDragItem->pixmap());
 
1258
    d->startDragItem = 0;
 
1259
    drag->dragCopy();
 
1260
 
 
1261
}
 
1262
 
 
1263
void ThumbView::contentsDropEvent(QDropEvent *e)
 
1264
{
 
1265
 
 
1266
    if (!e) return;
 
1267
 
 
1268
    if (e->source() == this) {
 
1269
        e->accept();
 
1270
        return;
 
1271
    }
 
1272
    
 
1273
    
 
1274
}
 
1275
 
 
1276
void ThumbView::keyPressEvent(QKeyEvent *e)
 
1277
{
 
1278
    bool handled = false;
 
1279
    
 
1280
    if ( !d->firstItem )
 
1281
        return;
 
1282
 
 
1283
    ThumbItem *currItem = d->selectedItems.first();
 
1284
 
 
1285
    switch ( e->key() ) {
 
1286
 
 
1287
    case Key_Home: {
 
1288
        d->firstItem->setSelected(true, true);
 
1289
        ensureItemVisible(d->firstItem);
 
1290
        handled = true;
 
1291
        break;
 
1292
    }
 
1293
 
 
1294
    case Key_End: {
 
1295
        d->lastItem->setSelected(true, true);
 
1296
        ensureItemVisible(d->lastItem);
 
1297
        handled = true;
 
1298
        break;
 
1299
    }
 
1300
 
 
1301
    case Key_Enter:
 
1302
    case Key_Return: {
 
1303
        if (currItem)
 
1304
        {
 
1305
            emit signalReturnPressed(currItem);
 
1306
            handled = true;
 
1307
        }
 
1308
        break;
 
1309
    }
 
1310
        
 
1311
    case Key_Right: {
 
1312
        ThumbItem *item = currItem ? currItem->next : d->firstItem;
 
1313
        if (item)
 
1314
        {
 
1315
            keySelectItem(item, e->state() & Qt::ShiftButton);
 
1316
            ensureItemVisible(item);
 
1317
        }
 
1318
        handled = true;
 
1319
        break;
 
1320
    }
 
1321
        
 
1322
    case Key_Left: {
 
1323
        ThumbItem *item = currItem ? currItem->prev : d->firstItem;
 
1324
        if (item)
 
1325
        {
 
1326
            keySelectItem(item, e->state() & Qt::ShiftButton);
 
1327
            ensureItemVisible(item);
 
1328
        }
 
1329
        handled = true;
 
1330
        break;
 
1331
    }
 
1332
 
 
1333
    case Key_Up: {
 
1334
 
 
1335
        currItem = currItem ? currItem : d->firstItem;
 
1336
        
 
1337
        int x = currItem->x() + currItem->width()/2;
 
1338
        int y = currItem->y() - d->spacing*2;
 
1339
        
 
1340
        ThumbItem *item = 0;
 
1341
        
 
1342
        while (!item && y > 0) {
 
1343
            item = findItem(QPoint(x,y));
 
1344
            y -= d->spacing * 2;
 
1345
        }
 
1346
 
 
1347
        if (item)
 
1348
        {
 
1349
            keySelectItem(item, e->state() & Qt::ShiftButton);
 
1350
            ensureItemVisible(item);
 
1351
        }
 
1352
        handled = true;
 
1353
        break;
 
1354
    }
 
1355
        
 
1356
    case Key_Down: {
 
1357
 
 
1358
        currItem = currItem ? currItem : d->firstItem;
 
1359
 
 
1360
        int x = currItem->x() + currItem->width()/2;
 
1361
        int y = currItem->y() + currItem->height() +
 
1362
                d->spacing * 2;
 
1363
 
 
1364
        ThumbItem *item = 0;
 
1365
        
 
1366
        while (!item && y < contentsHeight()) {
 
1367
            item = findItem(QPoint(x,y));
 
1368
            y += d->spacing * 2;
 
1369
        }
 
1370
        
 
1371
        if (item)
 
1372
        {
 
1373
            keySelectItem(item, e->state() & Qt::ShiftButton);
 
1374
            ensureItemVisible(item);
 
1375
        }
 
1376
        handled = true;
 
1377
 
 
1378
        break;
 
1379
    }
 
1380
 
 
1381
    case Key_Next: {
 
1382
 
 
1383
        currItem = currItem ? currItem : d->firstItem;
 
1384
 
 
1385
        QRect r( 0, currItem->y() + visibleHeight(),
 
1386
                 contentsWidth(), visibleHeight() );
 
1387
        ThumbItem *ni = findFirstVisibleItem(r);
 
1388
        if (!ni) {
 
1389
            r = QRect( 0, currItem->y() + currItem->height(),
 
1390
                       contentsWidth(), contentsHeight() );
 
1391
            ni = findLastVisibleItem( r );
 
1392
        }
 
1393
        if (ni) {
 
1394
            ni->setSelected(true, true);
 
1395
            ensureItemVisible(ni);
 
1396
            handled = true;
 
1397
        }
 
1398
        break;
 
1399
    }
 
1400
        
 
1401
    case Key_Prior: {
 
1402
 
 
1403
        currItem = currItem ? currItem : d->firstItem;
 
1404
 
 
1405
        QRect r(0, currItem->y() - visibleHeight(),
 
1406
                contentsWidth(), visibleHeight() );
 
1407
        ThumbItem *ni = findFirstVisibleItem(r);
 
1408
        if ( !ni ) {
 
1409
            r = QRect( 0, 0, contentsWidth(), currItem->y() );
 
1410
            ni = findFirstVisibleItem( r );
 
1411
        }
 
1412
        if ( ni ) {
 
1413
            ni->setSelected(true, true);
 
1414
            ensureItemVisible(ni);
 
1415
            handled = true;
 
1416
        }
 
1417
 
 
1418
        break;
 
1419
    }
 
1420
 
 
1421
    default:
 
1422
        e->ignore();
 
1423
        return;
 
1424
    }
 
1425
 
 
1426
    if (handled) {
 
1427
        viewport()->update();
 
1428
        emit signalSelectionChanged();
 
1429
    }
 
1430
}
 
1431
 
 
1432
void ThumbView::keySelectItem(ThumbItem* item, bool shift)
 
1433
{
 
1434
    if (!item)
 
1435
        return;
 
1436
    
 
1437
    if (shift)
 
1438
    {
 
1439
        if (!item->isSelected())
 
1440
        {
 
1441
            item->setSelected(true,false);
 
1442
        }
 
1443
        else
 
1444
        {
 
1445
            d->selectedItems.removeRef(item);
 
1446
            d->selectedItems.prepend(item);
 
1447
        }
 
1448
    }
 
1449
    else
 
1450
    {
 
1451
        item->setSelected(true,true);
 
1452
    }
 
1453
}
 
1454
 
 
1455
void ThumbView::ensureItemVisible(ThumbItem *item)
 
1456
{
 
1457
    if ( !item )
 
1458
        return;
 
1459
 
 
1460
    if ( item->y() == d->firstItem->y() )
 
1461
    {
 
1462
        int w = item->width();
 
1463
        ensureVisible( item->x() + w / 2, 0, w/2+1, 0 );
 
1464
    }
 
1465
    else
 
1466
    {
 
1467
        int w = item->width();
 
1468
        int h = item->height();
 
1469
        ensureVisible( item->x() + w / 2, item->y() + h / 2,
 
1470
                       w / 2 + 1, h / 2 + 1 );
 
1471
    }
 
1472
}
 
1473
 
 
1474
ThumbItem* ThumbView::findFirstVisibleItem(const QRect &r ) const
 
1475
{
 
1476
    ThumbViewPrivate::ItemContainer *c = d->firstContainer;
 
1477
    ThumbItem *i = 0;
 
1478
    bool alreadyIntersected = false;
 
1479
    for ( ; c; c = c->next ) {
 
1480
        if ( c->rect.intersects( r ) ) {
 
1481
            alreadyIntersected = true;
 
1482
            ThumbItem *item = c->items.first();
 
1483
            for ( ; item; item = c->items.next() ) {
 
1484
                if ( r.intersects( item->rect() ) ) {
 
1485
                    if ( !i ) {
 
1486
                        i = item;
 
1487
                    } else {
 
1488
                        QRect r2 = item->rect();
 
1489
                        QRect r3 = i->rect();
 
1490
                        if ( r2.y() < r3.y() )
 
1491
                            i = item;
 
1492
                        else if ( r2.y() == r3.y() &&
 
1493
                                  r2.x() < r3.x() )
 
1494
                            i = item;
 
1495
                    }
 
1496
                }
 
1497
            }
 
1498
        } else {
 
1499
            if ( alreadyIntersected )
 
1500
                break;
 
1501
        }
 
1502
    }
 
1503
 
 
1504
    return i;
 
1505
}
 
1506
 
 
1507
ThumbItem* ThumbView::findLastVisibleItem(const QRect &r ) const
 
1508
{
 
1509
    ThumbViewPrivate::ItemContainer *c = d->firstContainer;
 
1510
    ThumbItem *i = 0;
 
1511
    bool alreadyIntersected = false;
 
1512
    for ( ; c; c = c->next ) {
 
1513
        if ( c->rect.intersects( r ) ) {
 
1514
            alreadyIntersected = true;
 
1515
            ThumbItem *item = c->items.first();
 
1516
            for ( ; item; item = c->items.next() ) {
 
1517
                if ( r.intersects( item->rect() ) ) {
 
1518
                    if ( !i ) {
 
1519
                        i = item;
 
1520
                    } else {
 
1521
                        QRect r2 = item->rect();
 
1522
                        QRect r3 = i->rect();
 
1523
                        if ( r2.y() > r3.y() )
 
1524
                            i = item;
 
1525
                        else if ( r2.y() == r3.y() &&
 
1526
                                  r2.x() > r3.x() )
 
1527
                            i = item;
 
1528
                    }
 
1529
                }
 
1530
            }
 
1531
        } else {
 
1532
            if ( alreadyIntersected )
 
1533
                break;
 
1534
        }
 
1535
    }
 
1536
 
 
1537
    return i;
 
1538
}
 
1539
 
 
1540
#include "thumbview.moc"