1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : Qt item view for images - the delegate
9
* Copyright (C) 2012 by Islam Wazery <wazery at ubuntu dot com>
11
* This program is free software; you can redistribute it
12
* and/or modify it under the terms of the GNU General
13
* Public License as published by the Free Software Foundation;
14
* either version 2, or (at your option)
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* ============================================================ */
24
#include "itemviewimportdelegate.moc"
25
#include "itemviewimportdelegatepriv.h"
36
#include <kio/global.h>
38
#include <kiconloader.h>
40
#include <kapplication.h>
44
#include "imagedelegateoverlay.h"
45
#include "thememanager.h"
46
#include "imagescanner.h"
47
#include "camiteminfo.h"
48
#include "colorlabelwidget.h"
53
ItemViewImportDelegatePrivate::ItemViewImportDelegatePrivate()
65
ratingPixmaps = QVector<QPixmap>(10);
68
void ItemViewImportDelegatePrivate::init(ItemViewImportDelegate* const _q)
72
q->connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()),
73
q, SLOT(slotThemeChanged()));
76
void ItemViewImportDelegatePrivate::clearRects()
78
gridSize = QSize(0, 0);
79
rect = QRect(0, 0, 0, 0);
80
ratingRect = QRect(0, 0, 0, 0);
83
void ItemViewImportDelegatePrivate::makeStarPolygon()
85
// Pre-computed star polygon for a 15x15 pixmap.
86
starPolygon << QPoint(0, 6);
87
starPolygon << QPoint(5, 5);
88
starPolygon << QPoint(7, 0);
89
starPolygon << QPoint(9, 5);
90
starPolygon << QPoint(14, 6);
91
starPolygon << QPoint(10, 9);
92
starPolygon << QPoint(11, 14);
93
starPolygon << QPoint(7, 11);
94
starPolygon << QPoint(3, 14);
95
starPolygon << QPoint(4, 9);
97
starPolygonSize = QSize(15, 15);
100
// ---- ItemViewImportDelegate -----------------------------------------------
102
ItemViewImportDelegate::ItemViewImportDelegate(QObject* const parent)
103
: DItemDelegate(parent), d_ptr(new ItemViewImportDelegatePrivate)
108
ItemViewImportDelegate::ItemViewImportDelegate(ItemViewImportDelegatePrivate& dd, QObject* const parent)
109
: DItemDelegate(parent), d_ptr(&dd)
114
ItemViewImportDelegate::~ItemViewImportDelegate()
116
Q_D(ItemViewImportDelegate);
121
ThumbnailSize ItemViewImportDelegate::thumbnailSize() const
123
Q_D(const ItemViewImportDelegate);
127
void ItemViewImportDelegate::setThumbnailSize(const ThumbnailSize& thumbSize)
129
Q_D(ItemViewImportDelegate);
131
if ( d->thumbSize != thumbSize)
133
d->thumbSize = thumbSize;
134
invalidatePaintingCache();
138
void ItemViewImportDelegate::setSpacing(int spacing)
140
Q_D(ItemViewImportDelegate);
142
if (d->spacing == spacing)
147
d->spacing = spacing;
148
invalidatePaintingCache();
151
int ItemViewImportDelegate::spacing() const
153
Q_D(const ItemViewImportDelegate);
157
QRect ItemViewImportDelegate::rect() const
159
Q_D(const ItemViewImportDelegate);
163
QRect ItemViewImportDelegate::pixmapRect() const
168
QRect ItemViewImportDelegate::imageInformationRect() const
173
QRect ItemViewImportDelegate::ratingRect() const
175
Q_D(const ItemViewImportDelegate);
176
return d->ratingRect;
179
void ItemViewImportDelegate::setRatingEdited(const QModelIndex& index)
181
Q_D(ItemViewImportDelegate);
182
d->editingRating = index;
185
QSize ItemViewImportDelegate::sizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const
187
Q_D(const ItemViewImportDelegate);
188
return d->rect.size();
191
QSize ItemViewImportDelegate::gridSize() const
193
Q_D(const ItemViewImportDelegate);
197
bool ItemViewImportDelegate::acceptsToolTip(const QPoint&, const QRect& visualRect, const QModelIndex&, QRect* retRect) const
201
*retRect = visualRect;
207
bool ItemViewImportDelegate::acceptsActivation(const QPoint& , const QRect& visualRect, const QModelIndex&, QRect* retRect) const
211
*retRect = visualRect;
217
QAbstractItemDelegate* ItemViewImportDelegate::asDelegate()
222
void ItemViewImportDelegate::overlayDestroyed(QObject* o)
224
ImageDelegateOverlayContainer::overlayDestroyed(o);
227
void ItemViewImportDelegate::mouseMoved(QMouseEvent* e, const QRect& visualRect, const QModelIndex& index)
229
// 3-way indirection AbstractImportItemDelegate -> ItemViewImportDelegate -> ImageDelegateOverlayContainer
230
ImageDelegateOverlayContainer::mouseMoved(e, visualRect, index);
233
void ItemViewImportDelegate::setDefaultViewOptions(const QStyleOptionViewItem& option)
235
Q_D(ItemViewImportDelegate);
236
d->font = option.font;
237
invalidatePaintingCache();
240
void ItemViewImportDelegate::slotThemeChanged()
242
invalidatePaintingCache();
245
void ItemViewImportDelegate::slotSetupChanged()
247
invalidatePaintingCache();
250
void ItemViewImportDelegate::invalidatePaintingCache()
252
Q_D(ItemViewImportDelegate);
253
QSize oldGridSize = d->gridSize;
254
updateSizeRectsAndPixmaps();
256
if (oldGridSize != d->gridSize)
258
emit gridSizeChanged(d->gridSize);
259
// emit sizeHintChanged(QModelIndex());
265
QRect ItemViewImportDelegate::drawThumbnail(QPainter* p, const QRect& thumbRect, const QPixmap& background,
266
const QPixmap& thumbnail) const
268
p->drawPixmap(0, 0, background);
270
if (thumbnail.isNull())
277
QRect actualPixmapRect(r.x() + (r.width()-thumbnail.width())/2,
278
r.y() + (r.height()-thumbnail.height())/2,
279
thumbnail.width(), thumbnail.height());
281
QPixmap borderPix = thumbnailBorderPixmap(actualPixmapRect.size());
282
p->drawPixmap(actualPixmapRect.x()-3, actualPixmapRect.y()-3, borderPix);
284
p->drawPixmap(r.x() + (r.width()-thumbnail.width())/2,
285
r.y() + (r.height()-thumbnail.height())/2,
287
return actualPixmapRect;
290
void ItemViewImportDelegate::drawRating(QPainter* p, const QModelIndex& index, const QRect& ratingRect,
291
int rating, bool isSelected) const
293
Q_D(const ItemViewImportDelegate);
295
if (d->editingRating != index)
297
p->drawPixmap(ratingRect, ratingPixmap(rating, isSelected));
301
p->drawPixmap(r, ratingPixmap(-1, isSelected));
305
void ItemViewImportDelegate::drawName(QPainter* p,const QRect& nameRect, const QString& name) const
307
Q_D(const ItemViewImportDelegate);
308
p->setFont(d->fontReg);
309
p->drawText(nameRect, Qt::AlignCenter, name);//squeezedTextCached(p, nameRect.width(), name));
312
void ItemViewImportDelegate::drawModificationDate(QPainter* p, const QRect& dateRect, const QDateTime& date) const
314
Q_D(const ItemViewImportDelegate);
315
p->setFont(d->fontXtra);
316
QString str = dateToString(date);
317
str = i18nc("date of last image modification", "modified: %1",str);
318
p->drawText(dateRect, Qt::AlignCenter, str);//squeezedTextCached(p, dateRect.width(), str));
321
void ItemViewImportDelegate::drawImageFormat(QPainter* p, const QRect& r, const QString& mime) const
323
Q_D(const ItemViewImportDelegate);
325
if (!mime.isEmpty() && !r.isNull())
327
QString type = mime.split("/").at(1);
328
type = ImageScanner::formatToString(type);
332
QFont fnt(d->fontReg);
333
fnt.setWeight(QFont::Black);
334
fnt.setItalic(false);
336
p->setPen(QPen(Qt::gray));
339
QRect bRect = p->boundingRect(r, Qt::AlignTop | Qt::AlignHCenter, type.toUpper());
340
bRect.adjust(-1, -1, 1, 1);
341
bRect.translate(0, 1);
343
p->fillRect(bRect, Qt::SolidPattern);
344
p->setPen(QPen(Qt::white));
346
p->drawText(bRect, Qt::AlignTop | Qt::AlignHCenter, type.toUpper());
352
void ItemViewImportDelegate::drawImageSize(QPainter* p, const QRect& dimsRect, const QSize& dims) const
354
Q_D(const ItemViewImportDelegate);
358
p->setFont(d->fontXtra);
359
QString mpixels, resolution;
360
mpixels.setNum(dims.width()*dims.height()/1000000.0, 'f', 2);
363
resolution = i18nc("%1 width, %2 height, %3 mpixels", "%1x%2 (%3Mpx)",
364
dims.width(), dims.height(), mpixels);
367
resolution = i18nc("unknown image resolution", "Unknown");
370
p->drawText(dimsRect, Qt::AlignCenter, resolution);
374
void ItemViewImportDelegate::drawFileSize(QPainter* p, const QRect& r, qlonglong bytes) const
376
Q_D(const ItemViewImportDelegate);
377
p->setFont(d->fontXtra);
378
p->drawText(r, Qt::AlignCenter, KIO::convertSize(bytes));//squeezedTextCached(p, r.width(), KIO::convertSize(bytes)));
381
void ItemViewImportDelegate::drawTags(QPainter* p, const QRect& r, const QString& tagsString,
382
bool isSelected) const
384
Q_D(const ItemViewImportDelegate);
385
p->setFont(d->fontCom);
386
p->setPen(isSelected ? kapp->palette().color(QPalette::HighlightedText)
387
: kapp->palette().color(QPalette::Link));
389
p->drawText(r, Qt::AlignCenter, squeezedTextCached(p, r.width(), tagsString));
392
void ItemViewImportDelegate::drawPickLabelIcon(QPainter* p, const QRect& r, int pickId) const
394
// Draw Pick Label icon
395
if (pickId != NoPickLabel)
399
if (pickId == RejectedLabel)
401
icon = KIconLoader::global()->loadIcon("flag-red", KIconLoader::NoGroup, r.width());
403
else if (pickId == PendingLabel)
405
icon = KIconLoader::global()->loadIcon("flag-yellow", KIconLoader::NoGroup, r.width());
407
else if (pickId == AcceptedLabel)
409
icon = KIconLoader::global()->loadIcon("flag-green", KIconLoader::NoGroup, r.width());
415
void ItemViewImportDelegate::drawColorLabelRect(QPainter* p, const QStyleOptionViewItem& option,
416
bool isSelected, int colorId) const
418
Q_D(const ItemViewImportDelegate);
420
Q_UNUSED(isSelected);
422
if (colorId > NoColorLabel)
424
// This draw a simple rectangle around item.
425
p->setPen(QPen(ColorLabelWidget::labelColor((ColorLabel)colorId), 5, Qt::SolidLine));
426
p->drawRect(3, 3, d->rect.width()-7, d->rect.height()-7);
430
void ItemViewImportDelegate::drawPanelSideIcon(QPainter* p, bool left, bool right) const
432
Q_D(const ItemViewImportDelegate);
433
int iconSize = KIconLoader::SizeSmall;
437
QRect r(3, d->rect.height()/2 - iconSize/2, iconSize, iconSize);
438
QIcon icon = KIconLoader::global()->loadIcon("arrow-left", KIconLoader::NoGroup, iconSize);
444
QRect r(d->rect.width() - 3 - iconSize, d->rect.height()/2 - iconSize/2, iconSize, iconSize);
445
QIcon icon = KIconLoader::global()->loadIcon("arrow-right", KIconLoader::NoGroup, iconSize);
450
void ItemViewImportDelegate::drawDownloadIndicator(QPainter* p, const QRect& r, int itemType) const
453
if (itemType == CamItemInfo::DownloadUnknown)
455
icon = KIconLoader::global()->loadIcon("dialog-information", KIconLoader::NoGroup, KIconLoader::SizeSmall);
458
if (itemType == CamItemInfo::NewPicture)
460
icon = KIconLoader::global()->loadIcon("get-hot-new-stuff", KIconLoader::NoGroup, KIconLoader::SizeSmall);
463
if (itemType == CamItemInfo::DownloadedYes)
465
icon = KIconLoader::global()->loadIcon("dialog-ok", KIconLoader::NoGroup, KIconLoader::SizeSmall);
468
qreal op = p->opacity();
474
void ItemViewImportDelegate::drawLockIndicator(QPainter* p, const QRect& r, int lockStatus) const
479
icon = KIconLoader::global()->loadIcon("object-locked", KIconLoader::NoGroup, KIconLoader::SizeSmall);
483
icon = KIconLoader::global()->loadIcon("object-unlocked", KIconLoader::NoGroup, KIconLoader::SizeSmall);
486
qreal op = p->opacity();
492
void ItemViewImportDelegate::drawFocusRect(QPainter* p, const QStyleOptionViewItem& option,
493
bool isSelected) const
495
Q_D(const ItemViewImportDelegate);
497
if (option.state & QStyle::State_HasFocus) //?? is current item
499
p->setPen(QPen(isSelected ? kapp->palette().color(QPalette::HighlightedText)
500
: kapp->palette().color(QPalette::Text),
502
p->drawRect(1, 1, d->rect.width()-3, d->rect.height()-3);
506
void ItemViewImportDelegate::drawGroupIndicator(QPainter* p, const QRect& r,
507
int numberOfGroupedImages, bool open) const
509
if (numberOfGroupedImages)
515
icon = KIconLoader::global()->loadIcon("document-import", KIconLoader::NoGroup, r.width());
519
icon = KIconLoader::global()->loadIcon("document-multiple", KIconLoader::NoGroup, r.width());
522
qreal op = p->opacity();
527
QString text = QString::number(numberOfGroupedImages);
528
p->drawText(r, Qt::AlignCenter, text);
532
void ItemViewImportDelegate::drawMouseOverRect(QPainter* p, const QStyleOptionViewItem& option) const
534
Q_D(const ItemViewImportDelegate);
536
if (option.state & QStyle::State_MouseOver)
538
p->setPen(QPen(option.palette.color(QPalette::Highlight), 3, Qt::SolidLine));
539
p->drawRect(1, 1, d->rect.width()-3, d->rect.height()-3);
543
void ItemViewImportDelegate::prepareFonts()
545
Q_D(ItemViewImportDelegate);
547
d->fontReg = d->font;
548
d->fontCom = d->font;
549
d->fontXtra = d->font;
550
d->fontCom.setItalic(true);
552
int fnSz = d->fontReg.pointSize();
556
d->fontCom.setPointSize(fnSz-1);
557
d->fontXtra.setPointSize(fnSz-2);
561
fnSz = d->fontReg.pixelSize();
562
d->fontCom.setPixelSize(fnSz-1);
563
d->fontXtra.setPixelSize(fnSz-2);
567
void ItemViewImportDelegate::prepareMetrics(int maxWidth)
569
Q_D(ItemViewImportDelegate);
571
QFontMetrics fm(d->fontReg);
572
d->oneRowRegRect = fm.boundingRect(0, 0, maxWidth, 0xFFFFFFFF,
573
Qt::AlignTop | Qt::AlignHCenter,
575
fm = QFontMetrics(d->fontCom);
576
d->oneRowComRect = fm.boundingRect(0, 0, maxWidth, 0xFFFFFFFF,
577
Qt::AlignTop | Qt::AlignHCenter,
579
fm = QFontMetrics(d->fontXtra);
580
d->oneRowXtraRect = fm.boundingRect(0, 0, maxWidth, 0xFFFFFFFF,
581
Qt::AlignTop | Qt::AlignHCenter,
585
void ItemViewImportDelegate::prepareBackground()
587
Q_D(ItemViewImportDelegate);
589
if (!d->rect.isValid())
591
d->regPixmap = QPixmap();
592
d->selPixmap = QPixmap();
596
d->regPixmap = QPixmap(d->rect.width(), d->rect.height());
597
d->regPixmap.fill(kapp->palette().color(QPalette::Base));
598
QPainter p1(&d->regPixmap);
599
p1.setPen(kapp->palette().color(QPalette::Midlight));
600
p1.drawRect(0, 0, d->rect.width()-1, d->rect.height()-1);
602
d->selPixmap = QPixmap(d->rect.width(), d->rect.height());
603
d->selPixmap.fill(kapp->palette().color(QPalette::Highlight));
604
QPainter p2(&d->selPixmap);
605
p2.setPen(kapp->palette().color(QPalette::Midlight));
606
p2.drawRect(0, 0, d->rect.width()-1, d->rect.height()-1);
610
void ItemViewImportDelegate::prepareRatingPixmaps(bool composeOverBackground)
612
/// Please call this method after prepareBackground() and when d->ratingPixmap is set
614
Q_D(ItemViewImportDelegate);
616
if (!d->ratingRect.isValid())
621
// We use antialiasing and want to pre-render the pixmaps.
622
// So we need the background at the time of painting,
623
// and the background may be a gradient, and will be different for selected items.
624
// This makes 5*2 (small) pixmaps.
625
for (int sel=0; sel<2; ++sel)
629
if (composeOverBackground)
631
// do this once for regular, once for selected backgrounds
634
basePix = d->selPixmap.copy(d->ratingRect);
638
basePix = d->regPixmap.copy(d->ratingRect);
643
basePix = QPixmap(d->ratingRect.size());
644
basePix.fill(Qt::transparent);
647
for (int rating=1; rating<=5; ++rating)
649
// we store first the 5 regular, then the 5 selected pixmaps, for simplicity
650
int index = (sel * 5 + rating) - 1;
653
d->ratingPixmaps[index] = basePix;
655
QPainter painter(&d->ratingPixmaps[index]);
658
painter.setRenderHint(QPainter::Antialiasing, true);
659
painter.setBrush(kapp->palette().color(QPalette::Link));
660
QPen pen(kapp->palette().color(QPalette::Text));
661
// set a pen which joins the lines at a filled angle
662
pen.setJoinStyle(Qt::MiterJoin);
665
// move painter while drawing polygons
666
painter.translate( lround((d->ratingRect.width() - d->margin - rating*(d->starPolygonSize.width()+1))/2.0) + 2, 1 );
668
for (int s=0; s<rating; ++s)
670
painter.drawPolygon(d->starPolygon, Qt::WindingFill);
671
painter.translate(d->starPolygonSize.width() + 1, 0);
677
QPixmap ItemViewImportDelegate::ratingPixmap(int rating, bool selected) const
679
Q_D(const ItemViewImportDelegate);
681
if (rating < 1 || rating > 5)
686
pix = d->selPixmap.copy(d->ratingRect);
688
pix = d->regPixmap.copy(d->ratingRect);
699
return d->ratingPixmaps.at(5 + rating);
703
return d->ratingPixmaps.at(rating);
708
} // namespace Digikam