19
23
* ============================================================ */
28
#include <qfileinfo.h>
22
31
#include <qpixmap.h>
23
#include <qpopupmenu.h>
24
32
#include <qcursor.h>
25
33
#include <qfontmetrics.h>
35
#include <qdragobject.h>
36
#include <qclipboard.h>
28
41
#include <kmimetype.h>
29
42
#include <klocale.h>
30
43
#include <kiconloader.h>
45
#include <kapplication.h>
50
#include "themeengine.h"
51
#include "thumbnailsize.h"
52
#include "gpiteminfo.h"
53
#include "renamecustomizer.h"
54
#include "icongroupitem.h"
55
#include "dpopupmenu.h"
56
#include "dragobjects.h"
37
57
#include "cameraui.h"
38
#include "gpiteminfo.h"
39
58
#include "cameraiconitem.h"
40
59
#include "cameraiconview.h"
41
#include "renamecustomizer.h"
42
#include "icongroupitem.h"
60
#include "cameraiconview.moc"
65
class CameraIconViewPriv
74
thumbSize = ThumbnailSize::Large;
77
QDict<CameraIconViewItem> itemDict;
81
QPixmap itemRegPixmap;
82
QPixmap itemSelPixmap;
84
RenameCustomizer *renamer;
86
IconGroupItem *groupItem;
88
ThumbnailSize thumbSize;
44
93
CameraIconView::CameraIconView(CameraUI* ui, QWidget* parent)
45
: IconView(parent), m_renamer(0), m_ui(ui),
46
m_groupItem(new IconGroupItem(this))
96
d = new CameraIconViewPriv;
98
d->groupItem = new IconGroupItem(this);
48
100
setHScrollBarMode(QScrollView::AlwaysOff);
50
CameraIconViewItem::m_newEmblem = new QPixmap(CameraIconViewItem::new_xpm);
101
setMinimumSize(400, 300);
103
setAcceptDrops(true);
104
viewport()->setAcceptDrops(true);
106
// ----------------------------------------------------------------
52
108
connect(this, SIGNAL(signalSelectionChanged()),
53
SLOT(slotSelectionChanged()));
109
this, SLOT(slotSelectionChanged()));
111
connect(this, SIGNAL(signalNewSelection(bool)),
112
this, SLOT(slotUpdateDownloadNames(bool)));
54
114
connect(this, SIGNAL(signalRightButtonClicked(IconItem*, const QPoint&)),
55
SLOT(slotContextMenu(IconItem*, const QPoint&)));
115
this, SLOT(slotContextMenu(IconItem*, const QPoint&)));
117
connect(this, SIGNAL(signalRightButtonClicked(const QPoint &)),
118
this, SLOT(slotRightButtonClicked(const QPoint &)));
56
120
connect(this, SIGNAL(signalDoubleClicked(IconItem*)),
57
SLOT(slotDoubleClicked(IconItem*)));
121
this, SLOT(slotDoubleClicked(IconItem*)));
123
connect(ThemeEngine::instance(), SIGNAL(signalThemeChanged()),
124
this, SLOT(slotThemeChanged()));
126
// ----------------------------------------------------------------
128
updateItemRectsPixmap();
60
132
CameraIconView::~CameraIconView()
63
delete CameraIconViewItem::m_newEmblem;
64
CameraIconViewItem::m_newEmblem = 0;
138
QPixmap* CameraIconView::itemBaseRegPixmap() const
140
return &d->itemRegPixmap;
143
QPixmap* CameraIconView::itemBaseSelPixmap() const
145
return &d->itemSelPixmap;
67
148
void CameraIconView::setRenameCustomizer(RenameCustomizer* renamer)
70
connect(m_renamer, SIGNAL(signalChanged()),
71
SLOT(slotDownloadNameChanged()));
150
d->renamer = renamer;
152
connect(d->renamer, SIGNAL(signalChanged()),
153
this, SLOT(slotDownloadNameChanged()));
74
156
void CameraIconView::addItem(const GPItemInfo& info)
77
mime = KMimeType::mimeType( info.mime );
78
QPixmap pix = mime->pixmap( KIcon::Desktop, 100, KIcon::DefaultState);
159
// Just to have a generic image thumb from desktop with KDE < 3.5.0
160
KMimeType::Ptr mime = KMimeType::mimeType(info.mime == QString("image/x-raw") ?
161
QString("image/tiff") : info.mime);
165
thumb = QImage(mime->pixmap(KIcon::Desktop, ThumbnailSize::Huge, KIcon::DefaultState)
170
KIconLoader *iconLoader = KApplication::kApplication()->iconLoader();
171
thumb = iconLoader->loadIcon("empty", KIcon::Desktop,
172
ThumbnailSize::Huge, KIcon::DefaultState, 0, true)
80
176
QString downloadName;
84
if (!m_renamer->useDefault())
180
if (!d->renamer->useDefault())
86
downloadName = getTemplatedName( m_renamer->nameTemplate(), &info,
182
downloadName = getTemplatedName( &info, d->itemDict.count() );
91
downloadName = getCasedName( m_renamer->changeCase(), &info);
186
downloadName = getCasedName( d->renamer->changeCase(), &info);
95
CameraIconViewItem* item = new CameraIconViewItem(m_groupItem, info,
97
m_itemDict.insert(info.folder+info.name, item);
190
CameraIconViewItem* item = new CameraIconViewItem(d->groupItem, info, thumb, downloadName);
191
d->itemDict.insert(info.folder+info.name, item);
100
194
void CameraIconView::removeItem(const QString& folder, const QString& file)
102
CameraIconViewItem* item = m_itemDict.find(folder+file);
196
CameraIconViewItem* item = d->itemDict.find(folder+file);
199
d->itemDict.remove(folder+file);
201
setDelayedRearrangement(true);
203
setDelayedRearrangement(false);
110
206
CameraIconViewItem* CameraIconView::findItem(const QString& folder, const QString& file)
112
return m_itemDict.find(folder+file);
115
void CameraIconView::setThumbnail(const QString& folder, const QString& filename,
116
const QPixmap& pixmap)
118
CameraIconViewItem* item = m_itemDict.find(folder+filename);
208
return d->itemDict.find(folder+file);
211
int CameraIconView::countItemsByFolder(QString folder)
214
if (folder.endsWith("/")) folder.truncate(folder.length()-1);
216
for (IconItem* item = firstItem(); item; item = item->nextItem())
218
CameraIconViewItem* iconItem = static_cast<CameraIconViewItem*>(item);
219
QString itemFolder = iconItem->itemInfo()->folder;
220
if (itemFolder.endsWith("/")) itemFolder.truncate(itemFolder.length()-1);
222
if (folder == itemFolder)
229
void CameraIconView::setThumbnail(const QString& folder, const QString& filename, const QImage& image)
231
CameraIconViewItem* item = d->itemDict.find(folder+filename);
122
item->setPixmap(pixmap);
235
item->setThumbnail(image);
239
void CameraIconView::ensureItemVisible(CameraIconViewItem *item)
241
IconView::ensureItemVisible(item);
244
void CameraIconView::ensureItemVisible(const GPItemInfo& itemInfo)
246
ensureItemVisible(itemInfo.folder, itemInfo.name);
249
void CameraIconView::ensureItemVisible(const QString& folder, const QString& file)
251
CameraIconViewItem* item = d->itemDict.find(folder+file);
255
ensureItemVisible(item);
126
258
void CameraIconView::slotDownloadNameChanged()
128
bool useDefault = true;
129
QString nameTemplate;
133
useDefault = m_renamer->useDefault();
134
nameTemplate = m_renamer->nameTemplate();
260
bool hasSelection = false;
261
for (IconItem* item = firstItem(); item; item = item->nextItem())
263
if (item->isSelected())
270
// connected to slotUpdateDownloadNames, and used externally
271
emit signalNewSelection(hasSelection);
274
void CameraIconView::slotUpdateDownloadNames(bool hasSelection)
276
bool useDefault = true;
281
useDefault = d->renamer->useDefault();
282
startIndex = d->renamer->startIndex() -1;
285
bool convertLossLessJpeg = d->cameraUI->convertLosslessJpegFiles();
286
QString losslessFormat = d->cameraUI->losslessFormat();
137
288
viewport()->setUpdatesEnabled(false);
138
for (IconItem* item = firstItem(); item;
139
item = item->nextItem())
141
CameraIconViewItem* viewItem =
142
static_cast<CameraIconViewItem*>(item);
144
QString downloadName;
146
downloadName = getTemplatedName( nameTemplate,
147
viewItem->itemInfo(),
148
m_groupItem->index(viewItem) );
150
downloadName = getCasedName( m_renamer->changeCase(),
151
viewItem->itemInfo() );
153
viewItem->setDownloadName( downloadName );
292
// Camera items selection.
294
for (IconItem* item = firstItem(); item; item = item->nextItem())
296
QString downloadName;
297
CameraIconViewItem* viewItem = static_cast<CameraIconViewItem*>(item);
299
if (item->isSelected())
302
downloadName = getTemplatedName( viewItem->itemInfo(), startIndex );
304
downloadName = getCasedName( d->renamer->changeCase(), viewItem->itemInfo() );
309
if (convertLossLessJpeg && !downloadName.isEmpty())
311
QFileInfo fi(downloadName);
312
QString ext = fi.extension(false).upper();
313
if (ext == QString("JPEG") || ext == QString("JPG") || ext == QString("JPE"))
315
downloadName.truncate(downloadName.length() - ext.length());
316
downloadName.append(losslessFormat.lower());
320
viewItem->setDownloadName( downloadName );
325
// No camera item selection.
327
for (IconItem* item = firstItem(); item; item = item->nextItem())
329
QString downloadName;
330
CameraIconViewItem* viewItem = static_cast<CameraIconViewItem*>(item);
333
downloadName = getTemplatedName( viewItem->itemInfo(), startIndex );
335
downloadName = getCasedName( d->renamer->changeCase(), viewItem->itemInfo() );
337
if (convertLossLessJpeg)
339
QFileInfo fi(downloadName);
340
QString ext = fi.extension(false).upper();
341
if (ext == QString("JPEG") || ext == QString("JPG") || ext == QString("JPE"))
343
downloadName.truncate(downloadName.length() - ext.length());
344
downloadName.append(losslessFormat.lower());
348
viewItem->setDownloadName( downloadName );
156
353
viewport()->setUpdatesEnabled(true);
157
354
viewport()->update();
160
QString CameraIconView::getTemplatedName(const QString& templ,
161
const GPItemInfo* itemInfo,
165
return QString::null;
167
QString dname(templ);
357
QString CameraIconView::defaultDownloadName(CameraIconViewItem *viewItem)
359
RenameCustomizer::Case renamecase = RenameCustomizer::NONE;
361
renamecase = d->renamer->changeCase();
363
return getCasedName( renamecase, viewItem->itemInfo() );
366
QString CameraIconView::getTemplatedName(const GPItemInfo* itemInfo, int position)
169
368
QString ext = itemInfo->name;
170
369
int pos = ext.findRev('.');
174
ext = ext.right( ext.length() - pos - 1);
176
struct tm* time_tm = ::localtime(&itemInfo->mtime);
178
strftime(s, 100, QFile::encodeName(dname), time_tm);
181
dname.replace("%s", "");
183
dname.sprintf(QFile::encodeName(dname), position+1);
184
dname.replace("/","");
373
ext = ext.right( ext.length() - pos );
376
mtime.setTime_t(itemInfo->mtime);
378
return d->renamer->newName(mtime, position+1, ext);
192
381
QString CameraIconView::getCasedName(const RenameCustomizer::Case ccase,
315
511
blockSignals(true);
316
512
clearSelection();
317
514
for (IconItem* item = firstItem(); item;
318
515
item = item->nextItem())
320
CameraIconViewItem* viewItem =
321
static_cast<CameraIconViewItem*>(item);
322
if (viewItem->itemInfo()->downloaded == 0)
517
CameraIconViewItem* viewItem = static_cast<CameraIconViewItem*>(item);
518
if (viewItem->itemInfo()->downloaded == GPItemInfo::NewPicture)
324
520
viewItem->setSelected(true, false);
327
524
blockSignals(false);
328
525
emit signalSelectionChanged();
331
528
void CameraIconView::startDrag()
532
for (IconItem* item = firstItem(); item; item = item->nextItem())
534
if (!item->isSelected())
537
CameraIconViewItem* iconItem = static_cast<CameraIconViewItem*>(item);
538
QString itemPath = iconItem->itemInfo()->folder + iconItem->itemInfo()->name;
539
lst.append(itemPath);
542
QDragObject * drag = new CameraItemListDrag(lst, d->cameraUI);
545
QPixmap icon(DesktopIcon("image", 48));
546
int w = icon.width();
547
int h = icon.height();
549
QPixmap pix(w+4,h+4);
550
QString text(QString::number(lst.count()));
553
p.fillRect(0, 0, w+4, h+4, QColor(Qt::white));
554
p.setPen(QPen(Qt::black, 1));
555
p.drawRect(0, 0, w+4, h+4);
556
p.drawPixmap(2, 2, icon);
557
QRect r = p.boundingRect(2,2,w,h,Qt::AlignLeft|Qt::AlignTop,text);
558
r.setWidth(QMAX(r.width(),r.height()));
559
r.setHeight(QMAX(r.width(),r.height()));
560
p.fillRect(r, QColor(0,80,0));
565
p.drawText(r, Qt::AlignCenter, text);
568
drag->setPixmap(pix);
573
void CameraIconView::contentsDropEvent(QDropEvent *event)
575
// don't popup context menu if the camera is busy
576
if (d->cameraUI->isBusy())
579
if ( (!QUriDrag::canDecode(event) && !CameraDragObject::canDecode(event) )
580
|| event->source() == this)
587
KURLDrag::decode(event, srcURLs);
588
uploadItemPopupMenu(srcURLs);
591
void CameraIconView::slotRightButtonClicked(const QPoint&)
593
// don't popup context menu if the camera is busy
594
if (d->cameraUI->isBusy())
597
QMimeSource *data = kapp->clipboard()->data(QClipboard::Clipboard);
598
if(!data || !QUriDrag::canDecode(data))
602
KURLDrag::decode(data, srcURLs);
603
uploadItemPopupMenu(srcURLs);
606
void CameraIconView::uploadItemPopupMenu(const KURL::List& srcURLs)
608
KPopupMenu popMenu(this);
609
popMenu.insertTitle(SmallIcon("digikam"), d->cameraUI->cameraTitle());
610
popMenu.insertItem( SmallIcon("goto"), i18n("&Upload to camera"), 10 );
611
popMenu.insertSeparator(-1);
612
popMenu.insertItem( SmallIcon("cancel"), i18n("C&ancel") );
614
popMenu.setMouseTracking(true);
615
int id = popMenu.exec(QCursor::pos());
620
emit signalUpload(srcURLs);
336
628
QRect CameraIconView::itemRect() const
341
CameraIconViewItem* item = static_cast<CameraIconViewItem*>(firstItem());
343
const int thumbSize = 128;
633
void CameraIconView::setThumbnailSize(const ThumbnailSize& thumbSize)
635
if ( d->thumbSize != thumbSize)
637
d->thumbSize = thumbSize;
638
updateItemRectsPixmap();
639
triggerRearrangement();
643
ThumbnailSize CameraIconView::thumbnailSize() const
648
void CameraIconView::updateItemRectsPixmap()
650
int thumbSize = d->thumbSize.size();
349
656
pixRect.setWidth(thumbSize);
350
657
pixRect.setHeight(thumbSize);
352
659
QFontMetrics fm(font());
353
660
QRect r = QRect(fm.boundingRect(0, 0, thumbSize, 0xFFFFFFFF,
354
Qt::AlignHCenter | Qt::AlignTop |
355
Qt::WordBreak | Qt::BreakAnywhere,
356
item->itemInfo()->name));
661
Qt::AlignHCenter | Qt::AlignTop,
357
663
textRect.setWidth(r.width());
358
664
textRect.setHeight(r.height());
360
if (!item->getDownloadName().isEmpty())
667
if (fn.pointSize() > 0)
363
if (fn.pointSize() > 0)
365
fn.setPointSize(QMAX(fn.pointSize()-2, 6));
368
fm = QFontMetrics(fn);
369
r = QRect(fm.boundingRect(0, 0, thumbSize, 0xFFFFFFFF,
370
Qt::AlignHCenter | Qt::WordBreak |
371
Qt::BreakAnywhere | Qt::AlignTop,
372
item->getDownloadName()));
373
extraRect.setWidth(r.width());
374
extraRect.setHeight(r.height());
669
fn.setPointSize(QMAX(fn.pointSize()-2, 6));
672
fm = QFontMetrics(fn);
673
r = QRect(fm.boundingRect(0, 0, thumbSize, 0xFFFFFFFF,
674
Qt::AlignHCenter | Qt::AlignTop,
676
extraRect.setWidth(r.width());
677
extraRect.setHeight(r.height());
378
r.setWidth(QMAX(QMAX(pixRect.width(), textRect.width()),
379
extraRect.width()) + 4);
380
r.setHeight(pixRect.height() +
382
extraRect.height() + 4);
387
#include "cameraiconview.moc"
680
r.setWidth(QMAX(QMAX(pixRect.width(), textRect.width()), extraRect.width()) + 4);
681
r.setHeight(pixRect.height() + textRect.height() + extraRect.height() + 4);
685
d->itemRegPixmap = ThemeEngine::instance()->thumbRegPixmap(d->itemRect.width(),
686
d->itemRect.height());
688
d->itemSelPixmap = ThemeEngine::instance()->thumbSelPixmap(d->itemRect.width(),
689
d->itemRect.height());
692
void CameraIconView::slotThemeChanged()
694
updateItemRectsPixmap();
695
viewport()->update();
698
int CameraIconView::itemsDownloaded()
702
for (IconItem* item = firstItem(); item; item = item->nextItem())
704
CameraIconViewItem* iconItem = static_cast<CameraIconViewItem*>(item);
706
if (iconItem->itemInfo()->downloaded == GPItemInfo::DownloadedYes)
713
void CameraIconView::itemsSelectionSizeInfo(unsigned long& fSize, unsigned long& dSize)
715
fSize = 0; // Files size
716
dSize = 0; // Estimated space requires to download and process files.
717
for (IconItem* item = firstItem(); item; item = item->nextItem())
719
if (item->isSelected())
721
CameraIconViewItem* iconItem = static_cast<CameraIconViewItem*>(item);
722
fSize += iconItem->itemInfo()->size;
724
if (iconItem->itemInfo()->mime == QString("image/jpeg"))
726
if (d->cameraUI->convertLosslessJpegFiles())
728
// Estimated size is aroud 5 x original size when JPEG=>PNG.
729
dSize += iconItem->itemInfo()->size*5;
731
else if (d->cameraUI->autoRotateJpegFiles())
733
// We need a double size to perform rotation.
734
dSize += iconItem->itemInfo()->size*2;
738
// Real file size is added.
739
dSize += iconItem->itemInfo()->size;
743
dSize += iconItem->itemInfo()->size;
752
} // namespace Digikam