00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "albumiconview.moc"
00028
00029
00030
00031 extern "C"
00032 {
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <unistd.h>
00036 }
00037
00038
00039
00040 #include <cstdio>
00041 #include <cmath>
00042
00043
00044
00045 #include <QClipboard>
00046 #include <QCursor>
00047 #include <QDataStream>
00048 #include <QDateTime>
00049 #include <QDragMoveEvent>
00050 #include <QDropEvent>
00051 #include <QEvent>
00052 #include <QFile>
00053 #include <QFileInfo>
00054 #include <QImage>
00055 #include <QPainter>
00056 #include <QPixmap>
00057 #include <QPoint>
00058 #include <QPolygon>
00059 #include <QResizeEvent>
00060 #include <QString>
00061 #include <QStringList>
00062 #include <QTimer>
00063 #include <QMap>
00064
00065
00066
00067 #include <kaction.h>
00068 #include <kactioncollection.h>
00069 #include <kapplication.h>
00070 #include <kcalendarsystem.h>
00071 #include <kdeversion.h>
00072 #include <kglobal.h>
00073 #include <kiconeffect.h>
00074 #include <kiconloader.h>
00075 #include <kinputdialog.h>
00076 #include <kio/jobuidelegate.h>
00077 #include <klocale.h>
00078 #include <kmenu.h>
00079 #include <kmessagebox.h>
00080 #include <kmimetypetrader.h>
00081 #include <kpropsdlg.h>
00082 #include <krun.h>
00083 #include <kstandardaction.h>
00084 #include <kstandarddirs.h>
00085 #include <ktrader.h>
00086 #include <kurl.h>
00087 #include <kwindowsystem.h>
00088 #include <kdebug.h>
00089
00090
00091
00092 #include <libkdcraw/kdcraw.h>
00093 #include <libkdcraw/version.h>
00094
00095 #if KDCRAW_VERSION < 0x000400
00096 #include <libkdcraw/dcrawbinary.h>
00097 #endif
00098
00099
00100
00101 #include "album.h"
00102 #include "albumdb.h"
00103 #include "albumicongroupitem.h"
00104 #include "albumiconitem.h"
00105 #include "albumiconviewtooltip.h"
00106 #include "albumlister.h"
00107 #include "albummanager.h"
00108 #include "albumselectdialog.h"
00109 #include "albumsettings.h"
00110 #include "cameraui.h"
00111 #include "contextmenuhelper.h"
00112 #include "databaseaccess.h"
00113 #include "databasetransaction.h"
00114 #include "ddragobjects.h"
00115 #include "deletedialog.h"
00116 #include "digikamapp.h"
00117 #include "dio.h"
00118 #include "dmetadata.h"
00119 #include "dpopupmenu.h"
00120 #include "imageattributeswatch.h"
00121 #include "imageinfo.h"
00122 #include "imagewindow.h"
00123 #include "lighttablewindow.h"
00124 #include "loadingcacheinterface.h"
00125 #include "metadatahub.h"
00126 #include "queuemgrwindow.h"
00127 #include "ratingpopupmenu.h"
00128 #include "scancontroller.h"
00129 #include "statusprogressbar.h"
00130 #include "tagspopupmenu.h"
00131 #include "themeengine.h"
00132 #include "thumbnailloadthread.h"
00133 #include "thumbnailsize.h"
00134
00135 namespace Digikam
00136 {
00137
00138 class AlbumIconViewPrivate
00139 {
00140 public:
00141
00142 void init()
00143 {
00144 imageLister = 0;
00145 currentAlbum = 0;
00146 albumSettings = 0;
00147 toolTip = 0;
00148
00149
00150 starPolygon << QPoint(0, 6);
00151 starPolygon << QPoint(5, 5);
00152 starPolygon << QPoint(7, 0);
00153 starPolygon << QPoint(9, 5);
00154 starPolygon << QPoint(14, 6);
00155 starPolygon << QPoint(10, 9);
00156 starPolygon << QPoint(11, 14);
00157 starPolygon << QPoint(7, 11);
00158 starPolygon << QPoint(3, 14);
00159 starPolygon << QPoint(4, 9);
00160
00161 starPolygonSize = QSize(15, 15);
00162
00163 ratingPixmaps = QVector<QPixmap>(10);
00164 }
00165
00166 QString albumTitle;
00167 QString albumDate;
00168 QString albumComments;
00169
00170 QRect itemRect;
00171 QRect itemRatingRect;
00172 QRect itemDateRect;
00173 QRect itemModDateRect;
00174 QRect itemPixmapRect;
00175 QRect itemNameRect;
00176 QRect itemCommentsRect;
00177 QRect itemResolutionRect;
00178 QRect itemSizeRect;
00179 QRect itemTagRect;
00180 QRect bannerRect;
00181
00182 QPixmap itemRegPixmap;
00183 QPixmap itemSelPixmap;
00184 QPixmap bannerPixmap;
00185 QVector<QPixmap> ratingPixmaps;
00186
00187 QFont fnReg;
00188 QFont fnCom;
00189 QFont fnXtra;
00190
00191 QPolygon starPolygon;
00192 QSize starPolygonSize;
00193
00194 QHash<QString, AlbumIconItem*> itemDict;
00195 QHash<ImageInfo, AlbumIconItem*> itemInfoMap;
00196
00197 KUrl itemUrlToFind;
00198
00199 AlbumLister* imageLister;
00200 Album* currentAlbum;
00201 const AlbumSettings* albumSettings;
00202 QHash<int, AlbumIconGroupItem*> albumDict;
00203
00204 ThumbnailSize thumbSize;
00205
00206 AlbumIconViewToolTip* toolTip;
00207 };
00208
00209 AlbumIconView::AlbumIconView(QWidget* parent)
00210 : IconView(parent), d(new AlbumIconViewPrivate)
00211 {
00212 d->init();
00213 d->imageLister = AlbumLister::instance();
00214 d->toolTip = new AlbumIconViewToolTip(this);
00215
00216 setAcceptDrops(true);
00217 viewport()->setAcceptDrops(true);
00218
00219
00220
00221 connect(d->imageLister, SIGNAL(signalNewFilteredItems(const ImageInfoList&)),
00222 this, SLOT(slotImageListerNewItems(const ImageInfoList&)));
00223
00224 connect(d->imageLister, SIGNAL(signalDeleteFilteredItem(const ImageInfo &)),
00225 this, SLOT(slotImageListerDeleteItem(const ImageInfo &)) );
00226
00227 connect(d->imageLister, SIGNAL(signalClear()),
00228 this, SLOT(slotImageListerClear()));
00229
00230
00231
00232 connect(this, SIGNAL(signalDoubleClicked(IconItem*)),
00233 this, SLOT(slotDoubleClicked(IconItem*)));
00234
00235 connect(this, SIGNAL(signalReturnPressed(IconItem*)),
00236 this, SLOT(slotDoubleClicked(IconItem*)));
00237
00238 connect(this, SIGNAL(signalRightButtonClicked(IconItem*, const QPoint &)),
00239 this, SLOT(slotRightButtonClicked(IconItem*, const QPoint &)));
00240
00241 connect(this, SIGNAL(signalRightButtonClicked(const QPoint &)),
00242 this, SLOT(slotRightButtonClicked(const QPoint &)));
00243
00244 connect(this, SIGNAL(signalSelectionChanged()),
00245 this, SLOT(slotSelectionChanged()));
00246
00247 connect(this, SIGNAL(signalShowToolTip(IconItem*)),
00248 this, SLOT(slotShowToolTip(IconItem*)));
00249
00250
00251
00252 connect(ThemeEngine::instance(), SIGNAL(signalThemeChanged()),
00253 this, SLOT(slotThemeChanged()));
00254
00255
00256
00257 connect(ThumbnailLoadThread::defaultIconViewThread(), SIGNAL(signalThumbnailLoaded(const LoadingDescription &, const QPixmap&)),
00258 this, SLOT(slotThumbnailLoaded(const LoadingDescription &, const QPixmap&)));
00259
00260
00261
00262 ImageAttributesWatch *watch = ImageAttributesWatch::instance();
00263
00264 connect(watch, SIGNAL(signalImageTagsChanged(qlonglong)),
00265 this, SLOT(slotImageAttributesChanged(qlonglong)));
00266
00267 connect(watch, SIGNAL(signalImagesChanged(int)),
00268 this, SLOT(slotAlbumImagesChanged(int)));
00269
00270 connect(watch, SIGNAL(signalImageRatingChanged(qlonglong)),
00271 this, SLOT(slotImageAttributesChanged(qlonglong)));
00272
00273 connect(watch, SIGNAL(signalImageDateChanged(qlonglong)),
00274 this, SLOT(slotImageAttributesChanged(qlonglong)));
00275
00276 connect(watch, SIGNAL(signalImageCaptionChanged(qlonglong)),
00277 this, SLOT(slotImageAttributesChanged(qlonglong)));
00278
00279
00280
00281 LoadingCacheInterface::connectToSignalFileChanged(this,
00282 SLOT(slotFileChanged(const QString &)));
00283
00284
00285
00286
00287 connect(this, SIGNAL(changeTagOnImageInfos(const ImageInfoList &, const QList<int> &, bool, bool)),
00288 this, SLOT(slotChangeTagOnImageInfos(const ImageInfoList &, const QList<int> &, bool, bool)),
00289 Qt::QueuedConnection);
00290 }
00291
00292 AlbumIconView::~AlbumIconView()
00293 {
00294 delete d->toolTip;
00295 delete d;
00296 }
00297
00298 void AlbumIconView::applySettings(const AlbumSettings* settings)
00299 {
00300 if (!settings)
00301 return;
00302
00303 d->albumSettings = settings;
00304
00305 d->thumbSize = (ThumbnailSize::Size)d->albumSettings->getDefaultIconSize();
00306
00307 setEnableToolTips(d->albumSettings->getShowToolTips());
00308
00309 updateRectsAndPixmaps();
00310
00311 d->imageLister->stop();
00312 clear();
00313
00314 ThumbnailLoadThread::defaultIconViewThread()->setThumbnailSize(d->thumbSize.size());
00315
00316 if (d->currentAlbum)
00317 {
00318 d->imageLister->openAlbum(d->currentAlbum);
00319 }
00320 }
00321
00322 void AlbumIconView::setThumbnailSize(const ThumbnailSize& thumbSize)
00323 {
00324 if ( d->thumbSize != thumbSize)
00325 {
00326 d->thumbSize = thumbSize;
00327 ThumbnailLoadThread::defaultIconViewThread()->setThumbnailSize(d->thumbSize.size());
00328
00329 updateRectsAndPixmaps();
00330 IconItem *currentIconItem = currentItem();
00331 triggerRearrangement();
00332 setStoredVisibleItem(currentIconItem);
00333 }
00334 }
00335
00336 void AlbumIconView::setAlbum(Album* album)
00337 {
00338 if (!album)
00339 {
00340 d->currentAlbum = 0;
00341 d->imageLister->stop();
00342 clear();
00343
00344 return;
00345 }
00346
00347 if (d->currentAlbum == album)
00348 return;
00349
00350 d->imageLister->stop();
00351 clear();
00352
00353 d->currentAlbum = album;
00354 d->imageLister->openAlbum(d->currentAlbum);
00355
00356 updateRectsAndPixmaps();
00357 }
00358
00359 void AlbumIconView::setAlbumItemToFind(const KUrl& url)
00360 {
00361 d->itemUrlToFind = url;
00362 }
00363
00364 void AlbumIconView::refreshIcon(AlbumIconItem* item)
00365 {
00366 if (!item)
00367 return;
00368
00369 emit signalSelectionChanged();
00370 }
00371
00372 void AlbumIconView::clear(bool update)
00373 {
00374 emit signalCleared();
00375
00376 d->itemDict.clear();
00377 d->albumDict.clear();
00378 d->itemInfoMap.clear();
00379
00380 IconView::clear(update);
00381
00382 emit signalSelectionChanged();
00383 }
00384
00385 void AlbumIconView::slotImageListerNewItems(const ImageInfoList& itemList)
00386 {
00387 if (!d->currentAlbum || d->currentAlbum->isRoot())
00388 return;
00389
00390 for (ImageInfoList::const_iterator it = itemList.constBegin(); it != itemList.constEnd(); ++it)
00391 {
00392 KUrl url( it->fileUrl() );
00393 url.cleanPath();
00394
00395 if (d->itemInfoMap.contains(*it))
00396 {
00397
00398
00399 continue;
00400 }
00401
00402 AlbumIconGroupItem* group = d->albumDict.value(it->albumId());
00403 if (!group)
00404 {
00405 group = new AlbumIconGroupItem(this, it->albumId());
00406 d->albumDict.insert(it->albumId(), group);
00407 }
00408
00409 PAlbum *album = AlbumManager::instance()->findPAlbum(it->albumId());
00410 if (!album)
00411 {
00412 kWarning() << "No album for item: " << it->name()
00413 << ", albumID: " << it->albumId();
00414 continue;
00415 }
00416
00417 AlbumIconItem* iconItem = new AlbumIconItem(group, (*it));
00418
00419 d->itemDict.insert(url.url(), iconItem);
00420 d->itemInfoMap.insert((*it), iconItem);
00421 }
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 if (!d->itemUrlToFind.isEmpty())
00436 {
00437 AlbumIconItem* icon = findItem(d->itemUrlToFind.url());
00438 if (icon)
00439 {
00440 clearSelection();
00441 updateContents();
00442 setCurrentItem(icon);
00443 ensureItemVisible(icon);
00444
00445
00446
00447 setStoredVisibleItem(icon);
00448 triggerRearrangement();
00449
00450
00451 d->itemUrlToFind = KUrl();
00452 }
00453 }
00454
00455 emit signalItemsAdded();
00456 }
00457
00458 void AlbumIconView::slotImageListerDeleteItem(const ImageInfo& item)
00459 {
00460 QHash<ImageInfo, AlbumIconItem*>::ConstIterator itMap = d->itemInfoMap.constFind(item);
00461 if (itMap == d->itemInfoMap.constEnd())
00462 return;
00463
00464 AlbumIconItem* iconItem = (*itMap);
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 emit signalItemDeleted(iconItem);
00483
00484 delete iconItem;
00485
00486 d->itemInfoMap.remove(item);
00487 d->itemDict.remove(item.fileUrl().url());
00488
00489 IconGroupItem* group = firstGroup();
00490 IconGroupItem* tmp;
00491
00492 while (group)
00493 {
00494 tmp = group->nextGroup();
00495
00496 if (group->count() == 0)
00497 {
00498 d->albumDict.remove(((AlbumIconGroupItem*)group)->albumID());
00499 delete group;
00500 }
00501
00502 group = tmp;
00503 }
00504 }
00505
00506 void AlbumIconView::slotImageListerClear()
00507 {
00508 clear();
00509 }
00510
00511 void AlbumIconView::slotDoubleClicked(IconItem *item)
00512 {
00513 if (!item) return;
00514
00515 if (d->albumSettings->getItemLeftClickAction() == AlbumSettings::ShowPreview)
00516 {
00517
00518
00519 signalPreviewItem(static_cast<AlbumIconItem *>(item));
00520 }
00521 else
00522 {
00523
00524
00525 slotDisplayItem(static_cast<AlbumIconItem *>(item));
00526 }
00527 }
00528
00529 void AlbumIconView::slotRightButtonClicked(const QPoint& pos)
00530 {
00531 if (!d->currentAlbum)
00532 return;
00533
00534 if (d->currentAlbum->isRoot() ||
00535 ( d->currentAlbum->type() != Album::PHYSICAL
00536 && d->currentAlbum->type() != Album::TAG))
00537 {
00538 return;
00539 }
00540
00541 KMenu popmenu(this);
00542 KAction *paste = KStandardAction::paste(this, SLOT(slotPaste()), 0);
00543 const QMimeData *data = kapp->clipboard()->mimeData(QClipboard::Clipboard);
00544
00545 if(!data || !KUrl::List::canDecode(data))
00546 paste->setEnabled(false);
00547
00548 popmenu.addAction(paste);
00549 popmenu.exec(pos);
00550 delete paste;
00551 }
00552
00553 void AlbumIconView::slotRightButtonClicked(IconItem *item, const QPoint&)
00554 {
00555 if (!item) return;
00556
00557 AlbumIconItem* iconItem = static_cast<AlbumIconItem *>(item);
00558 ImageInfo imageInfo = iconItem->imageInfo();
00559
00560
00561
00562 QList<qlonglong> selectedImageIDs;
00563 foreach (ImageInfo info, selectedImageInfosCurrentFirst())
00564 {
00565 selectedImageIDs << info.id();
00566 }
00567
00568
00569
00570 QAction *viewAction = new QAction(SmallIcon("viewimage"), i18nc("View the selected image", "View"), this);
00571 viewAction->setEnabled(selectedImageIDs.count() == 1);
00572
00573
00574
00575 DPopupMenu popmenu(this);
00576 ContextMenuHelper cmhelper(&popmenu);
00577
00578 cmhelper.addAction("album_new_from_selection");
00579 cmhelper.addAction(viewAction);
00580 cmhelper.addAction("image_edit");
00581 cmhelper.addServicesMenu(selectedItems());
00582 cmhelper.addKipiActions();
00583 popmenu.addSeparator();
00584
00585 cmhelper.addAction("image_find_similar");
00586 cmhelper.addActionLightTable();
00587 cmhelper.addQueueManagerMenu();
00588 cmhelper.addGotoMenu(selectedImageIDs);
00589 cmhelper.addAction("image_rename");
00590 popmenu.addSeparator();
00591
00592 cmhelper.addActionCopy(this, SLOT(slotCopy()));
00593 cmhelper.addActionPaste(this, SLOT(slotPaste()));
00594 cmhelper.addActionItemDelete(this, SLOT(slotDeleteSelectedItems()), selectedImageIDs.count());
00595 popmenu.addSeparator();
00596
00597 cmhelper.addActionThumbnail(selectedImageIDs, d->currentAlbum);
00598
00599 cmhelper.addAssignTagsMenu(selectedImageIDs);
00600 cmhelper.addRemoveTagsMenu(selectedImageIDs);
00601 popmenu.addSeparator();
00602
00603 cmhelper.addRatingMenu();
00604
00605
00606
00607 connect(&cmhelper, SIGNAL(signalAssignTag(int)),
00608 this, SLOT(slotAssignTag(int)));
00609
00610 connect(&cmhelper, SIGNAL(signalRemoveTag(int)),
00611 this, SLOT(slotRemoveTag(int)));
00612
00613 connect(&cmhelper, SIGNAL(signalGotoTag(int)),
00614 this, SLOT(slotGotoTag(int)));
00615
00616 connect(&cmhelper, SIGNAL(signalGotoAlbum(ImageInfo&)),
00617 this, SIGNAL(signalGotoAlbumAndItem(ImageInfo&)));
00618
00619 connect(&cmhelper, SIGNAL(signalGotoDate(ImageInfo&)),
00620 this, SIGNAL(signalGotoDateAndItem(ImageInfo&)));
00621
00622 connect(&cmhelper, SIGNAL(signalAssignRating(int)),
00623 this, SLOT(slotAssignRating(int)));
00624
00625 connect(&cmhelper, SIGNAL(signalSetThumbnail(ImageInfo&)),
00626 this, SLOT(slotSetAlbumThumbnail(ImageInfo&)));
00627
00628 connect(&cmhelper, SIGNAL(signalAddToExistingQueue(int)),
00629 this, SIGNAL(signalAddToExistingQueue(int)));
00630
00631
00632
00633 QAction *choice = cmhelper.exec(QCursor::pos());
00634 if (choice)
00635 {
00636 if (choice == viewAction)
00637 emit signalPreviewItem(iconItem);
00638 }
00639 }
00640
00641 void AlbumIconView::slotCopy()
00642 {
00643 if (!d->currentAlbum)
00644 return;
00645
00646 KUrl::List urls;
00647 KUrl::List kioURLs;
00648 QList<int> albumIDs;
00649 QList<int> imageIDs;
00650
00651 for (IconItem *it = firstItem(); it; it=it->nextItem())
00652 {
00653 if (it->isSelected())
00654 {
00655 AlbumIconItem *albumItem = static_cast<AlbumIconItem *>(it);
00656 ImageInfo info = albumItem->imageInfo();
00657 urls.append(info.fileUrl());
00658 kioURLs.append(info.databaseUrl());
00659 imageIDs.append(info.id());
00660 }
00661 }
00662 albumIDs.append(d->currentAlbum->id());
00663
00664 if (urls.isEmpty())
00665 return;
00666
00667 kapp->clipboard()->setMimeData(new DItemDrag(urls, kioURLs, albumIDs, imageIDs));
00668 }
00669
00670 void AlbumIconView::slotPaste()
00671 {
00672 const QMimeData *data = kapp->clipboard()->mimeData(QClipboard::Clipboard);
00673 if(!data)
00674 return;
00675
00676 Album *album = 0;
00677
00678
00679 if (groupCount() > 1)
00680 {
00681 AlbumIconGroupItem *grp = dynamic_cast<AlbumIconGroupItem*>(findGroup(QCursor::pos()));
00682 if (grp)
00683 {
00684 if(d->currentAlbum->type() == Album::PHYSICAL)
00685 album = dynamic_cast<Album*>(AlbumManager::instance()->findPAlbum(grp->albumID()));
00686 else if(d->currentAlbum->type() == Album::TAG)
00687 album = dynamic_cast<Album*>(AlbumManager::instance()->findTAlbum(grp->albumID()));
00688 }
00689 }
00690 if (!album)
00691 album = d->currentAlbum;
00692
00693 if (d->currentAlbum->type() == Album::PHYSICAL)
00694 {
00695 if (DItemDrag::canDecode(data))
00696 {
00697
00698
00699 PAlbum* palbum = (PAlbum*)album;
00700
00701
00702 if (palbum->isRoot())
00703 return;
00704
00705 KUrl::List urls;
00706 KUrl::List kioURLs;
00707 QList<int> albumIDs;
00708 QList<int> imageIDs;
00709
00710 if (!DItemDrag::decode(data, urls, kioURLs, albumIDs, imageIDs))
00711 return;
00712
00713 if (urls.isEmpty() || kioURLs.isEmpty() || albumIDs.isEmpty() || imageIDs.isEmpty())
00714 return;
00715
00716
00717 KUrl::List extUrls;
00718 QList<qlonglong> extImageIDs;
00719 for (QList<int>::ConstIterator it = imageIDs.constBegin(); it != imageIDs.constEnd(); ++it)
00720 {
00721 ImageInfo info(*it);
00722 if (info.albumId() != album->id())
00723 {
00724 extUrls << info.databaseUrl();
00725 extImageIDs << *it;
00726 }
00727 }
00728
00729 if(extUrls.isEmpty())
00730 return;
00731
00732 KIO::Job* job = DIO::copy(kioURLs, extImageIDs, palbum);
00733 connect(job, SIGNAL(result(KJob*)),
00734 this, SLOT(slotDIOResult(KJob*)));
00735 }
00736 else if (KUrl::List::canDecode(data))
00737 {
00738 PAlbum* palbum = (PAlbum*)album;
00739
00740
00741 if (palbum->isRoot())
00742 return;
00743
00744 KUrl::List srcURLs = KUrl::List::fromMimeData(data);
00745
00746 KIO::Job* job = DIO::copy(srcURLs, palbum);
00747 connect(job, SIGNAL(result(KJob*)),
00748 this, SLOT(slotDIOResult(KJob*)));
00749 }
00750 }
00751 else if(d->currentAlbum->type() == Album::TAG && DItemDrag::canDecode(data))
00752 {
00753 TAlbum* talbum = (TAlbum*)album;
00754
00755
00756 if (talbum->isRoot())
00757 return;
00758
00759 KUrl::List urls;
00760 KUrl::List kioURLs;
00761 QList<int> albumIDs;
00762 QList<int> imageIDs;
00763
00764 if (!DItemDrag::decode(data, urls, kioURLs, albumIDs, imageIDs))
00765 return;
00766
00767 if (urls.isEmpty() || kioURLs.isEmpty() || albumIDs.isEmpty() || imageIDs.isEmpty())
00768 return;
00769
00770 ImageInfoList list;
00771 for (QList<int>::const_iterator it = imageIDs.constBegin();
00772 it != imageIDs.constEnd(); ++it)
00773 {
00774 ImageInfo info(*it);
00775 list.append(info);
00776 }
00777
00778 emit changeTagOnImageInfos(list, QList<int>() << talbum->id(), true, true);
00779 }
00780 }
00781
00782 void AlbumIconView::slotSetAlbumThumbnail(ImageInfo& imageInfo)
00783 {
00784 if(!d->currentAlbum)
00785 return;
00786
00787 if(d->currentAlbum->type() == Album::PHYSICAL)
00788 {
00789 PAlbum *album = static_cast<PAlbum*>(d->currentAlbum);
00790
00791 QString err;
00792 AlbumManager::instance()->updatePAlbumIcon( album,
00793 imageInfo.id(),
00794 err );
00795 }
00796 else if (d->currentAlbum->type() == Album::TAG)
00797 {
00798 TAlbum *album = static_cast<TAlbum*>(d->currentAlbum);
00799
00800 QString err;
00801 AlbumManager::instance()->updateTAlbumIcon( album,
00802 QString(),
00803 imageInfo.id(),
00804 err );
00805 }
00806 }
00807
00808 void AlbumIconView::slotRename(AlbumIconItem* item)
00809 {
00810 if (!item)
00811 return;
00812
00813
00814
00815 ImageInfo renameInfo = item->imageInfo();
00816
00817 QFileInfo fi(renameInfo.name());
00818 QString ext = QString(".") + fi.suffix();
00819 QString name = fi.fileName();
00820 name.truncate(fi.fileName().length() - ext.length());
00821
00822 bool ok;
00823
00824 QString newName = KInputDialog::getText(i18n("Rename Item (%1)",fi.fileName()),
00825 i18n("Enter new name (without extension):"),
00826 name, &ok, this);
00827 if (!ok)
00828 return;
00829
00830 KIO::CopyJob* job = DIO::rename(renameInfo, newName + ext);
00831
00832 connect(job, SIGNAL(result(KJob*)),
00833 this, SLOT(slotDIOResult(KJob*)));
00834
00835 connect(job, SIGNAL(copyingDone(KIO::Job *, const KUrl &, const KUrl &, bool, bool)),
00836 this, SLOT(slotRenamed(KIO::Job*, const KUrl &, const KUrl&)));
00837
00838
00839
00840
00841
00842
00843 d->imageLister->invalidateItem(renameInfo);
00844 }
00845
00846 void AlbumIconView::slotRenamed(KIO::Job*, const KUrl &, const KUrl&newURL)
00847 {
00848
00849 KUrl fileURL;
00850 fileURL.setPath(newURL.user());
00851 fileURL.addPath(newURL.path());
00852
00853
00854 ThumbnailLoadThread::deleteThumbnail(fileURL.path());
00855
00856 LoadingCacheInterface::fileChanged(fileURL.path());
00857 }
00858
00859 void AlbumIconView::slotDeleteSelectedItems(bool deletePermanently)
00860 {
00861 KUrl::List urlList;
00862 KUrl::List kioUrlList;
00863
00864 for (IconItem *it = firstItem(); it; it=it->nextItem())
00865 {
00866 if (it->isSelected())
00867 {
00868 AlbumIconItem *iconItem = static_cast<AlbumIconItem *>(it);
00869 ImageInfo info = iconItem->imageInfo();
00870 urlList.append(info.fileUrl());
00871 kioUrlList.append(info.databaseUrl());
00872 }
00873 }
00874
00875 if (urlList.count() <= 0)
00876 return;
00877
00878 DeleteDialog dialog(this);
00879
00880 if (!dialog.confirmDeleteList(urlList,
00881 DeleteDialogMode::Files,
00882 deletePermanently ?
00883 DeleteDialogMode::NoChoiceDeletePermanently :
00884 DeleteDialogMode::NoChoiceTrash))
00885 return;
00886
00887 bool useTrash = !dialog.shouldDelete();
00888
00889
00890 KIO::Job* job = DIO::del(useTrash ? urlList : kioUrlList, useTrash);
00891
00892 connect(job, SIGNAL(result(KJob*)),
00893 this, SLOT(slotDIOResult(KJob*)));
00894 }
00895
00896 void AlbumIconView::slotDeleteSelectedItemsDirectly(bool useTrash)
00897 {
00898
00899
00900
00901 KUrl::List kioUrlList;
00902 KUrl::List urlList;
00903
00904 for (IconItem *it = firstItem(); it; it=it->nextItem())
00905 {
00906 if (it->isSelected())
00907 {
00908 AlbumIconItem *iconItem = static_cast<AlbumIconItem *>(it);
00909 ImageInfo info = iconItem->imageInfo();
00910 kioUrlList.append(info.databaseUrl());
00911 urlList.append(info.fileUrl());
00912 }
00913 }
00914
00915 if (kioUrlList.count() <= 0)
00916 return;
00917
00918
00919 KIO::Job* job = DIO::del(useTrash ? urlList : kioUrlList , useTrash);
00920
00921 connect(job, SIGNAL(result(KJob*)),
00922 this, SLOT(slotDIOResult(KJob*)));
00923 }
00924
00925 void AlbumIconView::slotFilesModified()
00926 {
00927 d->imageLister->refresh();
00928 }
00929
00930 void AlbumIconView::slotFilesModified(const KUrl& url)
00931 {
00932 refreshItems(url);
00933 }
00934
00935 void AlbumIconView::slotImageWindowURLChanged(const KUrl& url)
00936 {
00937 IconItem* item = findItem(url.url());
00938 if (item)
00939 setCurrentItem(item);
00940 }
00941
00942 void AlbumIconView::slotDisplayItem(AlbumIconItem *item)
00943 {
00944 if (!item) return;
00945
00946 AlbumSettings *settings = AlbumSettings::instance();
00947
00948 if (!settings) return;
00949
00950 QString currentFileExtension = item->imageInfo().name().section( '.', -1 );
00951 QString imagefilter = settings->getImageFileFilter().toLower() +
00952 settings->getImageFileFilter().toUpper();
00953
00954 #if KDCRAW_VERSION < 0x000400
00955 if (KDcrawIface::DcrawBinary::instance()->versionIsRight())
00956 {
00957
00958 imagefilter += settings->getRawFileFilter().toLower() +
00959 settings->getRawFileFilter().toUpper();
00960 }
00961 #else
00962
00963 imagefilter += settings->getRawFileFilter().toLower() +
00964 settings->getRawFileFilter().toUpper();
00965 #endif
00966
00967
00968 if ( !imagefilter.contains(currentFileExtension) )
00969 {
00970 KMimeType::Ptr mimePtr = KMimeType::findByUrl(item->imageInfo().fileUrl(), 0, true, true);
00971 const KService::List offers = KServiceTypeTrader::self()->query(mimePtr->name(), "Type == 'Application'");
00972
00973 if (offers.isEmpty())
00974 return;
00975
00976 KService::Ptr ptr = offers.first();
00977
00978 KRun::run(*ptr, item->imageInfo().fileUrl(), this);
00979 return;
00980 }
00981
00982
00983
00984 ImageInfoList list;
00985 ImageInfo current;
00986
00987 for (IconItem *it = firstItem() ; it ; it = it->nextItem())
00988 {
00989 AlbumIconItem *iconItem = static_cast<AlbumIconItem*>(it);
00990 ImageInfo info = iconItem->imageInfo();
00991 QString fileExtension = info.fileUrl().fileName().section( '.', -1 );
00992
00993 if ( imagefilter.indexOf(fileExtension) != -1 )
00994 {
00995 list << info;
00996 if (iconItem == item)
00997 current = info;
00998 }
00999 }
01000
01001 ImageWindow *imview = ImageWindow::imagewindow();
01002
01003 imview->disconnect(this);
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014 connect(imview, SIGNAL(signalURLChanged(const KUrl&)),
01015 this, SLOT(slotImageWindowURLChanged(const KUrl &)));
01016
01017 imview->loadImageInfos(list, current,
01018 d->currentAlbum ? i18n("Album \"%1\"",d->currentAlbum->title()) : QString(),
01019 true);
01020
01021 if (imview->isHidden())
01022 imview->show();
01023
01024 if (imview->isMinimized())
01025 KWindowSystem::unminimizeWindow(imview->winId());
01026 KWindowSystem::activateWindow(imview->winId());
01027 }
01028
01029 void AlbumIconView::insertSelectionToLightTable(bool addTo)
01030 {
01031
01032
01033
01034 ImageInfoList imageInfoList;
01035
01036 for (IconItem *it = firstItem() ; it ; it = it->nextItem())
01037 {
01038 if ((*it).isSelected())
01039 {
01040 AlbumIconItem *iconItem = static_cast<AlbumIconItem *>(it);
01041 imageInfoList << iconItem->imageInfo();
01042 }
01043 }
01044
01045 insertToLightTable(imageInfoList, imageInfoList.first(), addTo);
01046 }
01047
01048 void AlbumIconView::insertToLightTable(const ImageInfoList& list, const ImageInfo& current, bool addTo)
01049 {
01050 LightTableWindow *ltview = LightTableWindow::lightTableWindow();
01051
01052
01053
01054 ltview->loadImageInfos(list, current, addTo);
01055 ltview->setLeftRightItems(list, addTo);
01056
01057 if (ltview->isHidden())
01058 ltview->show();
01059
01060 if (ltview->isMinimized())
01061 KWindowSystem::unminimizeWindow(ltview->winId());
01062 KWindowSystem::activateWindow(ltview->winId());
01063
01064 }
01065
01066
01067
01068 void AlbumIconView::insertSelectionToCurrentQueue()
01069 {
01070 ImageInfoList imageInfoList = selectedImageInfos();
01071 insertToQueueManager(imageInfoList, imageInfoList.first(), false);
01072 }
01073
01074 void AlbumIconView::insertSelectionToNewQueue()
01075 {
01076 ImageInfoList imageInfoList = selectedImageInfos();
01077 insertToQueueManager(imageInfoList, imageInfoList.first(), true);
01078 }
01079
01080 void AlbumIconView::insertToQueueManager(const ImageInfoList& list, const ImageInfo& , bool newQueue)
01081 {
01082 QueueMgrWindow *bqmview = QueueMgrWindow::queueManagerWindow();
01083
01084 if (bqmview->isHidden())
01085 bqmview->show();
01086
01087 if (bqmview->isMinimized())
01088 KWindowSystem::unminimizeWindow(bqmview->winId());
01089 KWindowSystem::activateWindow(bqmview->winId());
01090
01091 if (newQueue) bqmview->addNewQueue();
01092
01093 bqmview->loadImageInfos(list, bqmview->currentQueueId());
01094 }
01095
01096 void AlbumIconView::insertSilentToQueueManager(const ImageInfoList& list, const ImageInfo& , int queueid)
01097 {
01098 QueueMgrWindow *bqmview = QueueMgrWindow::queueManagerWindow();
01099 bqmview->loadImageInfos(list, queueid);
01100 }
01101
01102
01103
01104 AlbumIconItem* AlbumIconView::firstSelectedItem() const
01105 {
01106 AlbumIconItem *iconItem = 0;
01107 for (IconItem *it = firstItem(); it; it = it->nextItem())
01108 {
01109 if (it->isSelected())
01110 {
01111 iconItem = static_cast<AlbumIconItem *>(it);
01112 break;
01113 }
01114 }
01115
01116 return iconItem;
01117 }
01118
01119 const AlbumSettings* AlbumIconView::settings() const
01120 {
01121 return d->albumSettings;
01122 }
01123
01124 ThumbnailSize AlbumIconView::thumbnailSize() const
01125 {
01126 return d->thumbSize;
01127 }
01128
01129 void AlbumIconView::resizeEvent(QResizeEvent *e)
01130 {
01131 IconView::resizeEvent(e);
01132
01133 if (d->bannerRect.width() != frameRect().width())
01134 updateRectsAndPixmaps();
01135 }
01136
01137
01138
01139 void AlbumIconView::startDrag()
01140 {
01141 if (!d->currentAlbum)
01142 return;
01143
01144 KUrl::List urls;
01145 KUrl::List kioURLs;
01146 QList<int> albumIDs;
01147 QList<int> imageIDs;
01148
01149 for (IconItem *it = firstItem(); it; it=it->nextItem())
01150 {
01151 if (it->isSelected())
01152 {
01153 AlbumIconItem *albumItem = static_cast<AlbumIconItem *>(it);
01154 ImageInfo info = albumItem->imageInfo();
01155 urls.append(info.fileUrl());
01156 kioURLs.append(info.databaseUrl());
01157 imageIDs.append(info.id());
01158 }
01159 }
01160 albumIDs.append(d->currentAlbum->id());
01161
01162 if (urls.isEmpty())
01163 return;
01164
01165 QPixmap icon(DesktopIcon("image-jp2", 48));
01166 int w = icon.width();
01167 int h = icon.height();
01168
01169 QPixmap pix(w+4, h+4);
01170 QString text(QString::number(urls.count()));
01171
01172 QPainter p(&pix);
01173 p.fillRect(0, 0, pix.width()-1, pix.height()-1, QColor(Qt::white));
01174 p.setPen(QPen(Qt::black, 1));
01175 p.drawRect(0, 0, pix.width()-1, pix.height()-1);
01176 p.drawPixmap(2, 2, icon);
01177 QRect r = p.boundingRect(2, 2, w, h, Qt::AlignLeft|Qt::AlignTop, text);
01178 r.setWidth(qMax(r.width(), r.height()));
01179 r.setHeight(qMax(r.width(), r.height()));
01180 p.fillRect(r, QColor(0, 80, 0));
01181 p.setPen(Qt::white);
01182 QFont f(font());
01183 f.setBold(true);
01184 p.setFont(f);
01185 p.drawText(r, Qt::AlignCenter, text);
01186 p.end();
01187
01188 QDrag* drag = new QDrag(this);
01189 drag->setMimeData(new DItemDrag(urls, kioURLs, albumIDs, imageIDs));
01190 drag->setPixmap(pix);
01191 drag->exec();
01192 }
01193
01194 void AlbumIconView::contentsDragEnterEvent(QDragEnterEvent *e)
01195 {
01196 if (!d->currentAlbum || (DAlbumDrag::canDecode(e->mimeData()) ||
01197 (!KUrl::List::canDecode(e->mimeData()) &&
01198 !DCameraDragObject::canDecode(e->mimeData()) &&
01199 !DTagListDrag::canDecode(e->mimeData()) &&
01200 !DTagDrag::canDecode(e->mimeData()) &&
01201 !DCameraItemListDrag::canDecode(e->mimeData()) &&
01202 !DItemDrag::canDecode(e->mimeData()))))
01203 {
01204 return;
01205 }
01206 e->acceptProposedAction();
01207 }
01208
01209 void AlbumIconView::contentsDropEvent(QDropEvent *e)
01210 {
01211 if (!d->currentAlbum || (DAlbumDrag::canDecode(e->mimeData()) ||
01212 (!KUrl::List::canDecode(e->mimeData()) &&
01213 !DCameraDragObject::canDecode(e->mimeData()) &&
01214 !DTagListDrag::canDecode(e->mimeData()) &&
01215 !DTagDrag::canDecode(e->mimeData()) &&
01216 !DCameraItemListDrag::canDecode(e->mimeData()) &&
01217 !DItemDrag::canDecode(e->mimeData()))))
01218 {
01219 e->ignore();
01220 return;
01221 }
01222
01223 Album *album = 0;
01224
01225
01226 if (groupCount() > 1)
01227 {
01228 AlbumIconGroupItem *grp = dynamic_cast<AlbumIconGroupItem*>(findGroup(QCursor::pos()));
01229 if (grp)
01230 {
01231 if(d->currentAlbum->type() == Album::PHYSICAL)
01232 album = dynamic_cast<Album*>(AlbumManager::instance()->findPAlbum(grp->albumID()));
01233 else if(d->currentAlbum->type() == Album::TAG)
01234 album = dynamic_cast<Album*>(AlbumManager::instance()->findTAlbum(grp->albumID()));
01235 }
01236 }
01237 if (!album)
01238 album = d->currentAlbum;
01239
01240 KUrl::List urls;
01241 KUrl::List kioURLs;
01242 QList<int> albumIDs;
01243 QList<int> imageIDs;
01244
01245 if (DItemDrag::decode(e->mimeData(), urls, kioURLs, albumIDs, imageIDs))
01246 {
01247
01248
01249
01250 KUrl::List extUrls;
01251 QList<qlonglong> extImageIDs;
01252 for (QList<int>::const_iterator it = imageIDs.constBegin(); it != imageIDs.constEnd(); ++it)
01253 {
01254 ImageInfo info(*it);
01255 if (info.albumId() != album->id())
01256 {
01257 extUrls << info.databaseUrl();
01258 extImageIDs << *it;
01259 }
01260 }
01261
01262 if(extUrls.isEmpty())
01263 {
01264 e->ignore();
01265 return;
01266 }
01267 else if (album->type() == Album::PHYSICAL)
01268 {
01269 PAlbum* palbum = (PAlbum*)album;
01270
01271 KMenu popMenu(this);
01272 QAction *moveAction = popMenu.addAction( SmallIcon("go-jump"), i18n("&Move Here"));
01273 QAction *copyAction = popMenu.addAction( SmallIcon("edit-copy"), i18n("&Copy Here"));
01274 popMenu.addSeparator();
01275 popMenu.addAction( SmallIcon("dialog-cancel"), i18n("C&ancel") );
01276
01277 popMenu.setMouseTracking(true);
01278 QAction *choice = popMenu.exec(QCursor::pos());
01279 if (choice == moveAction)
01280 {
01281 KIO::Job* job = DIO::move(extUrls, extImageIDs, palbum);
01282 connect(job, SIGNAL(result(KJob*)),
01283 this, SLOT(slotDIOResult(KJob*)));
01284 }
01285 else if (choice == copyAction)
01286 {
01287 KIO::Job* job = DIO::copy(extUrls, extImageIDs, palbum);
01288 connect(job, SIGNAL(result(KJob*)),
01289 this, SLOT(slotDIOResult(KJob*)));
01290 }
01291 }
01292 }
01293 else if (KUrl::List::canDecode(e->mimeData()) && d->currentAlbum->type() == Album::PHYSICAL)
01294 {
01295
01296 PAlbum* palbum = (PAlbum*)album;
01297
01298 KUrl::List srcURLs = KUrl::List::fromMimeData(e->mimeData());
01299
01300 KMenu popMenu(this);
01301 QAction *moveAction = popMenu.addAction( SmallIcon("go-jump"), i18n("&Move Here"));
01302 QAction *copyAction = popMenu.addAction( SmallIcon("edit-copy"), i18n("&Copy Here"));
01303 popMenu.addSeparator();
01304 popMenu.addAction( SmallIcon("dialog-cancel"), i18n("C&ancel") );
01305
01306 popMenu.setMouseTracking(true);
01307 QAction *choice = popMenu.exec(QCursor::pos());
01308 if (choice == moveAction)
01309 {
01310 KIO::Job* job = DIO::move(srcURLs, palbum);
01311 connect(job, SIGNAL(result(KJob*)),
01312 this, SLOT(slotDIOResult(KJob*)));
01313 }
01314 else if (choice == copyAction)
01315 {
01316 KIO::Job* job = DIO::copy(srcURLs, palbum);
01317 connect(job, SIGNAL(result(KJob*)),
01318 this, SLOT(slotDIOResult(KJob*)));
01319 }
01320 }
01321 else if(DTagDrag::canDecode(e->mimeData()))
01322 {
01323 int tagID;
01324 if (!DTagDrag::decode(e->mimeData(), tagID))
01325 return;
01326
01327 AlbumManager* man = AlbumManager::instance();
01328 TAlbum* talbum = man->findTAlbum(tagID);
01329
01330 if (talbum)
01331 {
01332 KMenu popMenu(this);
01333
01334 bool moreItemsSelected = false;
01335 bool itemDropped = false;
01336
01337 AlbumIconItem *albumItem = findItem(e->pos());
01338 if (albumItem)
01339 itemDropped = true;
01340
01341 for (IconItem *it = firstItem(); it; it = it->nextItem())
01342 {
01343 if (it->isSelected() && it != albumItem)
01344 {
01345 moreItemsSelected = true;
01346 break;
01347 }
01348 }
01349
01350 QAction *assignToSelectedAction = 0;
01351 if (moreItemsSelected)
01352 assignToSelectedAction =
01353 popMenu.addAction(SmallIcon("tag"), i18n("Assign '%1' to &Selected Items",talbum->tagPath().mid(1)));
01354
01355 QAction *assignToThisAction = 0;
01356 if (itemDropped)
01357 assignToThisAction =
01358 popMenu.addAction(SmallIcon("tag"), i18n("Assign '%1' to &This Item",talbum->tagPath().mid(1)));
01359
01360 QAction *assignToAllAction =
01361 popMenu.addAction(SmallIcon("tag"), i18n("Assign '%1' to &All Items",talbum->tagPath().mid(1)));
01362
01363 popMenu.addSeparator();
01364 popMenu.addAction(SmallIcon("dialog-cancel"), i18n("&Cancel"));
01365
01366 popMenu.setMouseTracking(true);
01367 QAction *choice = popMenu.exec(QCursor::pos());
01368 if (choice)
01369 {
01370 if (choice == assignToSelectedAction)
01371 {
01372 emit changeTagOnImageInfos(selectedImageInfosCurrentFirst(), QList<int>() << tagID, true, true);
01373 }
01374 else if (choice == assignToAllAction)
01375 {
01376 emit changeTagOnImageInfos(allImageInfos(), QList<int>() << tagID, true, true);
01377 }
01378 else if (choice == assignToThisAction)
01379 {
01380 AlbumIconItem *albumItem = findItem(e->pos());
01381 if (albumItem)
01382 {
01383 ImageInfoList infos;
01384 infos << albumItem->imageInfo();
01385 emit changeTagOnImageInfos(infos, QList<int>() << tagID, true, false);
01386 }
01387 }
01388 }
01389 }
01390 }
01391 else if(DTagListDrag::canDecode(e->mimeData()))
01392 {
01393 QList<int> tagIDs;
01394 DTagListDrag::decode(e->mimeData(), tagIDs);
01395
01396 KMenu popMenu(this);
01397
01398 bool moreItemsSelected = false;
01399 bool itemDropped = false;
01400
01401 AlbumIconItem *albumItem = findItem(e->pos());
01402 if (albumItem)
01403 itemDropped = true;
01404
01405 for (IconItem *it = firstItem(); it; it = it->nextItem())
01406 {
01407 if (it->isSelected() && it != albumItem)
01408 {
01409 moreItemsSelected = true;
01410 break;
01411 }
01412 }
01413
01414 QAction *assignToSelectedAction = 0;
01415 if (moreItemsSelected)
01416 assignToSelectedAction = popMenu.addAction(SmallIcon("tag"), i18n("Assign Tags to &Selected Items"));
01417
01418 QAction *assignToThisAction = 0;
01419 if (itemDropped)
01420 assignToThisAction = popMenu.addAction(SmallIcon("tag"), i18n("Assign Tags to &This Item"));
01421
01422 QAction *assignToAllAction =
01423 popMenu.addAction(SmallIcon("tag"), i18n("Assign Tags to &All Items"));
01424
01425 popMenu.addSeparator();
01426 popMenu.addAction(SmallIcon("dialog-cancel"), i18n("&Cancel"));
01427
01428 popMenu.setMouseTracking(true);
01429 QAction *choice = popMenu.exec(QCursor::pos());
01430 if (choice)
01431 {
01432 if (choice == assignToSelectedAction)
01433 {
01434 slotChangeTagOnImageInfos(selectedImageInfosCurrentFirst(), tagIDs, true, true);
01435 }
01436 else if (choice == assignToAllAction)
01437 {
01438 slotChangeTagOnImageInfos(allImageInfos(), tagIDs, true, true);
01439 }
01440 else if (choice == assignToThisAction)
01441 {
01442 AlbumIconItem *albumItem = findItem(e->pos());
01443 if (albumItem)
01444 {
01445 ImageInfoList infos;
01446 infos << albumItem->imageInfo();
01447 slotChangeTagOnImageInfos(infos, tagIDs, true, false);
01448 }
01449 }
01450 }
01451 }
01452 else if(DCameraItemListDrag::canDecode(e->mimeData()))
01453 {
01454 CameraUI *ui = dynamic_cast<CameraUI*>(e->source());
01455 if (ui)
01456 {
01457 KMenu popMenu(this);
01458 popMenu.addTitle(SmallIcon("digikam"), i18n("My Albums"));
01459 QAction *downAction = popMenu.addAction(SmallIcon("file-export"),
01460 i18n("Download From Camera"));
01461 QAction *downDelAction = popMenu.addAction(SmallIcon("file-export"),
01462 i18n("Download && Delete From Camera"));
01463 popMenu.addSeparator();
01464 popMenu.addAction(SmallIcon("dialog-cancel"), i18n("C&ancel"));
01465 popMenu.setMouseTracking(true);
01466 QAction *choice = popMenu.exec(QCursor::pos());
01467 if (choice)
01468 {
01469 if (choice == downAction)
01470 ui->slotDownload(true, false, album);
01471 else if (choice == downDelAction)
01472 ui->slotDownload(true, true, album);
01473 }
01474 }
01475 }
01476 else
01477 {
01478 e->ignore();
01479 }
01480 }
01481
01482 void AlbumIconView::slotChangeTagOnImageInfos(const ImageInfoList& list, const QList<int>& tagIDs, bool addOrRemove, bool progress)
01483 {
01484 float cnt = list.count();
01485 int i = 0;
01486
01487 if (progress)
01488 {
01489 if (addOrRemove)
01490 emit signalProgressBarMode(StatusProgressBar::ProgressBarMode,
01491 i18n("Assigning image tags. Please wait..."));
01492 else
01493 emit signalProgressBarMode(StatusProgressBar::ProgressBarMode,
01494 i18n("Removing image tags. Please wait..."));
01495 }
01496
01497 d->imageLister->blockSignals(true);
01498 ScanController::instance()->suspendCollectionScan();
01499 DatabaseTransaction transaction;
01500 foreach(const ImageInfo& info, list)
01501 {
01502 MetadataHub hub;
01503
01504 hub.load(info);
01505
01506 for (QList<int>::const_iterator tagIt = tagIDs.constBegin(); tagIt != tagIDs.constEnd(); ++tagIt)
01507 {
01508 hub.setTag(*tagIt, addOrRemove);
01509 }
01510
01511 QString filePath = info.filePath();
01512 hub.write(info, MetadataHub::PartialWrite);
01513 bool fileChanged = hub.write(filePath, MetadataHub::FullWriteIfChanged);
01514 if (fileChanged)
01515 ScanController::instance()->scanFileDirectly(filePath);
01516
01517 if (progress)
01518 {
01519 emit signalProgressValue((int)((i++/cnt)*100.0));
01520 kapp->processEvents();
01521 }
01522 }
01523 ScanController::instance()->resumeCollectionScan();
01524 d->imageLister->blockSignals(false);
01525
01526 if (progress)
01527 emit signalProgressBarMode(StatusProgressBar::TextMode, QString());
01528
01529 if (d->currentAlbum && d->currentAlbum->type() == Album::TAG)
01530 {
01531 d->imageLister->refresh();
01532 }
01533 updateContents();
01534 }
01535
01536 bool AlbumIconView::acceptToolTip(IconItem *item, const QPoint& mousePos)
01537 {
01538 AlbumIconItem *iconItem = dynamic_cast<AlbumIconItem*>(item);
01539
01540 if (iconItem && iconItem->clickToOpenRect().contains(mousePos))
01541 {
01542 return true;
01543 }
01544 else
01545 {
01546 return false;
01547 }
01548 }
01549
01550 void AlbumIconView::slotShowToolTip(IconItem* item)
01551 {
01552 d->toolTip->setIconItem(dynamic_cast<AlbumIconItem*>(item));
01553 }
01554
01555 KUrl::List AlbumIconView::allItems()
01556 {
01557 KUrl::List itemList;
01558
01559 for (IconItem *it = firstItem(); it; it = it->nextItem())
01560 {
01561 AlbumIconItem *item = (AlbumIconItem*) it;
01562 itemList.append(item->imageInfo().fileUrl());
01563 }
01564
01565 return itemList;
01566 }
01567
01568 KUrl::List AlbumIconView::selectedItems()
01569 {
01570 KUrl::List itemList;
01571
01572 for (IconItem *it = firstItem(); it; it = it->nextItem())
01573 {
01574 if (it->isSelected())
01575 {
01576 AlbumIconItem *item = (AlbumIconItem*) it;
01577 itemList.append(item->imageInfo().fileUrl());
01578 }
01579 }
01580
01581 return itemList;
01582 }
01583
01584 ImageInfoList AlbumIconView::allImageInfos(ImageInfo* current) const
01585 {
01586 if (current)
01587 {
01588
01589
01590 if (firstItem())
01591 *current = static_cast<AlbumIconItem*>(firstItem())->imageInfo();
01592 else
01593 *current = ImageInfo();
01594 }
01595
01596 IconItem *currentIconItem = currentItem();
01597 ImageInfoList list;
01598 for (IconItem *it = firstItem() ; it ; it = it->nextItem())
01599 {
01600 AlbumIconItem *iconItem = static_cast<AlbumIconItem*>(it);
01601 ImageInfo info = iconItem->imageInfo();
01602
01603 list << info;
01604
01605
01606 if (current && iconItem == currentIconItem)
01607 *current = info;
01608 }
01609
01610 return list;
01611 }
01612
01613 ImageInfoList AlbumIconView::selectedImageInfosCurrentFirst() const
01614 {
01615
01616
01617 ImageInfoList list;
01618 for (IconItem *it = firstItem(); it; it = it->nextItem())
01619 {
01620 AlbumIconItem *iconItem = static_cast<AlbumIconItem *>(it);
01621 if (it->isSelected())
01622 {
01623 ImageInfo info = iconItem->imageInfo();
01624
01625 if (iconItem == currentItem())
01626 list.prepend(info);
01627 else
01628 list.append(info);
01629 }
01630 }
01631 return list;
01632 }
01633
01634 ImageInfoList AlbumIconView::selectedImageInfos() const
01635 {
01636
01637 ImageInfoList list;
01638 for (IconItem *it = firstItem(); it; it = it->nextItem())
01639 {
01640 if (it->isSelected())
01641 {
01642 AlbumIconItem *iconItem = static_cast<AlbumIconItem *>(it);
01643 list << iconItem->imageInfo();
01644 }
01645 }
01646 return list;
01647 }
01648
01649 void AlbumIconView::refresh()
01650 {
01651 d->imageLister->stop();
01652 clear();
01653
01654 d->imageLister->openAlbum(d->currentAlbum);
01655 }
01656
01657 void AlbumIconView::refreshItems(const KUrl::List& urlList)
01658 {
01659 if (!d->currentAlbum || urlList.empty())
01660 return;
01661
01662
01663
01664
01665
01666 for (KUrl::List::const_iterator it = urlList.constBegin();
01667 it != urlList.constEnd(); ++it)
01668 {
01669 AlbumIconItem* iconItem = findItem((*it).url());
01670 if (!iconItem)
01671 continue;
01672
01673 ThumbnailLoadThread::deleteThumbnail((*it).toLocalFile());
01674
01675 LoadingCacheInterface::fileChanged((*it).toLocalFile());
01676 }
01677
01678 emit signalItemsUpdated(urlList);
01679
01680
01681 triggerRearrangement();
01682 }
01683
01684 void AlbumIconView::slotFileChanged(const QString& filePath)
01685 {
01686 if (!d->currentAlbum || filePath.isEmpty())
01687 return;
01688
01689 KUrl url = KUrl::fromPath(filePath);
01690
01691 AlbumIconItem* iconItem = findItem(url.url());
01692 if (!iconItem)
01693 return;
01694 iconItem->update();
01695
01696 emit signalItemsUpdated(KUrl::List() << url);
01697 }
01698
01699 void AlbumIconView::slotThumbnailLoaded(const LoadingDescription& loadingDescription, const QPixmap&)
01700 {
01701 AlbumIconItem* iconItem = findItem(KUrl::fromPath(loadingDescription.filePath).url());
01702 if (!iconItem)
01703 return;
01704
01705 iconItem->update();
01706 }
01707
01708 void AlbumIconView::prepareRepaint(const QList<IconItem *>& itemsToRepaint)
01709 {
01710 QStringList filePaths;
01711 foreach(IconItem *iconItem, itemsToRepaint)
01712 {
01713 AlbumIconItem *item = static_cast<AlbumIconItem *>(iconItem);
01714 filePaths << item->filePath();
01715 }
01716 ThumbnailLoadThread::defaultIconViewThread()->findGroup(filePaths);
01717 }
01718
01719 void AlbumIconView::slotSelectionChanged()
01720 {
01721 if (firstSelectedItem())
01722 emitItemsSelected(true);
01723 else
01724 emitItemsSelected(false);
01725 }
01726
01727 void AlbumIconView::slotSetExifOrientation( int orientation )
01728 {
01729 KUrl::List urlList;
01730 int i = 0;
01731
01732 for (IconItem *it = firstItem(); it; it=it->nextItem())
01733 {
01734 if (it->isSelected())
01735 {
01736 AlbumIconItem *iconItem = static_cast<AlbumIconItem *>(it);
01737 urlList.append(iconItem->imageInfo().fileUrl());
01738 }
01739 }
01740
01741 if (urlList.count() <= 0) return;
01742
01743 QStringList failedItems;
01744 KUrl::List::Iterator it;
01745 float cnt = (float)urlList.count();
01746 emit signalProgressBarMode(StatusProgressBar::ProgressBarMode,
01747 i18n("Revising Exif Orientation tags. Please wait..."));
01748
01749 for( it = urlList.begin(); it != urlList.end(); ++it )
01750 {
01751 kDebug() << "Setting Exif Orientation tag to " << orientation;
01752
01753 DMetadata metadata((*it).toLocalFile());
01754 DMetadata::ImageOrientation o = (DMetadata::ImageOrientation)orientation;
01755 metadata.setImageOrientation(o);
01756 metadata.setWriteRawFiles(AlbumSettings::instance()->getWriteRawFiles());
01757
01758 if (!metadata.applyChanges())
01759 {
01760 failedItems.append((*it).fileName());
01761 }
01762 else
01763 {
01764 ImageAttributesWatch::instance()->fileMetadataChanged((*it));
01765 }
01766
01767 emit signalProgressValue((int)((i++/cnt)*100.0));
01768 kapp->processEvents();
01769 }
01770
01771 emit signalProgressBarMode(StatusProgressBar::TextMode, QString());
01772
01773 if (!failedItems.isEmpty())
01774 {
01775 if (failedItems.count() == 1)
01776 {
01777 KMessageBox::error(0, i18n("Failed to revise Exif orientation for file %1.",
01778 failedItems[0]));
01779 }
01780 else
01781 {
01782 KMessageBox::errorList(0, i18n("Failed to revise Exif orientation these files:"),
01783 failedItems);
01784 }
01785 }
01786
01787 refreshItems(urlList);
01788 }
01789
01790 QRect AlbumIconView::itemRect() const
01791 {
01792 return d->itemRect;
01793 }
01794
01795 QRect AlbumIconView::itemRatingRect() const
01796 {
01797 return d->itemRatingRect;
01798 }
01799
01800 QRect AlbumIconView::itemDateRect() const
01801 {
01802 return d->itemDateRect;
01803 }
01804
01805 QRect AlbumIconView::itemModDateRect() const
01806 {
01807 return d->itemModDateRect;
01808 }
01809
01810 QRect AlbumIconView::itemPixmapRect() const
01811 {
01812 return d->itemPixmapRect;
01813 }
01814
01815 QRect AlbumIconView::itemNameRect() const
01816 {
01817 return d->itemNameRect;
01818 }
01819
01820 QRect AlbumIconView::itemCommentsRect() const
01821 {
01822 return d->itemCommentsRect;
01823 }
01824
01825 QRect AlbumIconView::itemResolutionRect() const
01826 {
01827 return d->itemResolutionRect;
01828 }
01829
01830 QRect AlbumIconView::itemTagRect() const
01831 {
01832 return d->itemTagRect;
01833 }
01834
01835 QRect AlbumIconView::itemSizeRect() const
01836 {
01837 return d->itemSizeRect;
01838 }
01839
01840 QRect AlbumIconView::bannerRect() const
01841 {
01842 return d->bannerRect;
01843 }
01844
01845 QPixmap AlbumIconView::itemBaseRegPixmap() const
01846 {
01847 return d->itemRegPixmap;
01848 }
01849
01850 QPixmap AlbumIconView::itemBaseSelPixmap() const
01851 {
01852 return d->itemSelPixmap;
01853 }
01854
01855 QPixmap AlbumIconView::bannerPixmap() const
01856 {
01857 return d->bannerPixmap;
01858 }
01859
01860 QPixmap AlbumIconView::ratingPixmap(int rating, bool selected) const
01861 {
01862 if (rating < 1 || rating > 5)
01863 {
01864 QPixmap pix;
01865 if (selected)
01866 pix = d->itemSelPixmap.copy(d->itemRatingRect);
01867 else
01868 pix = d->itemRegPixmap.copy(d->itemRatingRect);
01869
01870 return pix;
01871 }
01872
01873 --rating;
01874 if (selected)
01875 return d->ratingPixmaps[5 + rating];
01876 else
01877 return d->ratingPixmaps[rating];
01878 }
01879
01880 QFont AlbumIconView::itemFontReg() const
01881 {
01882 return d->fnReg;
01883 }
01884
01885 QFont AlbumIconView::itemFontCom() const
01886 {
01887 return d->fnCom;
01888 }
01889
01890 QFont AlbumIconView::itemFontXtra() const
01891 {
01892 return d->fnXtra;
01893 }
01894
01895 void AlbumIconView::updateBannerRectPixmap()
01896 {
01897 d->bannerRect = QRect(0, 0, 0, 0);
01898
01899
01900
01901 QFont fn(font());
01902 int fnSize = fn.pointSize();
01903 bool usePointSize;
01904 if (fnSize > 0)
01905 {
01906 fn.setPointSize(fnSize+2);
01907 usePointSize = true;
01908 }
01909 else
01910 {
01911 fnSize = fn.pixelSize();
01912 fn.setPixelSize(fnSize+2);
01913 usePointSize = false;
01914 }
01915
01916 fn.setBold(true);
01917 QFontMetrics fm(fn);
01918 QRect tr = fm.boundingRect(0, 0, frameRect().width(),
01919 0xFFFFFFFF, Qt::AlignLeft | Qt::AlignVCenter,
01920 "XXX");
01921 d->bannerRect.setHeight(tr.height());
01922
01923 if (usePointSize)
01924 fn.setPointSize(font().pointSize());
01925 else
01926 fn.setPixelSize(font().pixelSize());
01927
01928 fn.setBold(false);
01929 fm = QFontMetrics(fn);
01930
01931 tr = fm.boundingRect(0, 0, frameRect().width(),
01932 0xFFFFFFFF, Qt::AlignLeft | Qt::AlignVCenter,
01933 "XXX");
01934
01935 d->bannerRect.setHeight(d->bannerRect.height() + tr.height() + 10);
01936 d->bannerRect.setWidth(frameRect().width());
01937
01938 d->bannerPixmap = ThemeEngine::instance()->bannerPixmap(d->bannerRect.width(),
01939 d->bannerRect.height());
01940 }
01941
01942 void AlbumIconView::updateRectsAndPixmaps()
01943 {
01944 updateBannerRectPixmap();
01945
01946 d->itemRect = QRect(0, 0, 0, 0);
01947 d->itemRatingRect = QRect(0, 0, 0, 0);
01948 d->itemDateRect = QRect(0, 0, 0, 0);
01949 d->itemModDateRect = QRect(0, 0, 0, 0);
01950 d->itemPixmapRect = QRect(0, 0, 0, 0);
01951 d->itemNameRect = QRect(0, 0, 0, 0);
01952 d->itemCommentsRect = QRect(0, 0, 0, 0);
01953 d->itemResolutionRect = QRect(0, 0, 0, 0);
01954 d->itemSizeRect = QRect(0, 0, 0, 0);
01955 d->itemTagRect = QRect(0, 0, 0, 0);
01956
01957 d->fnReg = font();
01958 d->fnCom = font();
01959 d->fnXtra = font();
01960 d->fnCom.setItalic(true);
01961
01962 int fnSz = d->fnReg.pointSize();
01963 if (fnSz > 0)
01964 {
01965 d->fnCom.setPointSize(fnSz-1);
01966 d->fnXtra.setPointSize(fnSz-2);
01967 }
01968 else
01969 {
01970 fnSz = d->fnReg.pixelSize();
01971 d->fnCom.setPixelSize(fnSz-1);
01972 d->fnXtra.setPixelSize(fnSz-2);
01973 }
01974
01975 const int radius = 3;
01976 const int margin = 5;
01977 int w = d->thumbSize.size() + 2*radius;
01978
01979 QFontMetrics fm(d->fnReg);
01980 QRect oneRowRegRect = fm.boundingRect(0, 0, w, 0xFFFFFFFF,
01981 Qt::AlignTop | Qt::AlignHCenter,
01982 "XXXXXXXXX");
01983 fm = QFontMetrics(d->fnCom);
01984 QRect oneRowComRect = fm.boundingRect(0, 0, w, 0xFFFFFFFF,
01985 Qt::AlignTop | Qt::AlignHCenter,
01986 "XXXXXXXXX");
01987 fm = QFontMetrics(d->fnXtra);
01988 QRect oneRowXtraRect = fm.boundingRect(0, 0, w, 0xFFFFFFFF,
01989 Qt::AlignTop | Qt::AlignHCenter,
01990 "XXXXXXXXX");
01991
01992 QSize starPolygonSize(15, 15);
01993
01994 int y = margin;
01995
01996 d->itemPixmapRect = QRect(margin, y, w, d->thumbSize.size() + 2*radius);
01997 y = d->itemPixmapRect.bottom();
01998
01999 if (d->albumSettings->getIconShowRating())
02000 {
02001 d->itemRatingRect = QRect(margin, y, w, starPolygonSize.height());
02002 y = d->itemRatingRect.bottom();
02003 }
02004
02005 if (d->albumSettings->getIconShowName())
02006 {
02007 d->itemNameRect = QRect(margin, y, w-margin, oneRowRegRect.height());
02008 y = d->itemNameRect.bottom();
02009 }
02010
02011 if (d->albumSettings->getIconShowComments())
02012 {
02013 d->itemCommentsRect = QRect(margin, y, w, oneRowComRect.height());
02014 y = d->itemCommentsRect.bottom();
02015 }
02016
02017 if (d->albumSettings->getIconShowDate())
02018 {
02019 d->itemDateRect = QRect(margin, y, w, oneRowXtraRect.height());
02020 y = d->itemDateRect.bottom();
02021 }
02022
02023 if (d->albumSettings->getIconShowModDate())
02024 {
02025 d->itemModDateRect = QRect(margin, y, w, oneRowXtraRect.height());
02026 y = d->itemModDateRect.bottom();
02027 }
02028
02029 if (d->albumSettings->getIconShowResolution())
02030 {
02031 d->itemResolutionRect = QRect(margin, y, w, oneRowXtraRect.height());
02032 y = d->itemResolutionRect.bottom() ;
02033 }
02034
02035 if (d->albumSettings->getIconShowSize())
02036 {
02037 d->itemSizeRect = QRect(margin, y, w, oneRowXtraRect.height());
02038 y = d->itemSizeRect.bottom();
02039 }
02040
02041 if (d->albumSettings->getIconShowTags())
02042 {
02043 d->itemTagRect = QRect(margin, y, w, oneRowComRect.height());
02044 y = d->itemTagRect.bottom();
02045 }
02046
02047 d->itemRect = QRect(0, 0, w + 2*margin, y+margin+radius);
02048
02049 d->itemRegPixmap = ThemeEngine::instance()->thumbRegPixmap(d->itemRect.width(),
02050 d->itemRect.height());
02051
02052 d->itemSelPixmap = ThemeEngine::instance()->thumbSelPixmap(d->itemRect.width(),
02053 d->itemRect.height());
02054
02055
02056
02057
02058
02059
02060
02061 if (d->albumSettings->getIconShowRating())
02062 {
02063 for (int sel=0; sel<2; ++sel)
02064 {
02065 QPixmap basePix;
02066
02067
02068 if (sel)
02069 basePix = d->itemSelPixmap.copy(d->itemRatingRect);
02070 else
02071 basePix = d->itemRegPixmap.copy(d->itemRatingRect);
02072
02073 for (int rating=1; rating<=5; ++rating)
02074 {
02075
02076 int index = (sel * 5 + rating) - 1;
02077
02078
02079 d->ratingPixmaps[index] = basePix;
02080
02081 QPainter painter(&d->ratingPixmaps[index]);
02082
02083
02084 painter.setRenderHint(QPainter::Antialiasing, true);
02085 painter.setBrush(ThemeEngine::instance()->textSpecialRegColor());
02086 QPen pen(ThemeEngine::instance()->textRegColor());
02087
02088 pen.setJoinStyle(Qt::MiterJoin);
02089 painter.setPen(pen);
02090
02091
02092 painter.translate( lround((d->itemRatingRect.width() - margin - rating*(starPolygonSize.width()+1))/2.0) + 2, 1 );
02093 for (int s=0; s<rating; ++s)
02094 {
02095 painter.drawPolygon(d->starPolygon, Qt::WindingFill);
02096 painter.translate(starPolygonSize.width() + 1, 0);
02097 }
02098 }
02099 }
02100 }
02101
02102 clearThumbnailBorderCache();
02103 }
02104
02105 void AlbumIconView::slotThemeChanged()
02106 {
02107 updateRectsAndPixmaps();
02108 viewport()->update();
02109 }
02110
02111 AlbumIconItem* AlbumIconView::findItem(const QPoint& pos)
02112 {
02113 return dynamic_cast<AlbumIconItem*>(IconView::findItem(pos));
02114 }
02115
02116 AlbumIconItem* AlbumIconView::findItem(const QString& url) const
02117 {
02118 return d->itemDict.value(url);
02119 }
02120
02121 AlbumIconItem* AlbumIconView::nextItemToThumbnail() const
02122 {
02123 QRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
02124 IconItem *fItem = findFirstVisibleItem(r);
02125 IconItem *lItem = findLastVisibleItem(r);
02126 if (!fItem || !lItem)
02127 return 0;
02128
02129 AlbumIconItem* firstItem = static_cast<AlbumIconItem*>(fItem);
02130 AlbumIconItem* lastItem = static_cast<AlbumIconItem*>(lItem);
02131 AlbumIconItem* item = firstItem;
02132 while (item)
02133 {
02134 if (item->isDirty())
02135 return item;
02136 if (item == lastItem)
02137 break;
02138 item = (AlbumIconItem*)item->nextItem();
02139 }
02140
02141 return 0;
02142 }
02143
02144 void AlbumIconView::slotAlbumModified()
02145 {
02146 d->imageLister->stop();
02147 clear();
02148
02149 d->imageLister->openAlbum(d->currentAlbum);
02150
02151 updateRectsAndPixmaps();
02152 }
02153
02154 void AlbumIconView::slotGotoTag(int tagID)
02155 {
02156
02157
02158
02159 emit signalGotoTagAndItem(tagID);
02160 }
02161
02162 void AlbumIconView::slotAssignTag(int tagID)
02163 {
02164 slotChangeTagOnImageInfos(selectedImageInfosCurrentFirst(), QList<int>() << tagID, true, true);
02165 }
02166
02167 void AlbumIconView::slotRemoveTag(int tagID)
02168 {
02169 slotChangeTagOnImageInfos(selectedImageInfosCurrentFirst(), QList<int>() << tagID, false, true);
02170 }
02171
02172 void AlbumIconView::slotAssignRating(int rating)
02173 {
02174 emit signalProgressBarMode(StatusProgressBar::ProgressBarMode,
02175 i18n("Assigning image ratings. Please wait..."));
02176
02177 int i = 0;
02178 float cnt = (float)countSelected();
02179 rating = qMin(RatingMax, qMax(RatingMin, rating));
02180 MetadataHub hub;
02181
02182 QList<ImageInfo> infos;
02183 for (IconItem *it = firstItem() ; it ; it = it->nextItem())
02184 {
02185 if (it->isSelected())
02186 {
02187 AlbumIconItem *albumItem = dynamic_cast<AlbumIconItem *>(it);
02188 if (albumItem)
02189 infos << albumItem->imageInfo();
02190 }
02191 }
02192
02193 d->imageLister->blockSignals(true);
02194 ScanController::instance()->suspendCollectionScan();
02195 DatabaseTransaction transaction;
02196 foreach (const ImageInfo& info, infos)
02197 {
02198 hub.load(info);
02199
02200 hub.setRating(rating);
02201
02202 QString filePath = info.filePath();
02203 hub.write(info, MetadataHub::PartialWrite);
02204 hub.write(info.filePath(), MetadataHub::FullWriteIfChanged);
02205 bool fileChanged = hub.write(filePath, MetadataHub::FullWriteIfChanged);
02206
02207 if (fileChanged)
02208 ScanController::instance()->scanFileDirectly(filePath);
02209
02210 emit signalProgressValue((int)((i++/cnt)*100.0));
02211 kapp->processEvents();
02212 }
02213 ScanController::instance()->resumeCollectionScan();
02214 d->imageLister->blockSignals(false);
02215
02216 emit signalProgressBarMode(StatusProgressBar::TextMode, QString());
02217 updateContents();
02218 }
02219
02220 void AlbumIconView::slotAssignRatingNoStar()
02221 {
02222 slotAssignRating(0);
02223 }
02224
02225 void AlbumIconView::slotAssignRatingOneStar()
02226 {
02227 slotAssignRating(1);
02228 }
02229
02230 void AlbumIconView::slotAssignRatingTwoStar()
02231 {
02232 slotAssignRating(2);
02233 }
02234
02235 void AlbumIconView::slotAssignRatingThreeStar()
02236 {
02237 slotAssignRating(3);
02238 }
02239
02240 void AlbumIconView::slotAssignRatingFourStar()
02241 {
02242 slotAssignRating(4);
02243 }
02244
02245 void AlbumIconView::slotAssignRatingFiveStar()
02246 {
02247 slotAssignRating(5);
02248 }
02249
02250 void AlbumIconView::slotDIOResult(KJob* kjob)
02251 {
02252 KIO::Job *job = static_cast<KIO::Job*>(kjob);
02253 if (job->error())
02254 {
02255 job->ui()->setWindow(this);
02256 job->ui()->showErrorMessage();
02257 }
02258 }
02259
02260 void AlbumIconView::slotImageAttributesChanged(qlonglong imageId)
02261 {
02262 AlbumIconItem *firstItem = static_cast<AlbumIconItem *>(findFirstVisibleItem());
02263 AlbumIconItem *lastItem = static_cast<AlbumIconItem *>(findLastVisibleItem());
02264 for (AlbumIconItem *item = firstItem; item;
02265 item = static_cast<AlbumIconItem *>(item->nextItem()))
02266 {
02267 if (item->imageInfo().id() == imageId)
02268 {
02269 updateContents();
02270 return;
02271 }
02272 if (item == lastItem)
02273 break;
02274 }
02275 }
02276
02277 void AlbumIconView::slotAlbumImagesChanged(int )
02278 {
02279 updateContents();
02280 }
02281
02282 void AlbumIconView::slotEditRatingFromItem(int rating)
02283 {
02284 rating = qMin(RatingMax, qMax(RatingMin, rating));
02285
02286 d->imageLister->blockSignals(true);
02287 ScanController::instance()->suspendCollectionScan();
02288 DatabaseTransaction transaction;
02289 AlbumIconItem *albumItem = dynamic_cast<AlbumIconItem*>(ratingItem());
02290 if (albumItem)
02291 {
02292 ImageInfo info = albumItem->imageInfo();
02293
02294 MetadataHub hub;
02295 hub.load(info);
02296 hub.setRating(rating);
02297
02298 QString filePath = info.filePath();
02299 hub.write(info, MetadataHub::PartialWrite);
02300 hub.write(info.filePath(), MetadataHub::FullWriteIfChanged);
02301 bool fileChanged = hub.write(filePath, MetadataHub::FullWriteIfChanged);
02302
02303 if (fileChanged)
02304 ScanController::instance()->scanFileDirectly(filePath);
02305 }
02306
02307 ScanController::instance()->resumeCollectionScan();
02308 d->imageLister->blockSignals(false);
02309 updateContents();
02310 }
02311
02312 void AlbumIconView::slotMoveSelectionToAlbum()
02313 {
02314 KUrl::List kioURLs;
02315 QList<qlonglong> selectedImageIDs;
02316
02317 for (IconItem *it = firstItem(); it; it=it->nextItem())
02318 {
02319 if (it->isSelected())
02320 {
02321 AlbumIconItem *selItem = static_cast<AlbumIconItem *>(it);
02322 selectedImageIDs.append(selItem->imageInfo().id());
02323 kioURLs.append(selItem->imageInfo().fileUrl());
02324 }
02325 }
02326
02327 if (kioURLs.isEmpty() || selectedImageIDs.isEmpty())
02328 return;
02329
02330 Album *album = AlbumManager::instance()->currentAlbum();
02331 if (album && album->type() != Album::PHYSICAL)
02332 album = 0;
02333
02334 QString header(i18n("<p>Please select the destination album from the digiKam library to "
02335 "move the selected images into.</p>"));
02336
02337 album = AlbumSelectDialog::selectAlbum(this, (PAlbum*)album, header);
02338 if (!album) return;
02339
02340 KIO::Job* job = DIO::move(kioURLs, selectedImageIDs, (PAlbum*)album);
02341 connect(job, SIGNAL(result(KJob*)),
02342 this, SLOT(slotDIOResult(KJob*)));
02343 }
02344
02345 }