diff --git a/digikam/items/digikamimageview.cpp b/digikam/items/digikamimageview.cpp index c26a3ba11a..2241a816b6 100644 --- a/digikam/items/digikamimageview.cpp +++ b/digikam/items/digikamimageview.cpp @@ -1,697 +1,697 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-04-24 * Description : Qt item view for images * * Copyright (C) 2009-2011 by Marcel Wiesweg * Copyright (C) 2009-2014 by Gilles Caulier * Copyright (C) 2011 by Andi Clemens * Copyright (C) 2013 by Michael G. Hansen * Copyright (C) 2014 by Mohamed Anwer * * This program is free software you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "digikamimageview_p.h" #include "digikamimageview.moc" // Qt includes #include #include #include // KDE includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Local includes #include "albummanager.h" #include "albumdb.h" #include "advancedrenamedialog.h" #include "advancedrenameprocessdialog.h" #include "albumsettings.h" #include "assignnameoverlay.h" #include "contextmenuhelper.h" #include "databaseaccess.h" #include "ddragobjects.h" #include "digikamapp.h" #include "digikamimagedelegate.h" #include "digikamimagefacedelegate.h" #include "dio.h" #include "facerejectionoverlay.h" #include "groupindicatoroverlay.h" #include "imagealbumfiltermodel.h" #include "imagealbummodel.h" #include "imagedragdrop.h" #include "imageratingoverlay.h" #include "imagecoordinatesoverlay.h" #include "tagslineeditoverlay.h" #include "imageviewutilities.h" #include "imagewindow.h" #include "fileactionmngr.h" #include "fileactionprogress.h" #include "thumbnailloadthread.h" #include "tagregion.h" #include "addtagslineedit.h" namespace Digikam { DigikamImageView::DigikamImageView(QWidget* const parent) : ImageCategorizedView(parent), d(new Private(this)) { installDefaultModels(); d->editPipeline.plugDatabaseEditor(); d->editPipeline.plugTrainer(); d->editPipeline.construct(); connect(&d->editPipeline, SIGNAL(scheduled()), this, SLOT(slotInitProgressIndicator())); d->normalDelegate = new DigikamImageDelegate(this); d->faceDelegate = new DigikamImageFaceDelegate(this); setItemDelegate(d->normalDelegate); setSpacing(10); AlbumSettings* const settings = AlbumSettings::instance(); imageFilterModel()->setCategorizationMode(ImageSortSettings::CategoryByAlbum); imageAlbumModel()->setThumbnailLoadThread(ThumbnailLoadThread::defaultIconViewThread()); setThumbnailSize((ThumbnailSize::Size)settings->getDefaultIconSize()); imageAlbumModel()->setPreloadThumbnails(true); imageModel()->setDragDropHandler(new ImageDragDropHandler(imageModel())); setDragEnabled(true); setAcceptDrops(true); setDropIndicatorShown(false); setToolTipEnabled(settings->showToolTipsIsValid()); imageFilterModel()->setSortRole((ImageSortSettings::SortRole)settings->getImageSortOrder()); imageFilterModel()->setSortOrder((ImageSortSettings::SortOrder)settings->getImageSorting()); imageFilterModel()->setCategorizationMode((ImageSortSettings::CategorizationMode)settings->getImageGroupMode()); imageFilterModel()->setCategorizationSortOrder((ImageSortSettings::SortOrder) settings->getImageGroupSortOrder()); // selection overlay addSelectionOverlay(d->normalDelegate); addSelectionOverlay(d->faceDelegate); // rotation overlays d->rotateLeftOverlay = ImageRotateOverlay::left(this); d->rotateRightOverlay = ImageRotateOverlay::right(this); d->updateOverlays(); // rating overlay ImageRatingOverlay* const ratingOverlay = new ImageRatingOverlay(this); addOverlay(ratingOverlay); // face overlays // NOTE: order to plug this overlay is important, else rejection can be suitable (see B.K.O #324759). addAssignNameOverlay(d->faceDelegate); addRejectionOverlay(d->faceDelegate); GroupIndicatorOverlay* const groupOverlay = new GroupIndicatorOverlay(this); addOverlay(groupOverlay); addOverlay(new ImageCoordinatesOverlay(this)); connect(ratingOverlay, SIGNAL(ratingEdited(QList,int)), this, SLOT(assignRating(QList,int))); connect(groupOverlay, SIGNAL(toggleGroupOpen(QModelIndex)), this, SLOT(groupIndicatorClicked(QModelIndex))); connect(groupOverlay, SIGNAL(showButtonContextMenu(QModelIndex,QContextMenuEvent*)), this, SLOT(showGroupContextMenu(QModelIndex,QContextMenuEvent*))); d->utilities = new ImageViewUtilities(this); connect(d->utilities, SIGNAL(editorCurrentUrlChanged(KUrl)), this, SLOT(setCurrentUrl(KUrl))); connect(imageModel()->dragDropHandler(), SIGNAL(assignTags(QList,QList)), FileActionMngr::instance(), SLOT(assignTags(QList,QList))); connect(imageModel()->dragDropHandler(), SIGNAL(addToGroup(ImageInfo,QList)), FileActionMngr::instance(), SLOT(addToGroup(ImageInfo,QList))); connect(settings, SIGNAL(setupChanged()), this, SLOT(slotSetupChanged())); slotSetupChanged(); } DigikamImageView::~DigikamImageView() { delete d; } ImageViewUtilities* DigikamImageView::utilities() const { return d->utilities; } void DigikamImageView::setThumbnailSize(const ThumbnailSize& size) { imageThumbnailModel()->setPreloadThumbnailSize(size); ImageCategorizedView::setThumbnailSize(size); } int DigikamImageView::fitToWidthIcons() { return delegate()->calculatethumbSizeToFit(viewport()->size().width()); } void DigikamImageView::slotSetupChanged() { setToolTipEnabled(AlbumSettings::instance()->showToolTipsIsValid()); setFont(AlbumSettings::instance()->getIconViewFont()); d->updateOverlays(); ImageCategorizedView::slotSetupChanged(); } void DigikamImageView::setFaceMode(bool on) { d->faceMode = on; if (on) { // See ImageLister, which creates a search the implements listing tag in the ioslave imageAlbumModel()->setSpecialTagListing("faces"); setItemDelegate(d->faceDelegate); // grouping is not very much compatible with faces imageFilterModel()->setAllGroupsOpen(true); } else { imageAlbumModel()->setSpecialTagListing(QString()); setItemDelegate(d->normalDelegate); imageFilterModel()->setAllGroupsOpen(false); } } void DigikamImageView::addRejectionOverlay(ImageDelegate* delegate) { FaceRejectionOverlay* const rejectionOverlay = new FaceRejectionOverlay(this); connect(rejectionOverlay, SIGNAL(rejectFaces(QList)), this, SLOT(removeFaces(QList))); addOverlay(rejectionOverlay, delegate); } /* void DigikamImageView::addTagEditOverlay(ImageDelegate* delegate) { TagsLineEditOverlay* tagOverlay = new TagsLineEditOverlay(this); connect(tagOverlay, SIGNAL(tagEdited(QModelIndex,QString)), this, SLOT(assignTag(QModelIndex,QString))); addOverlay(tagOverlay, delegate); } */ void DigikamImageView::addAssignNameOverlay(ImageDelegate* delegate) { AssignNameOverlay* const nameOverlay = new AssignNameOverlay(this); addOverlay(nameOverlay, delegate); connect(nameOverlay, SIGNAL(confirmFaces(QList,int)), this, SLOT(confirmFaces(QList,int))); connect(nameOverlay, SIGNAL(removeFaces(QList)), this, SLOT(removeFaces(QList))); } void DigikamImageView::confirmFaces(const QList& indexes, int tagId) { QList infos; QList faces; QList sourceIndexes; // fast-remove in the "unknown person" view bool needFastRemove = false; if(imageAlbumModel()->currentAlbums().size() == 1) { needFastRemove = d->faceMode && (tagId != imageAlbumModel()->currentAlbums().first()->id()); } foreach(const QModelIndex& index, indexes) { infos << ImageModel::retrieveImageInfo(index); faces << d->faceDelegate->face(index); if (needFastRemove) { sourceIndexes << imageSortFilterModel()->mapToSourceImageModel(index); } } imageAlbumModel()->removeIndexes(sourceIndexes); for (int i=0; ieditPipeline.confirm(infos[i], faces[i], tagId); } } void DigikamImageView::removeFaces(const QList& indexes) { QList infos; QList faces; QList sourceIndexes; foreach(const QModelIndex& index, indexes) { infos << ImageModel::retrieveImageInfo(index); faces << d->faceDelegate->face(index); sourceIndexes << imageSortFilterModel()->mapToSourceImageModel(index); } imageAlbumModel()->removeIndexes(sourceIndexes); for (int i=0; ieditPipeline.remove(infos[i], faces[i]); } } void DigikamImageView::activated(const ImageInfo& info) { if (info.isNull()) { return; } if (AlbumSettings::instance()->getItemLeftClickAction() == AlbumSettings::ShowPreview) { emit previewRequested(info); } else { - openInEditor(info); + openFile(info); } } void DigikamImageView::showContextMenuOnInfo(QContextMenuEvent* event, const ImageInfo& info) { QList selectedInfos = selectedImageInfosCurrentFirst(); QList selectedImageIDs; foreach(const ImageInfo& info, selectedInfos) { selectedImageIDs << info.id(); } // Temporary actions -------------------------------------- QAction* const viewAction = new QAction(SmallIcon("viewimage"), i18nc("View the selected image", "Preview"), this); viewAction->setEnabled(selectedImageIDs.count() == 1); // -------------------------------------------------------- KMenu popmenu(this); ContextMenuHelper cmhelper(&popmenu); cmhelper.setImageFilterModel(imageFilterModel()); cmhelper.addAction("full_screen"); cmhelper.addAction("options_show_menubar"); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addAction("move_selection_to_album"); cmhelper.addAction(viewAction); cmhelper.addAction("image_edit"); cmhelper.addServicesMenu(selectedUrls()); cmhelper.addGotoMenu(selectedImageIDs); cmhelper.addAction("image_rotate"); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addAction("image_find_similar"); cmhelper.addStandardActionLightTable(); cmhelper.addQueueManagerMenu(); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addAction("image_rename"); cmhelper.addAction("cut_album_selection"); cmhelper.addAction("copy_album_selection"); cmhelper.addAction("paste_album_selection"); cmhelper.addStandardActionItemDelete(this, SLOT(deleteSelected()), selectedImageIDs.count()); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addStandardActionThumbnail(selectedImageIDs, currentAlbum()); // -------------------------------------------------------- cmhelper.addAssignTagsMenu(selectedImageIDs); cmhelper.addRemoveTagsMenu(selectedImageIDs); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addLabelsAction(); if (!d->faceMode) { cmhelper.addGroupMenu(selectedImageIDs); } // special action handling -------------------------------- connect(&cmhelper, SIGNAL(signalAssignTag(int)), this, SLOT(assignTagToSelected(int))); connect(&cmhelper, SIGNAL(signalPopupTagsView()), this, SIGNAL(signalPopupTagsView())); connect(&cmhelper, SIGNAL(signalRemoveTag(int)), this, SLOT(removeTagFromSelected(int))); connect(&cmhelper, SIGNAL(signalGotoTag(int)), this, SIGNAL(gotoTagAndImageRequested(int))); connect(&cmhelper, SIGNAL(signalGotoAlbum(ImageInfo)), this, SIGNAL(gotoAlbumAndImageRequested(ImageInfo))); connect(&cmhelper, SIGNAL(signalGotoDate(ImageInfo)), this, SIGNAL(gotoDateAndImageRequested(ImageInfo))); connect(&cmhelper, SIGNAL(signalAssignPickLabel(int)), this, SLOT(assignPickLabelToSelected(int))); connect(&cmhelper, SIGNAL(signalAssignColorLabel(int)), this, SLOT(assignColorLabelToSelected(int))); connect(&cmhelper, SIGNAL(signalAssignRating(int)), this, SLOT(assignRatingToSelected(int))); connect(&cmhelper, SIGNAL(signalSetThumbnail(ImageInfo)), this, SLOT(setAsAlbumThumbnail(ImageInfo))); connect(&cmhelper, SIGNAL(signalAddToExistingQueue(int)), this, SLOT(insertSelectedToExistingQueue(int))); connect(&cmhelper, SIGNAL(signalCreateGroup()), this, SLOT(createGroupFromSelection())); connect(&cmhelper, SIGNAL(signalCreateGroupByTime()), this, SLOT(createGroupByTimeFromSelection())); connect(&cmhelper, SIGNAL(signalUngroup()), this, SLOT(ungroupSelected())); connect(&cmhelper, SIGNAL(signalRemoveFromGroup()), this, SLOT(removeSelectedFromGroup())); // -------------------------------------------------------- QAction* const choice = cmhelper.exec(event->globalPos()); if (choice && (choice == viewAction)) { emit previewRequested(info); } } void DigikamImageView::showGroupContextMenu(const QModelIndex& index, QContextMenuEvent* event) { Q_UNUSED(index); QList selectedInfos = selectedImageInfosCurrentFirst(); QList selectedImageIDs; foreach(const ImageInfo& info, selectedInfos) { selectedImageIDs << info.id(); } KMenu popmenu(this); ContextMenuHelper cmhelper(&popmenu); cmhelper.setImageFilterModel(imageFilterModel()); cmhelper.addGroupActions(selectedImageIDs); // special action handling -------------------------------- connect(&cmhelper, SIGNAL(signalCreateGroup()), this, SLOT(createGroupFromSelection())); connect(&cmhelper, SIGNAL(signalCreateGroupByTime()), this, SLOT(createGroupByTimeFromSelection())); connect(&cmhelper, SIGNAL(signalUngroup()), this, SLOT(ungroupSelected())); connect(&cmhelper, SIGNAL(signalRemoveFromGroup()), this, SLOT(removeSelectedFromGroup())); cmhelper.exec(event->globalPos()); } void DigikamImageView::showContextMenu(QContextMenuEvent* event) { Album* const album = currentAlbum(); if (!album || album->isRoot() || (album->type() != Album::PHYSICAL && album->type() != Album::TAG) ) { return; } KMenu popmenu(this); ContextMenuHelper cmhelper(&popmenu); cmhelper.setImageFilterModel(imageFilterModel()); cmhelper.addAction("full_screen"); cmhelper.addAction("options_show_menubar"); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addStandardActionPaste(this, SLOT(paste())); // -------------------------------------------------------- cmhelper.exec(event->globalPos()); } -void DigikamImageView::openInEditor(const ImageInfo& info) +void DigikamImageView::openFile(const ImageInfo& info) { - d->utilities->openInEditor(info, imageInfos(), currentAlbum()); + d->utilities->openFile(info, imageInfos(), currentAlbum()); } void DigikamImageView::insertSelectedToCurrentQueue() { ImageInfoList imageInfoList = selectedImageInfos(); if (!imageInfoList.isEmpty()) { d->utilities->insertToQueueManager(imageInfoList, imageInfoList.first(), false); } } void DigikamImageView::insertSelectedToNewQueue() { ImageInfoList imageInfoList = selectedImageInfos(); if (!imageInfoList.isEmpty()) { d->utilities->insertToQueueManager(imageInfoList, imageInfoList.first(), true); } } void DigikamImageView::insertSelectedToExistingQueue(int queueid) { ImageInfoList imageInfoList = selectedImageInfos(); if (!imageInfoList.isEmpty()) { d->utilities->insertSilentToQueueManager(imageInfoList, imageInfoList.first(), queueid); } } void DigikamImageView::deleteSelected(const ImageViewUtilities::DeleteMode deleteMode) { ImageInfoList imageInfoList = selectedImageInfos(); if (d->utilities->deleteImages(imageInfoList, deleteMode)) { awayFromSelection(); } } void DigikamImageView::deleteSelectedDirectly(const ImageViewUtilities::DeleteMode deleteMode) { ImageInfoList imageInfoList = selectedImageInfos(); d->utilities->deleteImagesDirectly(imageInfoList, deleteMode); awayFromSelection(); } void DigikamImageView::assignTagToSelected(int tagID) { FileActionMngr::instance()->assignTags(selectedImageInfos(), QList() << tagID); } void DigikamImageView::removeTagFromSelected(int tagID) { FileActionMngr::instance()->removeTags(selectedImageInfos(), QList() << tagID); } void DigikamImageView::assignPickLabelToSelected(int pickId) { FileActionMngr::instance()->assignPickLabel(selectedImageInfos(), pickId); } void DigikamImageView::assignPickLabel(const QModelIndex& index, int pickId) { FileActionMngr::instance()->assignPickLabel(QList() << imageFilterModel()->imageInfo(index), pickId); } void DigikamImageView::assignColorLabelToSelected(int colorId) { FileActionMngr::instance()->assignColorLabel(selectedImageInfos(), colorId); } void DigikamImageView::assignColorLabel(const QModelIndex& index, int colorId) { FileActionMngr::instance()->assignColorLabel(QList() << imageFilterModel()->imageInfo(index), colorId); } void DigikamImageView::assignRatingToSelected(int rating) { FileActionMngr::instance()->assignRating(selectedImageInfos(), rating); } void DigikamImageView::assignRating(const QList& indexes, int rating) { FileActionMngr::instance()->assignRating(imageFilterModel()->imageInfos(indexes), rating); } void DigikamImageView::setAsAlbumThumbnail(const ImageInfo& setAsThumbnail) { d->utilities->setAsAlbumThumbnail(currentAlbum(), setAsThumbnail); } void DigikamImageView::createNewAlbumForSelected() { d->utilities->createNewAlbumForInfos(selectedImageInfos(), currentAlbum()); } void DigikamImageView::groupIndicatorClicked(const QModelIndex& index) { ImageInfo info = imageFilterModel()->imageInfo(index); if (info.isNull()) { return; } setCurrentIndex(index); imageFilterModel()->toggleGroupOpen(info.id()); imageAlbumModel()->ensureHasGroupedImages(info); } void DigikamImageView::createGroupFromSelection() { QList selectedInfos = selectedImageInfosCurrentFirst(); ImageInfo groupLeader = selectedInfos.takeFirst(); FileActionMngr::instance()->addToGroup(groupLeader, selectedInfos); } void DigikamImageView::createGroupByTimeFromSelection() { const QList selectedInfos = selectedImageInfos(); d->utilities->createGroupByTimeFromInfoList(selectedInfos); } void DigikamImageView::ungroupSelected() { FileActionMngr::instance()->ungroup(selectedImageInfos()); } void DigikamImageView::removeSelectedFromGroup() { FileActionMngr::instance()->removeFromGroup(selectedImageInfos()); } void DigikamImageView::rename() { KUrl::List urls = selectedUrls(); NewNamesList newNamesList; QPointer dlg = new AdvancedRenameDialog(this); dlg->slotAddImages(urls); if (dlg->exec() == KDialog::Accepted) { newNamesList = dlg->newNames(); } delete dlg; if (!newNamesList.isEmpty()) { QPointer dlg = new AdvancedRenameProcessDialog(newNamesList); dlg->exec(); delete dlg; } } void DigikamImageView::slotRotateLeft(const QList& indexes) { FileActionMngr::instance()->transform(QList() << imageFilterModel()->imageInfos(indexes), KExiv2Iface::RotationMatrix::Rotate270); } void DigikamImageView::slotRotateRight(const QList& indexes) { FileActionMngr::instance()->transform(QList() << imageFilterModel()->imageInfos(indexes), KExiv2Iface::RotationMatrix::Rotate90); } void DigikamImageView::slotInitProgressIndicator() { if (!ProgressManager::instance()->findItembyId("FaceActionProgress")) { FileActionProgress* const item = new FileActionProgress("FaceActionProgress"); connect(&d->editPipeline, SIGNAL(started(QString)), item, SLOT(slotProgressStatus(QString))); connect(&d->editPipeline, SIGNAL(progressValueChanged(float)), item, SLOT(slotProgressValue(float))); connect(&d->editPipeline, SIGNAL(finished()), item, SLOT(slotCompleted())); } } } // namespace Digikam diff --git a/digikam/items/digikamimageview.h b/digikam/items/digikamimageview.h index ce5c0b01f4..99f6a46db9 100644 --- a/digikam/items/digikamimageview.h +++ b/digikam/items/digikamimageview.h @@ -1,123 +1,123 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-04-24 * Description : Qt item view for images * * Copyright (C) 2009-2011 by Marcel Wiesweg * Copyright (C) 2009-2014 by Gilles Caulier * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef DIGIKAMIMAGEVIEW_H #define DIGIKAMIMAGEVIEW_H // Local includes #include "imagecategorizedview.h" #include "imageviewutilities.h" namespace Digikam { class ImageViewUtilities; class DigikamImageView : public ImageCategorizedView { Q_OBJECT public: explicit DigikamImageView(QWidget* const parent = 0); ~DigikamImageView(); ImageViewUtilities* utilities() const; int fitToWidthIcons(); virtual void setThumbnailSize(const ThumbnailSize& size); public Q_SLOTS: - void openInEditor(const ImageInfo& info); + void openFile(const ImageInfo& info); void insertSelectedToCurrentQueue(); void insertSelectedToNewQueue(); void insertSelectedToExistingQueue(int queueid); void deleteSelected(const ImageViewUtilities::DeleteMode deleteMode = ImageViewUtilities::DeleteUseTrash); void deleteSelectedDirectly(const ImageViewUtilities::DeleteMode deleteMode = ImageViewUtilities::DeleteUseTrash); void assignTagToSelected(int tagID); void removeTagFromSelected(int tagID); void assignPickLabelToSelected(int pickId); void assignColorLabelToSelected(int colorId); void assignRatingToSelected(int rating); void setAsAlbumThumbnail(const ImageInfo& setAsThumbnail); void createNewAlbumForSelected(); void rename(); void assignPickLabel(const QModelIndex& index, int pickId); void assignColorLabel(const QModelIndex& index, int colorId); void assignRating(const QList& index, int rating); void createGroupFromSelection(); void createGroupByTimeFromSelection(); void ungroupSelected(); void removeSelectedFromGroup(); void setFaceMode(bool on); void confirmFaces(const QList& indexes, int tagId); void removeFaces(const QList& indexes); Q_SIGNALS: void previewRequested(const ImageInfo& info); void gotoAlbumAndImageRequested(const ImageInfo& info); void gotoTagAndImageRequested(int tagId); void gotoDateAndImageRequested(const ImageInfo& info); void signalPopupTagsView(); protected Q_SLOTS: void groupIndicatorClicked(const QModelIndex& index); void showGroupContextMenu(const QModelIndex& index, QContextMenuEvent* event); protected: void addRejectionOverlay(ImageDelegate* delegate = 0); void addAssignNameOverlay(ImageDelegate* delegate = 0); virtual void activated(const ImageInfo& info); virtual void showContextMenuOnInfo(QContextMenuEvent* event, const ImageInfo& info); virtual void showContextMenu(QContextMenuEvent* event); virtual void slotSetupChanged(); private Q_SLOTS: void slotRotateLeft(const QList&); void slotRotateRight(const QList&); void slotInitProgressIndicator(); private: class Private; Private* const d; }; } // namespace Digikam #endif /* DIGIKAMIMAGEVIEW_H */ diff --git a/digikam/items/imageviewutilities.cpp b/digikam/items/imageviewutilities.cpp index 9ad89d9d41..2ab471a861 100644 --- a/digikam/items/imageviewutilities.cpp +++ b/digikam/items/imageviewutilities.cpp @@ -1,361 +1,361 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-05-04 * Description : Various operations on images * * Copyright (C) 2002-2005 by Renchi Raju * Copyright (C) 2002-2014 by Gilles Caulier * Copyright (C) 2006-2010 by Marcel Wiesweg * Copyright (C) 2009-2010 by Andi Clemens * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "imageviewutilities.moc" // Qt includes #include // KDE includes #include #include #include #include #include #include #include #include #include // Local includes #include "album.h" #include "albummanager.h" #include "albumselectdialog.h" #include "albumsettings.h" #include "deletedialog.h" #include "dio.h" #include "imageinfo.h" #include "imagewindow.h" #include "lighttablewindow.h" #include "loadingcacheinterface.h" #include "queuemgrwindow.h" #include "thumbnailloadthread.h" #include "fileactionmngr.h" namespace Digikam { ImageViewUtilities::ImageViewUtilities(QWidget* const parentWidget) : QObject(parentWidget) { m_widget = parentWidget; } void ImageViewUtilities::setAsAlbumThumbnail(Album* album, const ImageInfo& imageInfo) { if (!album) { return; } if (album->type() == Album::PHYSICAL) { PAlbum* const palbum = static_cast(album); QString err; AlbumManager::instance()->updatePAlbumIcon(palbum, imageInfo.id(), err); } else if (album->type() == Album::TAG) { TAlbum* const talbum = static_cast(album); QString err; AlbumManager::instance()->updateTAlbumIcon(talbum, QString(), imageInfo.id(), err); } } void ImageViewUtilities::rename(const KUrl& imageUrl, const QString& newName) { if (imageUrl.isEmpty() || !imageUrl.isLocalFile() || newName.isEmpty()) { return; } ImageInfo info(imageUrl.toLocalFile()); DIO::rename(info, newName); } bool ImageViewUtilities::deleteImages(const QList& infos, const DeleteMode deleteMode) { if (infos.isEmpty()) { return false; } KUrl::List urlList; foreach(const ImageInfo& info, infos) { urlList << info.fileUrl(); } DeleteDialog dialog(m_widget); DeleteDialogMode::DeleteMode deleteDialogMode = DeleteDialogMode::NoChoiceTrash; if (deleteMode == ImageViewUtilities::DeletePermanently) { deleteDialogMode = DeleteDialogMode::NoChoiceDeletePermanently; } if (!dialog.confirmDeleteList(urlList, DeleteDialogMode::Files, deleteDialogMode)) { return false; } const bool useTrash = !dialog.shouldDelete(); DIO::del(infos, useTrash); return true; } void ImageViewUtilities::deleteImagesDirectly(const QList& infos, const DeleteMode deleteMode) { // This method deletes the selected items directly, without confirmation. // It is not used in the default setup. if (infos.isEmpty()) { return; } const bool useTrash = (deleteMode==ImageViewUtilities::DeleteUseTrash); DIO::del(infos, useTrash); } void ImageViewUtilities::notifyFileContentChanged(const KUrl::List& urls) { foreach(const KUrl& url, urls) { QString path = url.toLocalFile(); ThumbnailLoadThread::deleteThumbnail(path); // clean LoadingCache as well - be pragmatic, do it here. LoadingCacheInterface::fileChanged(path); } } void ImageViewUtilities::createNewAlbumForInfos(const QList& infos, Album* currentAlbum) { if (infos.isEmpty()) { return; } if (currentAlbum && currentAlbum->type() != Album::PHYSICAL) { currentAlbum = 0; } QString header(i18n("

Please select the destination album from the digiKam library to " "move the selected images into.

")); Album* const album = AlbumSelectDialog::selectAlbum(m_widget, static_cast(currentAlbum), header); if (!album) { return; } DIO::move(infos, (PAlbum*)album); } void ImageViewUtilities::insertToLightTableAuto(const QList& all, const QList& selected, const ImageInfo& current) { ImageInfoList list = selected; ImageInfo singleInfo = current; if (list.isEmpty() || (list.size() == 1 && LightTableWindow::lightTableWindow()->isEmpty())) { list = all; } if (singleInfo.isNull() && !list.isEmpty()) { singleInfo = list.first(); } insertToLightTable(list, current, list.size() <= 1); } void ImageViewUtilities::insertToLightTable(const QList& list, const ImageInfo& current, bool addTo) { LightTableWindow* const ltview = LightTableWindow::lightTableWindow(); // If addTo is false, the light table will be emptied before adding // the images. ltview->loadImageInfos(list, current, addTo); ltview->setLeftRightItems(list, addTo); if (ltview->isHidden()) { ltview->show(); } if (ltview->isMinimized()) { KWindowSystem::unminimizeWindow(ltview->winId()); } KWindowSystem::activateWindow(ltview->winId()); } void ImageViewUtilities::insertToQueueManager(const QList& list, const ImageInfo& current, bool newQueue) { Q_UNUSED(current); QueueMgrWindow* const bqmview = QueueMgrWindow::queueManagerWindow(); if (bqmview->isHidden()) { bqmview->show(); } if (bqmview->isMinimized()) { KWindowSystem::unminimizeWindow(bqmview->winId()); } KWindowSystem::activateWindow(bqmview->winId()); if (newQueue) { bqmview->loadImageInfosToNewQueue(list); } else { bqmview->loadImageInfosToCurrentQueue(list); } } void ImageViewUtilities::insertSilentToQueueManager(const QList& list, const ImageInfo& /*current*/, int queueid) { QueueMgrWindow* const bqmview = QueueMgrWindow::queueManagerWindow(); bqmview->loadImageInfos(list, queueid); } -void ImageViewUtilities::openInEditor(const ImageInfo& info, const QList& allInfosToOpen, Album* currentAlbum) +void ImageViewUtilities::openFile(const ImageInfo& info, const QList& allInfosToOpen, Album* currentAlbum) { if (info.isNull()) { return; } QFileInfo fi(info.filePath()); QString imagefilter = AlbumSettings::instance()->getImageFileFilter(); imagefilter += AlbumSettings::instance()->getRawFileFilter(); // If the current item is not an image file. if ( !imagefilter.contains(fi.suffix().toLower()) ) { const QString mimeType = KMimeType::findByUrl(info.fileUrl(), 0, true, true)->name(); KService::List offers = KMimeTypeTrader::self()->query(mimeType, "Application"); if (offers.isEmpty()) { return; } KService::Ptr ptr = offers.first(); // Run the dedicated app to show the item. KRun::run(*ptr, info.fileUrl(), m_widget); return; } // Run digiKam ImageEditor with all image from current Album. ImageWindow* const imview = ImageWindow::imageWindow(); imview->disconnect(this); connect(imview, SIGNAL(signalURLChanged(KUrl)), this, SIGNAL(editorCurrentUrlChanged(KUrl))); imview->loadImageInfos(allInfosToOpen, info, currentAlbum ? i18n("Album \"%1\"", currentAlbum->title()) : QString()); if (imview->isHidden()) { imview->show(); } if (imview->isMinimized()) { KWindowSystem::unminimizeWindow(imview->winId()); } KWindowSystem::activateWindow(imview->winId()); } namespace { bool lessThanByTimeForImageInfo(const ImageInfo& a, const ImageInfo& b) { return a.dateTime() < b.dateTime(); } } // namespace void ImageViewUtilities::createGroupByTimeFromInfoList(const ImageInfoList& imageInfoList) { QList groupingList = imageInfoList; // sort by time qStableSort(groupingList.begin(), groupingList.end(), lessThanByTimeForImageInfo); QList::iterator it, it2; for (it = groupingList.begin(); it != groupingList.end(); ) { const ImageInfo& leader = *it; QList group; QDateTime time = it->dateTime(); for (it2 = it + 1; it2 != groupingList.end(); ++it2) { if (abs(time.secsTo(it2->dateTime())) < 2) { group << *it2; } else { break; } } // increment to next item not put in the group it = it2; if (!group.isEmpty()) { FileActionMngr::instance()->addToGroup(leader, group); } } } } // namespace Digikam diff --git a/digikam/items/imageviewutilities.h b/digikam/items/imageviewutilities.h index 6a7c83f097..ff6a0c5442 100644 --- a/digikam/items/imageviewutilities.h +++ b/digikam/items/imageviewutilities.h @@ -1,99 +1,99 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-05-04 * Description : Various operations on images * * Copyright (C) 2002-2014 by Gilles Caulier * Copyright (C) 2009-2010 by Marcel Wiesweg * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #ifndef IMAGEVIEWUTILITIES_H #define IMAGEVIEWUTILITIES_H // Qt includes #include #include // KDE includes #include // Local includes #include "imageinfo.h" class KJob; namespace KIO { class Job; } namespace Digikam { class Album; class ImageViewUtilities : public QObject { Q_OBJECT public: enum DeleteMode { DeletePermanently = 1, DeleteUseTrash = 2 }; explicit ImageViewUtilities(QWidget* const parentWidget); public Q_SLOTS: void createNewAlbumForInfos(const QList& infos, Album* currentAlbum); bool deleteImages(const QList& infos, const DeleteMode deleteMode); void deleteImagesDirectly(const QList& infos, const DeleteMode deleteMode); void insertToLightTableAuto(const QList& all, const QList& selected, const ImageInfo& current); void insertToLightTable(const QList& list, const ImageInfo& current, bool addTo); void insertToQueueManager(const QList& list, const ImageInfo& currentInfo, bool newQueue); void insertSilentToQueueManager(const QList& list, const ImageInfo& currentInfo, int queueid); void notifyFileContentChanged(const KUrl::List& urls); - void openInEditor(const ImageInfo& info, const QList& allInfosToOpen, Album* currentAlbum); + void openFile(const ImageInfo& info, const QList& allInfosToOpen, Album* currentAlbum); void rename(const KUrl& imageUrl, const QString& newName); void setAsAlbumThumbnail(Album* album, const ImageInfo& imageInfo); void createGroupByTimeFromInfoList(const ImageInfoList& imageInfoList); Q_SIGNALS: void editorCurrentUrlChanged(const KUrl& url); protected: QWidget* m_widget; }; } // namespace Digikam Q_DECLARE_METATYPE(Digikam::ImageViewUtilities::DeleteMode) #endif /* IMAGEVIEWUTILITIES_H */ diff --git a/digikam/views/digikamview.cpp b/digikam/views/digikamview.cpp index 8190948e4e..c3a00cc162 100644 --- a/digikam/views/digikamview.cpp +++ b/digikam/views/digikamview.cpp @@ -1,2364 +1,2364 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2002-16-10 * Description : implementation of album view interface. * * Copyright (C) 2002-2005 by Renchi Raju * Copyright (C) 2002-2014 by Gilles Caulier * Copyright (C) 2009-2011 by Johannes Wienke * Copyright (C) 2010-2011 by Andi Clemens * Copyright (C) 2011-2013 by Michael G. Hansen * Copyright (C) 2014 by Mohamed Anwer * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "digikamview.moc" // Qt includes #include // KDE includes #include #include #include #include #include #include // Local includes #include "albumhistory.h" #include "albumsettings.h" #include "metadatasynchronizer.h" #include "digikamapp.h" #include "digikamimageview.h" #include "dzoombar.h" #include "imagealbummodel.h" #include "imagedescedittab.h" #include "imagepreviewview.h" #include "imagepropertiessidebardb.h" #include "imagethumbnailbar.h" #include "imageviewutilities.h" #include "filterstatusbar.h" #include "leftsidebarwidgets.h" #include "loadingcacheinterface.h" #include "mapwidgetview.h" #include "mediaplayerview.h" #include "metadatasettings.h" #include "newitemsfinder.h" #include "globals.h" #include "metadatahub.h" #include "fileactionmngr.h" #include "queuemgrwindow.h" #include "scancontroller.h" #include "setup.h" #include "sidebar.h" #include "slideshow.h" #include "slideshowbuilder.h" #include "statusprogressbar.h" #include "filtersidebarwidget.h" #include "tagmodificationhelper.h" #include "imagepropertiesversionstab.h" #include "tagscache.h" #include "searchxml.h" #include "fileactionprogress.h" #include "versionmanagersettings.h" #include "tableview.h" #include "tagsmanager.h" #include "thumbsgenerator.h" #include "albumlabelstreeview.h" #ifdef USE_PRESENTATION_MODE #include "qmlshow.h" #endif // USE_PRESENTATION_MODE namespace Digikam { class DigikamView::Private { public: Private() : needDispatchSelection(false), useAlbumHistory(false), initialAlbumID(0), thumbSize(ThumbnailSize::Medium), dockArea(0), splitter(0), selectionTimer(0), thumbSizeTimer(0), albumFolderSideBar(0), tagViewSideBar(0), labelsSideBar(0), dateViewSideBar(0), timelineSideBar(0), searchSideBar(0), fuzzySearchSideBar(0), gpsSearchSideBar(0), peopleSideBar(0), parent(0), iconView(0), mapView(0), tableView(0), albumManager(0), albumHistory(0), stackedview(0), lastViewMode(StackedView::IconViewMode), albumModificationHelper(0), tagModificationHelper(0), searchModificationHelper(0), leftSideBar(0), rightSideBar(0), filterWidget(0), optionAlbumViewPrefix("AlbumView"), modelCollection(0), labelsSearchHandler(0) { } QString userPresentableAlbumTitle(const QString& album) const; void addPageUpDownActions(DigikamView* const q, QWidget* const w); public: bool needDispatchSelection; bool useAlbumHistory; int initialAlbumID; int thumbSize; QMainWindow* dockArea; SidebarSplitter* splitter; QTimer* selectionTimer; QTimer* thumbSizeTimer; // left side bar AlbumFolderViewSideBarWidget* albumFolderSideBar; TagViewSideBarWidget* tagViewSideBar; LabelsSideBarWidget* labelsSideBar; DateFolderViewSideBarWidget* dateViewSideBar; TimelineSideBarWidget* timelineSideBar; SearchSideBarWidget* searchSideBar; FuzzySearchSideBarWidget* fuzzySearchSideBar; GPSSearchSideBarWidget* gpsSearchSideBar; PeopleSideBarWidget* peopleSideBar; DigikamApp* parent; DigikamImageView* iconView; MapWidgetView* mapView; TableView* tableView; AlbumManager* albumManager; AlbumHistory* albumHistory; StackedView* stackedview; StackedView::StackedViewMode lastViewMode; AlbumModificationHelper* albumModificationHelper; TagModificationHelper* tagModificationHelper; SearchModificationHelper* searchModificationHelper; Sidebar* leftSideBar; ImagePropertiesSideBarDB* rightSideBar; FilterSideBarWidget* filterWidget; QString optionAlbumViewPrefix; QList leftSideBarWidgets; DigikamModelCollection* modelCollection; AlbumLabelsSearchHandler* labelsSearchHandler; }; QString DigikamView::Private::userPresentableAlbumTitle(const QString& title) const { if (title == SAlbum::getTemporaryHaarTitle(DatabaseSearch::HaarSketchSearch)) { return i18n("Fuzzy Sketch Search"); } else if (title == SAlbum::getTemporaryHaarTitle(DatabaseSearch::HaarImageSearch)) { return i18n("Fuzzy Image Search"); } else if (title == SAlbum::getTemporaryTitle(DatabaseSearch::MapSearch)) { return i18n("Map Search"); } else if (title == SAlbum::getTemporaryTitle(DatabaseSearch::AdvancedSearch) || title == SAlbum::getTemporaryTitle(DatabaseSearch::KeywordSearch)) { return i18n("Last Search"); } else if (title == SAlbum::getTemporaryTitle(DatabaseSearch::TimeLineSearch)) { return i18n("Timeline"); } return title; } void DigikamView::Private::addPageUpDownActions(DigikamView* const q, QWidget* const w) { QShortcut* const nextImageShortcut = new QShortcut(w); nextImageShortcut->setKey(Qt::Key_PageDown); nextImageShortcut->setContext(Qt::WidgetWithChildrenShortcut); QObject::connect(nextImageShortcut, SIGNAL(activated()), q, SLOT(slotNextItem())); QShortcut* const prevImageShortcut = new QShortcut(w); prevImageShortcut->setKey(Qt::Key_PageUp); prevImageShortcut->setContext(Qt::WidgetWithChildrenShortcut); QObject::connect(prevImageShortcut, SIGNAL(activated()), q, SLOT(slotPrevItem())); } // ------------------------------------------------------------------------------------------- DigikamView::DigikamView(QWidget* const parent, DigikamModelCollection* const modelCollection) : KHBox(parent), d(new Private) { qRegisterMetaType("SlideShowSettings"); d->parent = static_cast(parent); d->modelCollection = modelCollection; d->albumManager = AlbumManager::instance(); d->albumModificationHelper = new AlbumModificationHelper(this, this); d->tagModificationHelper = new TagModificationHelper(this, this); d->searchModificationHelper = new SearchModificationHelper(this, this); d->splitter = new SidebarSplitter; d->splitter->setFrameStyle( QFrame::NoFrame ); d->splitter->setFrameShadow( QFrame::Plain ); d->splitter->setFrameShape( QFrame::NoFrame ); d->splitter->setOpaqueResize(false); d->leftSideBar = new Sidebar(this, d->splitter, KMultiTabBar::Left); d->leftSideBar->setObjectName("Digikam Left Sidebar"); d->splitter->setParent(this); // The dock area where the thumbnail bar is allowed to go. d->dockArea = new QMainWindow(this, Qt::Widget); d->splitter->addWidget(d->dockArea); d->stackedview = new StackedView(d->dockArea); d->dockArea->setCentralWidget(d->stackedview); d->stackedview->setDockArea(d->dockArea); d->iconView = d->stackedview->imageIconView(); d->mapView = d->stackedview->mapWidgetView(); d->tableView = d->stackedview->tableView(); d->addPageUpDownActions(this, d->stackedview->imagePreviewView()); d->addPageUpDownActions(this, d->stackedview->thumbBar()); d->addPageUpDownActions(this, d->stackedview->mediaPlayerView()); d->rightSideBar = new ImagePropertiesSideBarDB(this, d->splitter, KMultiTabBar::Right, true); d->rightSideBar->setObjectName("Digikam Right Sidebar"); // album folder view d->albumFolderSideBar = new AlbumFolderViewSideBarWidget(d->leftSideBar, d->modelCollection->getAlbumModel(), d->albumModificationHelper); d->leftSideBarWidgets << d->albumFolderSideBar; connect(d->albumFolderSideBar, SIGNAL(signalFindDuplicatesInAlbum(Album*)), this, SLOT(slotNewDuplicatesSearch(Album*))); // Tags sidebar tab contents. d->tagViewSideBar = new TagViewSideBarWidget(d->leftSideBar, d->modelCollection->getTagModel()); d->leftSideBarWidgets << d->tagViewSideBar; connect(d->tagViewSideBar, SIGNAL(signalFindDuplicatesInAlbum(Album*)), this, SLOT(slotNewDuplicatesSearch(Album*))); // Labels sidebar d->labelsSideBar = new LabelsSideBarWidget(d->leftSideBar); d->leftSideBarWidgets << d->labelsSideBar; d->labelsSearchHandler = new AlbumLabelsSearchHandler(d->labelsSideBar->labelsTree()); // date view d->dateViewSideBar = new DateFolderViewSideBarWidget(d->leftSideBar, d->modelCollection->getDateAlbumModel(), d->iconView->imageAlbumFilterModel()); d->leftSideBarWidgets << d->dateViewSideBar; // timeline side bar d->timelineSideBar = new TimelineSideBarWidget(d->leftSideBar, d->modelCollection->getSearchModel(), d->searchModificationHelper); d->leftSideBarWidgets << d->timelineSideBar; // Search sidebar tab contents. d->searchSideBar = new SearchSideBarWidget(d->leftSideBar, d->modelCollection->getSearchModel(), d->searchModificationHelper); d->leftSideBarWidgets << d->searchSideBar; // Fuzzy search d->fuzzySearchSideBar = new FuzzySearchSideBarWidget(d->leftSideBar, d->modelCollection->getSearchModel(), d->searchModificationHelper); d->leftSideBarWidgets << d->fuzzySearchSideBar; d->gpsSearchSideBar = new GPSSearchSideBarWidget(d->leftSideBar, d->modelCollection->getSearchModel(), d->searchModificationHelper, d->iconView->imageFilterModel(),d->iconView->getSelectionModel()); d->leftSideBarWidgets << d->gpsSearchSideBar; // People Sidebar d->peopleSideBar = new PeopleSideBarWidget(d->leftSideBar, d->modelCollection->getTagFacesModel(), d->searchModificationHelper); connect(d->peopleSideBar, SIGNAL(requestFaceMode(bool)), d->iconView, SLOT(setFaceMode(bool))); d->leftSideBarWidgets << d->peopleSideBar; foreach(SidebarWidget* const leftWidget, d->leftSideBarWidgets) { d->leftSideBar->appendTab(leftWidget, leftWidget->getIcon(), leftWidget->getCaption()); connect(leftWidget, SIGNAL(requestActiveTab(SidebarWidget*)), this, SLOT(slotLeftSideBarActivate(SidebarWidget*))); } // To the right. d->addPageUpDownActions(this, d->rightSideBar->imageDescEditTab()); // Tags Filter sidebar tab contents. d->filterWidget = new FilterSideBarWidget(d->rightSideBar, d->modelCollection->getTagFilterModel()); d->rightSideBar->appendTab(d->filterWidget, SmallIcon("view-filter"), i18n("Filters")); // Versions sidebar overlays d->rightSideBar->getFiltersHistoryTab()->addOpenAlbumAction(d->iconView->imageModel()); d->rightSideBar->getFiltersHistoryTab()->addShowHideOverlay(); d->selectionTimer = new QTimer(this); d->selectionTimer->setSingleShot(true); d->selectionTimer->setInterval(75); d->thumbSizeTimer = new QTimer(this); d->thumbSizeTimer->setSingleShot(true); d->thumbSizeTimer->setInterval(300); d->albumHistory = new AlbumHistory(); slotSidebarTabTitleStyleChanged(); setupConnections(); connect(d->rightSideBar->imageDescEditTab()->getNewTagEdit(), SIGNAL(taggingActionFinished()), this, SLOT(slotFocusAndNextImage())); connect(d->rightSideBar, SIGNAL(signalSetupMetadataFilters(int)), this, SLOT(slotSetupMetadataFilters(int))); } DigikamView::~DigikamView() { saveViewState(); delete d->albumHistory; delete d; } void DigikamView::applySettings() { foreach(SidebarWidget* const sidebarWidget, d->leftSideBarWidgets) { sidebarWidget->applySettings(); } d->iconView->imageFilterModel()->setVersionImageFilterSettings(VersionImageFilterSettings(AlbumSettings::instance()->getVersionManagerSettings())); refreshView(); } void DigikamView::refreshView() { d->rightSideBar->refreshTagsView(); } void DigikamView::setupConnections() { // -- DigikamApp connections ---------------------------------- connect(d->parent, SIGNAL(signalEscapePressed()), this, SLOT(slotEscapePreview())); connect(d->parent, SIGNAL(signalEscapePressed()), d->stackedview, SLOT(slotEscapePreview())); connect(d->parent, SIGNAL(signalNextItem()), this, SLOT(slotNextItem())); connect(d->parent, SIGNAL(signalPrevItem()), this, SLOT(slotPrevItem())); connect(d->parent, SIGNAL(signalFirstItem()), this, SLOT(slotFirstItem())); connect(d->parent, SIGNAL(signalLastItem()), this, SLOT(slotLastItem())); connect(d->parent, SIGNAL(signalCutAlbumItemsSelection()), d->iconView, SLOT(cut())); connect(d->parent, SIGNAL(signalCopyAlbumItemsSelection()), d->iconView, SLOT(copy())); connect(d->parent, SIGNAL(signalPasteAlbumItemsSelection()), d->iconView, SLOT(paste())); // -- AlbumManager connections -------------------------------- connect(d->albumManager, SIGNAL(signalAlbumCurrentChanged(QList)), this, SLOT(slotAlbumSelected(QList))); connect(d->albumManager, SIGNAL(signalAllAlbumsLoaded()), this, SLOT(slotAllAlbumsLoaded())); connect(d->albumManager, SIGNAL(signalAlbumsCleared()), this, SLOT(slotAlbumsCleared())); // -- IconView Connections ------------------------------------- connect(d->iconView->model(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(slotImageSelected())); connect(d->iconView->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(slotImageSelected())); connect(d->iconView->model(), SIGNAL(layoutChanged()), this, SLOT(slotImageSelected())); connect(d->iconView, SIGNAL(selectionChanged()), this, SLOT(slotImageSelected())); connect(d->iconView, SIGNAL(previewRequested(ImageInfo)), this, SLOT(slotTogglePreviewMode(ImageInfo))); connect(d->iconView, SIGNAL(gotoAlbumAndImageRequested(ImageInfo)), this, SLOT(slotGotoAlbumAndItem(ImageInfo))); connect(d->iconView, SIGNAL(gotoDateAndImageRequested(ImageInfo)), this, SLOT(slotGotoDateAndItem(ImageInfo))); connect(d->iconView, SIGNAL(gotoTagAndImageRequested(int)), this, SLOT(slotGotoTagAndItem(int))); connect(d->iconView, SIGNAL(zoomOutStep()), this, SLOT(slotZoomOut())); connect(d->iconView, SIGNAL(zoomInStep()), this, SLOT(slotZoomIn())); connect(d->iconView, SIGNAL(signalPopupTagsView()), d->rightSideBar, SLOT(slotPopupTagsView())); // -- TableView Connections ----------------------------------- connect(d->tableView, SIGNAL(signalPreviewRequested(ImageInfo)), this, SLOT(slotTogglePreviewMode(ImageInfo))); connect(d->tableView, SIGNAL(signalZoomOutStep()), this, SLOT(slotZoomOut())); connect(d->tableView, SIGNAL(signalZoomInStep()), this, SLOT(slotZoomIn())); connect(d->tableView, SIGNAL(signalPopupTagsView()), d->rightSideBar, SLOT(slotPopupTagsView())); connect(d->tableView, SIGNAL(signalGotoAlbumAndImageRequested(ImageInfo)), this, SLOT(slotGotoAlbumAndItem(ImageInfo))); connect(d->tableView, SIGNAL(signalGotoDateAndImageRequested(ImageInfo)), this, SLOT(slotGotoDateAndItem(ImageInfo))); connect(d->tableView, SIGNAL(signalGotoTagAndImageRequested(int)), this, SLOT(slotGotoTagAndItem(int))); // TableView::signalItemsChanged is emitted when something changes in the model that // DigikamView should care about, not only the selection. connect(d->tableView, SIGNAL(signalItemsChanged()), this, SLOT(slotImageSelected())); // -- Sidebar Connections ------------------------------------- connect(d->leftSideBar, SIGNAL(signalChangedTab(QWidget*)), this, SLOT(slotLeftSidebarChangedTab(QWidget*))); connect(d->rightSideBar, SIGNAL(signalFirstItem()), this, SLOT(slotFirstItem())); connect(d->rightSideBar, SIGNAL(signalNextItem()), this, SLOT(slotNextItem())); connect(d->rightSideBar, SIGNAL(signalPrevItem()), this, SLOT(slotPrevItem())); connect(d->rightSideBar, SIGNAL(signalLastItem()), this, SLOT(slotLastItem())); connect(this, SIGNAL(signalNoCurrentItem()), d->rightSideBar, SLOT(slotNoCurrentItem())); connect(d->gpsSearchSideBar, SIGNAL(signalMapSoloItems(QList,QString)), d->iconView->imageFilterModel(), SLOT(setIdWhitelist(QList,QString))); // -- Filter Bars Connections --------------------------------- ImageAlbumFilterModel* const model = d->iconView->imageAlbumFilterModel(); connect(d->filterWidget, SIGNAL(signalTagFilterChanged(QList,QList,ImageFilterSettings::MatchingCondition,bool,QList,QList)), d->iconView->imageFilterModel(), SLOT(setTagFilter(QList,QList,ImageFilterSettings::MatchingCondition,bool,QList,QList))); connect(d->filterWidget, SIGNAL(signalRatingFilterChanged(int,ImageFilterSettings::RatingCondition,bool)), model, SLOT(setRatingFilter(int,ImageFilterSettings::RatingCondition,bool))); connect(d->filterWidget, SIGNAL(signalSearchTextFilterChanged(SearchTextFilterSettings)), model, SLOT(setTextFilter(SearchTextFilterSettings))); connect(model, SIGNAL(filterMatchesForText(bool)), d->filterWidget, SLOT(slotFilterMatchesForText(bool))); connect(d->filterWidget, SIGNAL(signalMimeTypeFilterChanged(int)), model, SLOT(setMimeTypeFilter(int))); connect(d->filterWidget, SIGNAL(signalGeolocationFilterChanged(ImageFilterSettings::GeolocationCondition)), model, SLOT(setGeolocationFilter(ImageFilterSettings::GeolocationCondition))); // -- Preview image widget Connections ------------------------ connect(d->stackedview, SIGNAL(signalNextItem()), this, SLOT(slotNextItem())); connect(d->stackedview, SIGNAL(signalPrevItem()), this, SLOT(slotPrevItem())); connect(d->stackedview, SIGNAL(signalEditItem()), this, SLOT(slotImageEdit())); connect(d->stackedview, SIGNAL(signalDeleteItem()), this, SLOT(slotImageDelete())); connect(d->stackedview, SIGNAL(signalViewModeChanged()), this, SLOT(slotViewModeChanged())); connect(d->stackedview, SIGNAL(signalEscapePreview()), this, SLOT(slotEscapePreview())); connect(d->stackedview, SIGNAL(signalSlideShow()), this, SLOT(slotSlideShowAll())); connect(d->stackedview, SIGNAL(signalZoomFactorChanged(double)), this, SLOT(slotZoomFactorChanged(double))); connect(d->stackedview, SIGNAL(signalInsert2LightTable()), this, SLOT(slotImageAddToLightTable())); connect(d->stackedview, SIGNAL(signalInsert2QueueMgr()), this, SLOT(slotImageAddToCurrentQueue())); connect(d->stackedview, SIGNAL(signalFindSimilar()), this, SLOT(slotImageFindSimilar())); connect(d->stackedview, SIGNAL(signalAddToExistingQueue(int)), this, SLOT(slotImageAddToExistingQueue(int))); connect(d->stackedview, SIGNAL(signalGotoAlbumAndItem(ImageInfo)), this, SLOT(slotGotoAlbumAndItem(ImageInfo))); connect(d->stackedview, SIGNAL(signalGotoDateAndItem(ImageInfo)), this, SLOT(slotGotoDateAndItem(ImageInfo))); connect(d->stackedview, SIGNAL(signalGotoTagAndItem(int)), this, SLOT(slotGotoTagAndItem(int))); // -- FileActionMngr progress --------------- connect(FileActionMngr::instance(), SIGNAL(signalImageChangeFailed(QString,QStringList)), this, SLOT(slotImageChangeFailed(QString,QStringList))); // -- timers --------------- connect(d->selectionTimer, SIGNAL(timeout()), this, SLOT(slotDispatchImageSelected())); connect(d->thumbSizeTimer, SIGNAL(timeout()), this, SLOT(slotThumbSizeEffect()) ); // -- Album Settings ---------------- connect(AlbumSettings::instance(), SIGNAL(setupChanged()), this, SLOT(slotSidebarTabTitleStyleChanged())); // -- Album History ----------------- connect(this, SIGNAL(signalAlbumSelected(bool)), d->albumHistory, SLOT(slotAlbumSelected())); connect(this, SIGNAL(signalImageSelected(ImageInfoList,ImageInfoList)), d->albumHistory, SLOT(slotImageSelected(ImageInfoList))); connect(d->iconView, SIGNAL(currentChanged(ImageInfo)), d->albumHistory, SLOT(slotCurrentChange(ImageInfo))); connect(d->iconView, SIGNAL(gotoAlbumAndImageRequested(ImageInfo)), d->albumHistory, SLOT(slotClearSelectPAlbum(ImageInfo))); connect(d->iconView, SIGNAL(gotoTagAndImageRequested(int)), d->albumHistory, SLOT(slotClearSelectTAlbum(int))); connect(d->iconView->imageModel(), SIGNAL(imageInfosAdded(QList)), d->albumHistory, SLOT(slotAlbumCurrentChanged())); connect(d->albumHistory, SIGNAL(signalSetCurrent(qlonglong)), this, SLOT(slotSetCurrentWhenAvailable(qlonglong))); connect(d->albumHistory, SIGNAL(signalSetSelectedInfos(QList)), d->iconView, SLOT(setSelectedImageInfos(QList))); connect(d->albumManager, SIGNAL(signalAlbumDeleted(Album*)), d->albumHistory, SLOT(slotAlbumDeleted(Album*))); connect(d->albumManager, SIGNAL(signalAlbumsCleared()), d->albumHistory, SLOT(slotAlbumsCleared())); // -- Image versions ---------------- connect(d->rightSideBar->getFiltersHistoryTab(), SIGNAL(imageSelected(ImageInfo)), d->iconView, SLOT(hintAt(ImageInfo))); connect(d->rightSideBar->getFiltersHistoryTab(), SIGNAL(actionTriggered(ImageInfo)), this, SLOT(slotGotoAlbumAndItem(ImageInfo))); } void DigikamView::connectIconViewFilter(FilterStatusBar* const filterbar) { ImageAlbumFilterModel* const model = d->iconView->imageAlbumFilterModel(); connect(model, SIGNAL(filterMatches(bool)), filterbar, SLOT(slotFilterMatches(bool))); connect(model, SIGNAL(filterSettingsChanged(ImageFilterSettings)), filterbar, SLOT(slotFilterSettingsChanged(ImageFilterSettings))); connect(filterbar, SIGNAL(signalResetFilters()), d->filterWidget, SLOT(slotResetFilters())); connect(filterbar, SIGNAL(signalPopupFiltersView()), this, SLOT(slotPopupFiltersView())); } void DigikamView::slotPopupFiltersView() { d->rightSideBar->setActiveTab(d->filterWidget); d->filterWidget->setFocusToTextFilter(); } void DigikamView::loadViewState() { foreach(SidebarWidget* const widget, d->leftSideBarWidgets) { widget->loadState(); } d->filterWidget->loadState(); KSharedConfig::Ptr config = KGlobal::config(); KConfigGroup group = config->group("MainWindow"); // Restore the splitter d->splitter->restoreState(group); // Restore the thumbnail bar dock. QByteArray thumbbarState; thumbbarState = group.readEntry("ThumbbarState", thumbbarState); d->dockArea->restoreState(QByteArray::fromBase64(thumbbarState)); d->initialAlbumID = group.readEntry("InitialAlbumID", 0); d->mapView->loadState(); d->tableView->loadState(); d->rightSideBar->loadState(); } void DigikamView::saveViewState() { KSharedConfig::Ptr config = KGlobal::config(); KConfigGroup group = config->group("MainWindow"); foreach(SidebarWidget* const widget, d->leftSideBarWidgets) { widget->saveState(); } d->filterWidget->saveState(); // Save the splitter states. d->splitter->saveState(group); // Save the position and size of the thumbnail bar. The thumbnail bar dock // needs to be closed explicitly, because when it is floating and visible // (when the user is in image preview mode) when the layout is saved, it // also reappears when restoring the view, while it should always be hidden. d->stackedview->thumbBarDock()->close(); group.writeEntry("ThumbbarState", d->dockArea->saveState().toBase64()); QList albumList = AlbumManager::instance()->currentAlbums(); Album* album = 0; if(!albumList.isEmpty()) { album = albumList.first(); } if (album) { group.writeEntry("InitialAlbumID", album->globalID()); } else { group.writeEntry("InitialAlbumID", 0); } d->mapView->saveState(); d->tableView->saveState(); d->rightSideBar->saveState(); } QList DigikamView::leftSidebarWidgets() const { return d->leftSideBarWidgets; } KUrl::List DigikamView::allUrls() const { /// @todo This functions seems not to be used anywhere right now switch (viewMode()) { case StackedView::TableViewMode: return d->tableView->allUrls(); default: return d->iconView->urls(); } } KUrl::List DigikamView::selectedUrls() const { switch (viewMode()) { case StackedView::TableViewMode: return d->tableView->selectedUrls(); default: return d->iconView->selectedUrls(); } } void DigikamView::showSideBars() { d->leftSideBar->restore(); d->rightSideBar->restore(); } void DigikamView::hideSideBars() { d->leftSideBar->backup(); d->rightSideBar->backup(); } void DigikamView::toggleLeftSidebar() { d->leftSideBar->isExpanded() ? d->leftSideBar->shrink() : d->leftSideBar->expand(); } void DigikamView::toggleRightSidebar() { d->rightSideBar->isExpanded() ? d->rightSideBar->shrink() : d->rightSideBar->expand(); } void DigikamView::previousLeftSideBarTab() { d->leftSideBar->activePreviousTab(); } void DigikamView::nextLeftSideBarTab() { d->leftSideBar->activeNextTab(); } void DigikamView::previousRightSideBarTab() { d->rightSideBar->activePreviousTab(); } void DigikamView::nextRightSideBarTab() { d->rightSideBar->activeNextTab(); } void DigikamView::slotFirstItem() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotGoToRow(0, false); break; default: // all other views are tied to IconView's selection model d->iconView->toFirstIndex(); } } void DigikamView::slotPrevItem() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotGoToRow(-1, true); break; default: // all other views are tied to IconView's selection model d->iconView->toPreviousIndex(); } } void DigikamView::slotNextItem() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotGoToRow(1, true); break; default: // all other views are tied to IconView's selection model d->iconView->toNextIndex(); } } void DigikamView::slotLastItem() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotGoToRow(-1, false); break; default: // all other views are tied to IconView's selection model d->iconView->toLastIndex(); } } void DigikamView::slotSelectItemByUrl(const KUrl& url) { /// @todo This functions seems not to be used anywhere right now /// @todo Adapt to TableView d->iconView->toIndex(url); } void DigikamView::slotAllAlbumsLoaded() { disconnect(d->albumManager, SIGNAL(signalAllAlbumsLoaded()), this, SLOT(slotAllAlbumsLoaded())); loadViewState(); d->leftSideBar->loadState(); d->rightSideBar->loadState(); d->rightSideBar->populateTags(); // now that all albums have been loaded, activate the albumHistory d->useAlbumHistory = true; Album* const album = d->albumManager->findAlbum(d->initialAlbumID); d->albumManager->setCurrentAlbums(QList() << album); } void DigikamView::slotSortAlbums(int order) { AlbumSettings* settings = AlbumSettings::instance(); if (!settings) { return; } settings->setAlbumSortOrder((AlbumSettings::AlbumSortOrder) order); settings->saveSettings(); //A dummy way to force the tree view to resort if the album sort role changed PAlbum* albumBeforeSorting = d->albumFolderSideBar->currentAlbum(); settings->setAlbumSortChanged(true); d->albumFolderSideBar->doSaveState(); d->albumFolderSideBar->doLoadState(); d->albumFolderSideBar->doSaveState(); d->albumFolderSideBar->doLoadState(); settings->setAlbumSortChanged(false); if (d->leftSideBar->getActiveTab() == d->albumFolderSideBar) { d->albumFolderSideBar->setCurrentAlbum(albumBeforeSorting); } } void DigikamView::slotNewAlbum() { // TODO use the selection model of the view instead d->albumModificationHelper->slotAlbumNew(d->albumFolderSideBar->currentAlbum()); } void DigikamView::slotDeleteAlbum() { d->albumModificationHelper->slotAlbumDelete(d->albumFolderSideBar->currentAlbum()); } void DigikamView::slotRenameAlbum() { d->albumModificationHelper->slotAlbumRename(d->albumFolderSideBar->currentAlbum()); } void DigikamView::slotNewTag() { d->tagModificationHelper->slotTagNew(d->tagViewSideBar->currentAlbum()); } void DigikamView::slotDeleteTag() { d->tagModificationHelper->slotTagDelete(d->tagViewSideBar->currentAlbum()); } void DigikamView::slotEditTag() { d->tagModificationHelper->slotTagEdit(d->tagViewSideBar->currentAlbum()); } void DigikamView::slotOpenTagsManager() { TagsManager* tagMngr = TagsManager::instance(); tagMngr->show(); tagMngr->activateWindow(); tagMngr->raise(); } void DigikamView::slotAssignTag() { ImageDescEditTab* imageDescEditTab = d->rightSideBar->imageDescEditTab(); //activate image properties tab d->rightSideBar->setActiveTab(imageDescEditTab); //activate tags tab on properties tab imageDescEditTab->setFocusToNewTagEdit(); } void DigikamView::slotNewKeywordSearch() { slotLeftSideBarActivate(d->searchSideBar); d->searchSideBar->newKeywordSearch(); } void DigikamView::slotNewAdvancedSearch() { slotLeftSideBarActivate(d->searchSideBar); d->searchSideBar->newAdvancedSearch(); } void DigikamView::slotNewDuplicatesSearch(Album* album) { slotLeftSideBarActivate(d->fuzzySearchSideBar); d->fuzzySearchSideBar->newDuplicatesSearch(album); } void DigikamView::slotAlbumsCleared() { emit signalAlbumSelected(false); } void DigikamView::slotAlbumHistoryBack(int steps) { QList albums; QWidget* widget = 0; d->albumHistory->back(albums, &widget, steps); changeAlbumFromHistory(albums, widget); } void DigikamView::slotAlbumHistoryForward(int steps) { QList albums; QWidget* widget = 0; d->albumHistory->forward(albums, &widget, steps); changeAlbumFromHistory(albums , widget); } // TODO update, use SideBarWidget instead of QWidget void DigikamView::changeAlbumFromHistory(QList album, QWidget* const widget) { if (!(album.isEmpty()) && widget) { // TODO update, temporary casting until signature is changed SidebarWidget* const sideBarWidget = dynamic_cast(widget); if (sideBarWidget) { sideBarWidget->changeAlbumFromHistory(album); slotLeftSideBarActivate(sideBarWidget); if(sideBarWidget == d->labelsSideBar) { d->labelsSearchHandler->restoreSelectionFromHistory(d->albumHistory->neededLabels()); } } d->parent->enableAlbumBackwardHistory(d->useAlbumHistory && !d->albumHistory->isBackwardEmpty()); d->parent->enableAlbumForwardHistory(d->useAlbumHistory && !d->albumHistory->isForwardEmpty()); } } void DigikamView::clearHistory() { d->albumHistory->clearHistory(); d->parent->enableAlbumBackwardHistory(false); d->parent->enableAlbumForwardHistory(false); } void DigikamView::getBackwardHistory(QStringList& titles) { d->albumHistory->getBackwardHistory(titles); for (int i = 0; i < titles.size(); ++i) { titles[i] = d->userPresentableAlbumTitle(titles.at(i)); } } void DigikamView::getForwardHistory(QStringList& titles) { d->albumHistory->getForwardHistory(titles); for (int i = 0; i < titles.size(); ++i) { titles[i] = d->userPresentableAlbumTitle(titles.at(i)); } } void DigikamView::slotGotoAlbumAndItem(const ImageInfo& imageInfo) { kDebug() << "going to " << imageInfo; emit signalNoCurrentItem(); PAlbum* const album = AlbumManager::instance()->findPAlbum(imageInfo.albumId()); d->albumFolderSideBar->setCurrentAlbum(album); slotLeftSideBarActivate(d->albumFolderSideBar); // Set the activate item url to find in the Album View after // all items have be reloaded. slotSetCurrentWhenAvailable(imageInfo.id()); // And finally toggle album manager to handle album history and // reload all items. d->albumManager->setCurrentAlbums(QList() << album); } void DigikamView::slotGotoDateAndItem(const ImageInfo& imageInfo) { QDate date = imageInfo.dateTime().date(); emit signalNoCurrentItem(); // Change to Date Album view. // Note, that this also opens the side bar if it is closed; this is // considered as a feature, because it highlights that the view was changed. slotLeftSideBarActivate(d->dateViewSideBar); // Set the activate item url to find in the Album View after // all items have be reloaded. slotSetCurrentWhenAvailable(imageInfo.id()); // Change the year and month of the iconItem (day is unused). d->dateViewSideBar->gotoDate(date); } void DigikamView::slotGotoTagAndItem(int tagID) { // FIXME: Arnd: don't know yet how to get the iconItem passed through ... // then we would know how to use the following ... // KURL url( iconItem->imageInfo()->kurl() ); // url.cleanPath(); emit signalNoCurrentItem(); // Change to Tag Folder view. // Note, that this also opens the side bar if it is closed; this is // considered as a feature, because it highlights that the view was changed. slotLeftSideBarActivate(d->tagViewSideBar); // Set the current tag in the tag folder view. // TODO this slot should use a TAlbum pointer directly TAlbum* const tag = AlbumManager::instance()->findTAlbum(tagID); if (tag) { d->tagViewSideBar->setCurrentAlbum(tag); } else { kError() << "Could not find a tag album for tag id " << tagID; } // Set the activate item url to find in the Tag View after // all items have be reloaded. // FIXME: see above // d->iconView->setAlbumItemToFind(url); } void DigikamView::slotSelectAlbum(const KUrl& url) { PAlbum* const album = d->albumManager->findPAlbum(url); if (!album) { kWarning() << "Unable to find album for " << url; return; } slotLeftSideBarActivate(d->albumFolderSideBar); d->albumFolderSideBar->setCurrentAlbum(album); } void DigikamView::slotAlbumSelected(QList albums) { emit signalNoCurrentItem(); if (albums.isEmpty() || !(albums.first())) { d->iconView->openAlbum(QList()); d->mapView->openAlbum(0); emit signalAlbumSelected(false); emit signalTagSelected(false); slotTogglePreviewMode(ImageInfo()); return; } Album* album = albums.first(); if (album->type() == Album::PHYSICAL) { emit signalAlbumSelected(true); emit signalTagSelected(false); } else if (album->type() == Album::TAG) { emit signalAlbumSelected(false); /* kDebug()<<"Album "<title()<<" selected." ; // Now loop through children of the people album and check if this album is a child. Album* peopleAlbum = AlbumManager::instance()->findTAlbum(TagsCache::instance()->tagForPath("/People")); int thisAlbumId = album->id(); QList children = peopleAlbum->childAlbumIds(true); foreach(int id, children) { if(id == thisAlbumId) { kDebug()<<"Is a people tag"; showFaceAlbum(thisAlbumId); emit signalTagSelected(true); return; } } */ emit signalTagSelected(true); } else { emit signalAlbumSelected(false); emit signalTagSelected(false); } if (d->useAlbumHistory && !d->labelsSearchHandler->isRestoringSelectionFromHistory()) { if(!(d->leftSideBar->getActiveTab() == d->labelsSideBar)) { d->albumHistory->addAlbums(albums, d->leftSideBar->getActiveTab()); } else { if(albums.first()->isUsedByLabelsTree()) { d->albumHistory-> addAlbums(albums, d->leftSideBar->getActiveTab(), d->labelsSideBar->selectedLabels()); } } } d->parent->enableAlbumBackwardHistory(d->useAlbumHistory && !d->albumHistory->isBackwardEmpty()); d->parent->enableAlbumForwardHistory(d->useAlbumHistory && !d->albumHistory->isForwardEmpty()); d->iconView->openAlbum(albums); if (album->isRoot()) { d->stackedview->setViewMode(StackedView::WelcomePageMode); } else { switch (viewMode()) { case StackedView::PreviewImageMode: case StackedView::MediaPlayerMode: case StackedView::WelcomePageMode: slotTogglePreviewMode(ImageInfo()); break; default: break; } } } void DigikamView::slotAlbumOpenInFileManager() { Album* const album = d->albumManager->currentAlbums().first(); if (!album || album->type() != Album::PHYSICAL) { return; } if (album->isRoot()) { KMessageBox::error(this, i18n("Cannot open the root album. It is not a physical location.")); return; } PAlbum* const palbum = dynamic_cast(album); if (palbum) { new KRun(KUrl(palbum->folderPath()), this); // KRun will delete itself. } } void DigikamView::slotAlbumOpenInTerminal() { Album* const album = d->albumManager->currentAlbums().first(); if (!album || album->type() != Album::PHYSICAL) { return; } if (album->isRoot()) { KMessageBox::error(this, i18n("Cannot open the root. It is not a physical location.")); return; } PAlbum* const palbum = dynamic_cast(album); if (!palbum) { return; } QString dir(palbum->folderPath()); // If the given directory is not local, it can still be the URL of an // ioslave using UDS_LOCAL_PATH which to be converted first. KUrl url = KIO::NetAccess::mostLocalUrl(dir, this); //If the URL is local after the above conversion, set the directory. if (url.isLocalFile()) { dir = url.toLocalFile(); } KToolInvocation::invokeTerminal(QString(), dir); } void DigikamView::slotRefresh() { switch (viewMode()) { case StackedView::PreviewImageMode: d->stackedview->imagePreviewView()->reload(); break; case StackedView::MediaPlayerMode: d->stackedview->mediaPlayerView()->reload(); break; default: Album* const album = d->iconView->currentAlbum(); if (!album) return; // force reloading of thumbnails LoadingCacheInterface::cleanThumbnailCache(); ThumbsGenerator* const tool = new ThumbsGenerator(true, album->id()); tool->start(); // if physical album, schedule a collection scan of current album's path if (album->type() == Album::PHYSICAL) { NewItemsFinder* const tool = new NewItemsFinder(NewItemsFinder::ScheduleCollectionScan, QStringList() << static_cast(album)->folderPath()); connect(tool, SIGNAL(signalComplete()), this, SLOT(slotAlbumRefreshComplete())); tool->start(); } break; } } void DigikamView::slotAlbumRefreshComplete() { // force reload. Should normally not be necessary, but we may have bugs qlonglong currentId = currentInfo().id(); d->iconView->imageAlbumModel()->refresh(); if (currentId != -1) { slotSetCurrentWhenAvailable(currentId); } } void DigikamView::slotImageSelected() { // delay to slotDispatchImageSelected d->needDispatchSelection = true; d->selectionTimer->start(); switch (viewMode()) { case StackedView::TableViewMode: emit signalSelectionChanged(d->tableView->numberOfSelectedItems()); break; default: emit signalSelectionChanged(d->iconView->numberOfSelectedIndexes()); } } void DigikamView::slotDispatchImageSelected() { if (d->needDispatchSelection) { // the list of ImageInfos of currently selected items, currentItem first // since the iconView tracks the changes also while we are in map widget mode, // we can still pull the data from the iconView const ImageInfoList list = selectedInfoList(true); const ImageInfoList allImages = allInfo(); if (list.isEmpty()) { d->stackedview->setPreviewItem(); emit signalImageSelected(list, allImages); emit signalNoCurrentItem(); } else { d->rightSideBar->itemChanged(list); ImageInfo previousInfo; ImageInfo nextInfo; if (viewMode() == StackedView::TableViewMode) { previousInfo = d->tableView->previousInfo(); nextInfo = d->tableView->nextInfo(); } else { previousInfo = d->iconView->previousInfo(list.first()); nextInfo = d->iconView->nextInfo(list.first()); } if ((viewMode() != StackedView::IconViewMode) && (viewMode() != StackedView::MapWidgetMode) && (viewMode() != StackedView::TableViewMode) ) { d->stackedview->setPreviewItem(list.first(), previousInfo, nextInfo); } emit signalImageSelected(list, allImages); } d->needDispatchSelection = false; } } double DigikamView::zoomMin() const { return d->stackedview->zoomMin(); } double DigikamView::zoomMax() const { return d->stackedview->zoomMax(); } void DigikamView::setZoomFactor(double zoom) { d->stackedview->setZoomFactorSnapped(zoom); } void DigikamView::slotZoomFactorChanged(double zoom) { toggleZoomActions(); emit signalZoomChanged(zoom); } void DigikamView::setThumbSize(int size) { if (viewMode() == StackedView::PreviewImageMode) { double z = DZoomBar::zoomFromSize(size, zoomMin(), zoomMax()); setZoomFactor(z); } else if ( (viewMode() == StackedView::IconViewMode) || (viewMode() == StackedView::TableViewMode) ) { if (size > ThumbnailSize::maxThumbsSize()) { d->thumbSize = ThumbnailSize::maxThumbsSize(); } else if (size < ThumbnailSize::Small) { d->thumbSize = ThumbnailSize::Small; } else { d->thumbSize = size; } emit signalThumbSizeChanged(d->thumbSize); d->thumbSizeTimer->start(); } } void DigikamView::slotThumbSizeEffect() { d->iconView->setThumbnailSize(d->thumbSize); d->tableView->setThumbnailSize(d->thumbSize); toggleZoomActions(); AlbumSettings::instance()->setDefaultIconSize(d->thumbSize); } void DigikamView::toggleZoomActions() { if (viewMode() == StackedView::PreviewImageMode) { d->parent->enableZoomMinusAction(true); d->parent->enableZoomPlusAction(true); if (d->stackedview->maxZoom()) { d->parent->enableZoomPlusAction(false); } if (d->stackedview->minZoom()) { d->parent->enableZoomMinusAction(false); } } else if ( (viewMode() == StackedView::IconViewMode) || (viewMode() == StackedView::TableViewMode) ) { d->parent->enableZoomMinusAction(true); d->parent->enableZoomPlusAction(true); if (d->thumbSize >= ThumbnailSize::maxThumbsSize()) { d->parent->enableZoomPlusAction(false); } if (d->thumbSize <= ThumbnailSize::Small) { d->parent->enableZoomMinusAction(false); } } else { d->parent->enableZoomMinusAction(false); d->parent->enableZoomPlusAction(false); } } void DigikamView::slotZoomIn() { if ( (viewMode() == StackedView::IconViewMode) || (viewMode() == StackedView::TableViewMode) ) { setThumbSize(d->thumbSize + ThumbnailSize::Step); toggleZoomActions(); emit signalThumbSizeChanged(d->thumbSize); } else if (viewMode() == StackedView::PreviewImageMode) { d->stackedview->increaseZoom(); } } void DigikamView::slotZoomOut() { if ( (viewMode() == StackedView::IconViewMode) || (viewMode() == StackedView::TableViewMode) ) { setThumbSize(d->thumbSize - ThumbnailSize::Step); toggleZoomActions(); emit signalThumbSizeChanged(d->thumbSize); } else if (viewMode() == StackedView::PreviewImageMode) { d->stackedview->decreaseZoom(); } } void DigikamView::slotZoomTo100Percents() { if (viewMode() == StackedView::PreviewImageMode) { d->stackedview->toggleFitToWindowOr100(); } } void DigikamView::slotFitToWindow() { if (viewMode() == StackedView::TableViewMode) { /// @todo We should choose an appropriate thumbnail size here } else if (viewMode() == StackedView::IconViewMode) { int nts = d->iconView->fitToWidthIcons(); kDebug() << "new thumb size = " << nts; setThumbSize(nts); toggleZoomActions(); emit signalThumbSizeChanged(d->thumbSize); } else if (viewMode() == StackedView::PreviewImageMode) { d->stackedview->fitToWindow(); } } void DigikamView::slotAlbumPropsEdit() { d->albumModificationHelper->slotAlbumEdit(d->albumManager->currentPAlbum()); } void DigikamView::slotAlbumWriteMetadata() { Album* const album = d->albumManager->currentAlbums().first(); if (!album) { return; } MetadataSynchronizer* const tool = new MetadataSynchronizer(AlbumList() << album, MetadataSynchronizer::WriteFromDatabaseToFile); tool->start(); } void DigikamView::slotAlbumReadMetadata() { Album* const album = d->albumManager->currentAlbums().first(); if (!album) { return; } MetadataSynchronizer* const tool = new MetadataSynchronizer(AlbumList() << album, MetadataSynchronizer::ReadFromFileToDatabase); tool->start(); } void DigikamView::slotImageWriteMetadata() { const ImageInfoList selected = selectedInfoList(); MetadataSynchronizer* const tool = new MetadataSynchronizer(selected, MetadataSynchronizer::WriteFromDatabaseToFile); tool->start(); } void DigikamView::slotImageReadMetadata() { const ImageInfoList selected = selectedInfoList(); MetadataSynchronizer* const tool = new MetadataSynchronizer(selected, MetadataSynchronizer::ReadFromFileToDatabase); tool->start(); } // ---------------------------------------------------------------- void DigikamView::slotEscapePreview() { if (viewMode() == StackedView::IconViewMode || viewMode() == StackedView::MapWidgetMode || viewMode() == StackedView::TableViewMode || viewMode() == StackedView::WelcomePageMode) { return; } // pass a null image info, because we want to fall back to the old // view mode slotTogglePreviewMode(ImageInfo()); } void DigikamView::slotMapWidgetView() { d->stackedview->setViewMode(StackedView::MapWidgetMode); } void DigikamView::slotTableView() { d->stackedview->setViewMode(StackedView::TableViewMode); } void DigikamView::slotIconView() { if (viewMode() == StackedView::PreviewImageMode) { emit signalThumbSizeChanged(d->iconView->thumbnailSize().size()); } // and switch to icon view d->stackedview->setViewMode(StackedView::IconViewMode); // make sure the next/previous buttons are updated slotImageSelected(); } void DigikamView::slotImagePreview() { slotTogglePreviewMode(currentInfo()); } /** * @brief This method toggles between AlbumView/MapWidgetView and ImagePreview modes, depending on the context. */ void DigikamView::slotTogglePreviewMode(const ImageInfo& info) { if ( (viewMode() == StackedView::IconViewMode || viewMode() == StackedView::TableViewMode || viewMode() == StackedView::MapWidgetMode) && !info.isNull() ) { d->lastViewMode = viewMode(); if (viewMode() == StackedView::IconViewMode) { d->stackedview->setPreviewItem(info, d->iconView->previousInfo(info), d->iconView->nextInfo(info)); } else { d->stackedview->setPreviewItem(info, ImageInfo(), ImageInfo()); } } else { // go back to either AlbumViewMode or MapWidgetMode d->stackedview->setViewMode( d->lastViewMode ); } // make sure the next/previous buttons are updated slotImageSelected(); } void DigikamView::slotViewModeChanged() { toggleZoomActions(); switch (viewMode()) { case StackedView::IconViewMode: emit signalSwitchedToIconView(); emit signalThumbSizeChanged(d->iconView->thumbnailSize().size()); break; case StackedView::PreviewImageMode: emit signalSwitchedToPreview(); slotZoomFactorChanged(d->stackedview->zoomFactor()); break; case StackedView::WelcomePageMode: emit signalSwitchedToIconView(); break; case StackedView::MediaPlayerMode: emit signalSwitchedToPreview(); break; case StackedView::MapWidgetMode: emit signalSwitchedToMapView(); //TODO: connect map view's zoom buttons to main status bar zoom buttons break; case StackedView::TableViewMode: emit signalSwitchedToTableView(); emit signalThumbSizeChanged(d->tableView->getThumbnailSize().size()); break; } } void DigikamView::slotImageFindSimilar() { const ImageInfo current = currentInfo(); if (!current.isNull()) { d->fuzzySearchSideBar->newSimilarSearch(current); slotLeftSideBarActivate(d->fuzzySearchSideBar); } } void DigikamView::slotEditor() { const ImageInfoList imageInfoList = selectedInfoList(); ImageInfo singleInfo = currentInfo(); if (singleInfo.isNull() && !imageInfoList.isEmpty()) { singleInfo = imageInfoList.first(); } // the current album is the same for all views Album* const currentAlbum = d->iconView->currentAlbum(); - d->iconView->utilities()->openInEditor(singleInfo, imageInfoList, currentAlbum); + d->iconView->utilities()->openFile(singleInfo, imageInfoList, currentAlbum); } void DigikamView::slotLightTable() { const ImageInfoList allInfoList = allInfo(); const ImageInfoList selectedList = selectedInfoList(); const ImageInfo currentImageInfo = currentInfo(); d->iconView->utilities()->insertToLightTableAuto(allInfoList, selectedList, currentImageInfo); } void DigikamView::slotQueueMgr() { ImageInfoList imageInfoList = selectedInfoList(); ImageInfo singleInfo = currentInfo(); if (singleInfo.isNull() && !imageInfoList.isEmpty()) { singleInfo = imageInfoList.first(); } if (singleInfo.isNull()) { const ImageInfoList allItems = allInfo(); if (!allItems.isEmpty()) { singleInfo = allItems.first(); } } d->iconView->utilities()->insertToQueueManager(imageInfoList, singleInfo, true); } void DigikamView::slotImageEdit() { // Where is the difference to slotEditor? slotEditor(); } void DigikamView::slotImageLightTable() { const ImageInfoList selectedList = selectedInfoList(); const ImageInfo currentImageInfo = currentInfo(); // replace images in light table d->iconView->utilities()->insertToLightTable(selectedList, currentImageInfo, false); } void DigikamView::slotImageAddToLightTable() { const ImageInfoList selectedList = selectedInfoList(); const ImageInfo currentImageInfo = currentInfo(); // add to images in light table d->iconView->utilities()->insertToLightTable(selectedList, currentImageInfo, true); } void DigikamView::slotImageAddToCurrentQueue() { const ImageInfoList selectedList = selectedInfoList(); const ImageInfo currentImageInfo = currentInfo(); d->iconView->utilities()->insertToQueueManager(selectedList, currentImageInfo, false); } void DigikamView::slotImageAddToNewQueue() { const bool newQueue = QueueMgrWindow::queueManagerWindowCreated() && !QueueMgrWindow::queueManagerWindow()->queuesMap().isEmpty(); const ImageInfoList selectedList = selectedInfoList(); const ImageInfo currentImageInfo = currentInfo(); d->iconView->utilities()->insertToQueueManager(selectedList, currentImageInfo, newQueue); } void DigikamView::slotImageAddToExistingQueue(int queueid) { const ImageInfoList selectedList = selectedInfoList(); const ImageInfo currentImageInfo = currentInfo(); if (!selectedList.isEmpty()) { d->iconView->utilities()->insertSilentToQueueManager(selectedList, currentImageInfo, queueid); } } void DigikamView::slotImageRename() { d->iconView->rename(); } void DigikamView::slotImageDelete() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotDeleteSelected(ImageViewUtilities::DeleteUseTrash); break; default: d->iconView->deleteSelected(ImageViewUtilities::DeleteUseTrash); } } void DigikamView::slotImageDeletePermanently() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotDeleteSelected(ImageViewUtilities::DeletePermanently); break; default: d->iconView->deleteSelected(ImageViewUtilities::DeletePermanently); } } void DigikamView::slotImageDeletePermanentlyDirectly() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotDeleteSelectedWithoutConfirmation(ImageViewUtilities::DeletePermanently); break; default: d->iconView->deleteSelectedDirectly(ImageViewUtilities::DeletePermanently); } } void DigikamView::slotImageTrashDirectly() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotDeleteSelectedWithoutConfirmation(ImageViewUtilities::DeleteUseTrash); break; default: d->iconView->deleteSelectedDirectly(ImageViewUtilities::DeleteUseTrash); } } void DigikamView::slotSelectAll() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->selectAll(); break; default: d->iconView->selectAll(); } } void DigikamView::slotSelectNone() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->clearSelection(); break; default: d->iconView->clearSelection(); } } void DigikamView::slotSelectInvert() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->invertSelection(); break; default: d->iconView->invertSelection(); } } void DigikamView::slotSortImages(int sortRole) { AlbumSettings* const settings = AlbumSettings::instance(); if (!settings) { return; } settings->setImageSortOrder(sortRole); d->iconView->imageFilterModel()->setSortRole((ImageSortSettings::SortRole) sortRole); } void DigikamView::slotSortImagesOrder(int order) { AlbumSettings* const settings = AlbumSettings::instance(); if (!settings) { return; } settings->setImageSorting(order); d->iconView->imageFilterModel()->setSortOrder((ImageSortSettings::SortOrder) order); } void DigikamView::slotGroupImages(int categoryMode) { AlbumSettings* const settings = AlbumSettings::instance(); if (!settings) { return; } settings->setImageGroupMode(categoryMode); d->iconView->imageFilterModel()->setCategorizationMode((ImageSortSettings::CategorizationMode) categoryMode); } void DigikamView::slotSortImageGroupOrder(int order) { AlbumSettings* const settings = AlbumSettings::instance(); if (!settings) { return; } settings->setImageGroupSortOrder(order); d->iconView->imageFilterModel()->setCategorizationSortOrder((ImageSortSettings::SortOrder) order); } void DigikamView::slotMoveSelectionToAlbum() { d->iconView->createNewAlbumForSelected(); } void DigikamView::slotLeftSidebarChangedTab(QWidget* w) { // TODO update, temporary cast SidebarWidget* const widget = dynamic_cast(w); foreach(SidebarWidget* const sideBarWidget, d->leftSideBarWidgets) { bool active = (widget && (widget == sideBarWidget)); sideBarWidget->setActive(active); } } void DigikamView::toggleTag(int tagID) { ImageInfoList tagToRemove, tagToAssign; const ImageInfoList selectedList = selectedInfoList(); foreach(ImageInfo info, selectedList) { if (info.tagIds().contains(tagID)) tagToRemove.append(info); else tagToAssign.append(info); } FileActionMngr::instance()->assignTags(tagToAssign, QList() << tagID); FileActionMngr::instance()->removeTags(tagToRemove, QList() << tagID); } void DigikamView::slotAssignPickLabel(int pickId) { FileActionMngr::instance()->assignPickLabel(selectedInfoList(), pickId); } void DigikamView::slotAssignColorLabel(int colorId) { FileActionMngr::instance()->assignColorLabel(selectedInfoList(), colorId); } void DigikamView::slotAssignRating(int rating) { FileActionMngr::instance()->assignRating(selectedInfoList(), rating); } void DigikamView::slotSlideShowAll() { slideShow(allInfo()); } void DigikamView::slotSlideShowSelection() { slideShow(selectedInfoList()); } void DigikamView::slotSlideShowRecursive() { QList albumList = AlbumManager::instance()->currentAlbums(); Album* album = 0; if(!albumList.isEmpty()) { album = albumList.first(); } if (album) { SlideShowBuilder* const builder = new SlideShowBuilder(album); connect(builder, SIGNAL(signalComplete(SlideShowSettings)), this, SLOT(slotSlideShowBuilderComplete(SlideShowSettings))); } } void DigikamView::slideShow(const ImageInfoList& infoList) { SlideShowBuilder* const builder = new SlideShowBuilder(infoList); connect(builder, SIGNAL(signalComplete(SlideShowSettings)), this, SLOT(slotSlideShowBuilderComplete(SlideShowSettings))); } void DigikamView::slotSlideShowBuilderComplete(const SlideShowSettings& settings) { SlideShow* const slide = new SlideShow(settings); if (settings.startWithCurrent) { slide->setCurrent(currentUrl()); } connect(slide, SIGNAL(signalRatingChanged(KUrl,int)), this, SLOT(slotRatingChanged(KUrl,int))); connect(slide, SIGNAL(signalColorLabelChanged(KUrl,int)), this, SLOT(slotColorLabelChanged(KUrl,int))); connect(slide, SIGNAL(signalPickLabelChanged(KUrl,int)), this, SLOT(slotPickLabelChanged(KUrl,int))); slide->show(); } void DigikamView::toggleShowBar(bool b) { d->stackedview->thumbBarDock()->showThumbBar(b); // See B.K.O #319876 : force to reload current view mode to set thumbbar visibility properly. d->stackedview->setViewMode(viewMode()); } void DigikamView::setRecurseAlbums(bool recursive) { d->iconView->imageAlbumModel()->setRecurseAlbums(recursive); } void DigikamView::setRecurseTags(bool recursive) { d->iconView->imageAlbumModel()->setRecurseTags(recursive); } void DigikamView::slotSidebarTabTitleStyleChanged() { d->leftSideBar->setStyle(AlbumSettings::instance()->getSidebarTitleStyle()); d->rightSideBar->setStyle(AlbumSettings::instance()->getSidebarTitleStyle()); /// @todo Which settings actually have to be reloaded? // d->rightSideBar->applySettings(); } void DigikamView::slotImageChangeFailed(const QString& message, const QStringList& fileNames) { if (fileNames.isEmpty()) { return; } KMessageBox::errorList(0, message, fileNames); } void DigikamView::slotLeftSideBarActivateAlbums() { d->leftSideBar->setActiveTab(d->albumFolderSideBar); } void DigikamView::slotLeftSideBarActivateTags() { d->leftSideBar->setActiveTab(d->tagViewSideBar); } void DigikamView::slotLeftSideBarActivate(SidebarWidget* widget) { d->leftSideBar->setActiveTab(widget); } void DigikamView::slotLeftSideBarActivate(QWidget* widget) { slotLeftSideBarActivate(static_cast(widget)); } void DigikamView::slotRatingChanged(const KUrl& url, int rating) { rating = qMin(RatingMax, qMax(RatingMin, rating)); ImageInfo info(url); if (!info.isNull()) { MetadataHub hub; hub.load(info); hub.setRating(rating); hub.write(info, MetadataHub::PartialWrite); hub.write(info.filePath(), MetadataHub::FullWriteIfChanged); } } void DigikamView::slotColorLabelChanged(const KUrl& url, int color) { ImageInfo info(url); if (!info.isNull()) { MetadataHub hub; hub.load(info); hub.setColorLabel(color); hub.write(info, MetadataHub::PartialWrite); hub.write(info.filePath(), MetadataHub::FullWriteIfChanged); } } void DigikamView::slotPickLabelChanged(const KUrl& url, int pick) { ImageInfo info(url); if (!info.isNull()) { MetadataHub hub; hub.load(info); hub.setPickLabel(pick); hub.write(info, MetadataHub::PartialWrite); hub.write(info.filePath(), MetadataHub::FullWriteIfChanged); } } bool DigikamView::hasCurrentItem() const { return !currentInfo().isNull(); } void DigikamView::slotFocusAndNextImage() { //slot is called on pressing "return" a second time after assigning a tag d->stackedview->currentWidget()->setFocus(); //select next image, since the user is probably done tagging the current image d->iconView->toNextIndex(); } void DigikamView::slotImageExifOrientation(int orientation) { FileActionMngr::instance()->setExifOrientation(selectedInfoList(), orientation); } void DigikamView::imageTransform(RotationMatrix::TransformationAction transform) { FileActionMngr::instance()->transform(selectedInfoList(), transform); } ImageInfo DigikamView::currentInfo() const { switch (viewMode()) { case StackedView::TableViewMode: return d->tableView->currentInfo(); case StackedView::MapWidgetMode: return d->mapView->currentImageInfo(); case StackedView::MediaPlayerMode: case StackedView::PreviewImageMode: case StackedView::IconViewMode: // all of these modes use the same selection model and data as the IconViewMode return d->iconView->currentInfo(); default: return ImageInfo(); } } QList< ImageInfo > DigikamView::selectedInfoList(const bool currentFirst) const { switch (viewMode()) { case StackedView::TableViewMode: if (currentFirst) { return d->tableView->selectedImageInfosCurrentFirst(); } return d->tableView->selectedImageInfos(); case StackedView::PreviewImageMode: case StackedView::MediaPlayerMode: case StackedView::MapWidgetMode: case StackedView::IconViewMode: // all of these modes use the same selection model and data as the IconViewMode if (currentFirst) { return d->iconView->selectedImageInfosCurrentFirst(); } return d->iconView->selectedImageInfos(); default: return QList(); } } ImageInfoList DigikamView::allInfo() const { switch (viewMode()) { case StackedView::TableViewMode: return d->tableView->allInfo(); case StackedView::MapWidgetMode: case StackedView::PreviewImageMode: case StackedView::MediaPlayerMode: case StackedView::IconViewMode: // all of these modes use the same selection model and data as the IconViewMode return d->iconView->imageInfos(); default: return QList(); } } KUrl DigikamView::currentUrl() const { const ImageInfo cInfo = currentInfo(); return cInfo.fileUrl(); } void DigikamView::slotSetCurrentWhenAvailable(const qlonglong id) { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotSetCurrentWhenAvailable(id); break; default: d->iconView->setCurrentWhenAvailable(id); } } void DigikamView::slotAwayFromSelection() { switch (viewMode()) { case StackedView::TableViewMode: d->tableView->slotAwayFromSelection(); break; default: d->iconView->awayFromSelection(); } } StackedView::StackedViewMode DigikamView::viewMode() const { return d->stackedview->viewMode(); } void DigikamView::slotSetupMetadataFilters(int tab) { Setup::execMetadataFilters(this, tab); } void DigikamView::toggleFullScreen(bool set) { d->stackedview->imagePreviewView()->toggleFullScreen(set); } #ifdef USE_PRESENTATION_MODE void DigikamView::slotSlideShowQml() { /* QStringList list; foreach (const ImageInfo& info, d->iconView->imageInfos()) { list << info.filePath(); } */ SlideShowSettings settings; settings.readFromConfig(); QmlShow* const qmlShow = new QmlShow(allInfo(), settings); qmlShow->setWindowState(Qt::WindowFullScreen); qmlShow->show(); } #endif // USE_PRESENTATION_MODE } // namespace Digikam diff --git a/utilities/importui/views/importiconview.cpp b/utilities/importui/views/importiconview.cpp index 7220c382a9..0f47a93604 100644 --- a/utilities/importui/views/importiconview.cpp +++ b/utilities/importui/views/importiconview.cpp @@ -1,472 +1,472 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2012-22-07 * Description : Icon view for import tool items * * Copyright (C) 2012 by Islam Wazery * Copyright (C) 2012-2014 by Gilles Caulier * * This program is free software you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ #include "importiconview.moc" #include "importiconview_p.h" // Qt includes #include #include // KDE includes #include #include // Local includes #include "importcategorizedview.h" #include "importoverlays.h" #include "importsettings.h" #include "camitemsortsettings.h" #include "fileactionmngr.h" #include "importdelegate.h" #include "advancedrenamedialog.h" #include "advancedrenameprocessdialog.h" #include "imageviewutilities.h" #include "importcontextmenu.h" #include "importdragdrop.h" namespace Digikam { ImportIconView::ImportIconView(QWidget* const parent) : ImportCategorizedView(parent), d(new Private(this)) { } void ImportIconView::init() { d->normalDelegate = new ImportNormalDelegate(this); setItemDelegate(d->normalDelegate); setSpacing(10); ImportSettings* const settings = ImportSettings::instance(); setThumbnailSize((ThumbnailSize::Size)settings->getDefaultIconSize()); importImageModel()->setDragDropHandler(new ImportDragDropHandler(importImageModel())); setDragEnabled(true); setAcceptDrops(true); setDropIndicatorShown(false); setToolTipEnabled(settings->showToolTipsIsValid()); // selection overlay addSelectionOverlay(d->normalDelegate); //TODO: addSelectionOverlay(d->faceDelegate); // rotation overlays d->rotateLeftOverlay = ImportRotateOverlay::left(this); d->rotateRightOverlay = ImportRotateOverlay::right(this); addOverlay(new ImportDownloadOverlay(this)); addOverlay(new ImportLockOverlay(this)); addOverlay(new ImportCoordinatesOverlay(this)); d->updateOverlays(); // rating overlay ImportRatingOverlay* const ratingOverlay = new ImportRatingOverlay(this); addOverlay(ratingOverlay); //TODO: GroupIndicatorOverlay* groupOverlay = new GroupIndicatorOverlay(this); //TODO: addOverlay(groupOverlay); connect(ratingOverlay, SIGNAL(ratingEdited(QList,int)), this, SLOT(assignRating(QList,int))); //TODO: connect(groupOverlay, SIGNAL(toggleGroupOpen(QModelIndex)), //this, SLOT(groupIndicatorClicked(QModelIndex))); //TODO: connect(groupOverlay, SIGNAL(showButtonContextMenu(QModelIndex,QContextMenuEvent*)), //this, SLOT(showGroupContextMenu(QModelIndex,QContextMenuEvent*))); //TODO: connect(importImageModel()->dragDropHandler(), SIGNAL(assignTags(QList,QList)), //FileActionMngr::instance(), SLOT(assignTags(QList,QList))); //TODO: connect(importImageModel()->dragDropHandler(), SIGNAL(addToGroup(CamItemInfo,QList)), //FileActionMngr::instance(), SLOT(addToGroup(CamItemInfo,QList))); connect(settings, SIGNAL(setupChanged()), this, SLOT(slotSetupChanged())); slotSetupChanged(); } ImportIconView::~ImportIconView() { delete d; } ImageViewUtilities* ImportIconView::utilities() const { return d->utilities; } void ImportIconView::setThumbnailSize(const ThumbnailSize& size) { ImportCategorizedView::setThumbnailSize(size); } int ImportIconView::fitToWidthIcons() { return delegate()->calculatethumbSizeToFit(viewport()->size().width()); } CamItemInfo ImportIconView::camItemInfo(const QString& folder, const QString& file) { KUrl url(folder); url.adjustPath(KUrl::AddTrailingSlash); url.setFileName(file); QModelIndex indexForCamItemInfo = importFilterModel()->indexForPath(url.toLocalFile()); if(indexForCamItemInfo.isValid()) { return importFilterModel()->camItemInfo(indexForCamItemInfo); } return CamItemInfo(); } CamItemInfo& ImportIconView::camItemInfoRef(const QString& folder, const QString& file) { KUrl url(folder); url.adjustPath(KUrl::AddTrailingSlash); url.setFileName(file); QModelIndex indexForCamItemInfo = importFilterModel()->indexForPath(url.toLocalFile()); QModelIndex mappedIndex = importFilterModel()->mapToSource(indexForCamItemInfo); return importImageModel()->camItemInfoRef(mappedIndex); } void ImportIconView::slotSetupChanged() { setToolTipEnabled(ImportSettings::instance()->showToolTipsIsValid()); setFont(ImportSettings::instance()->getIconViewFont()); d->updateOverlays(); ImportCategorizedView::slotSetupChanged(); } void ImportIconView::rename() { KUrl::List urls = selectedUrls(); NewNamesList newNamesList; QPointer dlg = new AdvancedRenameDialog(this); dlg->slotAddImages(urls); if (dlg->exec() == KDialog::Accepted) { newNamesList = dlg->newNames(); } delete dlg; if (!newNamesList.isEmpty()) { QPointer dlg = new AdvancedRenameProcessDialog(newNamesList); dlg->exec(); delete dlg; } } void ImportIconView::deleteSelected(bool /*permanently*/) { CamItemInfoList camItemInfoList = selectedCamItemInfos(); //FIXME: This way of deletion may not working with camera items. //if (d->utilities->deleteImages(camItemInfoList, permanently)) //{ // awayFromSelection(); //} } void ImportIconView::deleteSelectedDirectly(bool /*permanently*/) { CamItemInfoList camItemInfoList = selectedCamItemInfos(); //FIXME: This way of deletion may not working with camera items. //d->utilities->deleteImagesDirectly(camItemInfoList, permanently); awayFromSelection(); } void ImportIconView::createGroupFromSelection() { //TODO: Impelemnt grouping in import tool. //QList selectedInfos = selectedCamItemInfosCurrentFirst(); //CamItemInfo groupLeader = selectedInfos.takeFirst(); //FileActionMngr::instance()->addToGroup(groupLeader, selectedInfos); } void ImportIconView::createGroupByTimeFromSelection() { //TODO: Impelemnt grouping in import tool. //QList selectedInfos = selectedCamItemInfosCurrentFirst(); //while (selectedInfos.size() > 0) //{ //QList group; //CamItemInfo groupLeader = selectedInfos.takeFirst(); //QDateTime dateTime = groupLeader.dateTime(); //while (selectedInfos.size() > 0 && abs(dateTime.secsTo(selectedInfos.first().dateTime())) < 2) //{ // group.push_back(selectedInfos.takeFirst()); //} //FileActionMngr::instance()->addToGroup(groupLeader, group); //} } void ImportIconView::ungroupSelected() { //TODO: Impelemnt grouping in import tool. //FileActionMngr::instance()->ungroup(selectedCamItemInfos()); } void ImportIconView::removeSelectedFromGroup() { //TODO: Impelemnt grouping in import tool. //FileActionMngr::instance()->removeFromGroup(selectedCamItemInfos()); } void ImportIconView::slotRotateLeft(const QList& indexes) { QList imageInfos; foreach(const QModelIndex& index, indexes) { ImageInfo imageInfo(importFilterModel()->camItemInfo(index).url()); imageInfos << imageInfo; } FileActionMngr::instance()->transform(imageInfos, KExiv2Iface::RotationMatrix::Rotate270); } void ImportIconView::slotRotateRight(const QList& indexes) { QList imageInfos; foreach(const QModelIndex& index, indexes) { ImageInfo imageInfo(importFilterModel()->camItemInfo(index).url()); imageInfos << imageInfo; } FileActionMngr::instance()->transform(imageInfos, KExiv2Iface::RotationMatrix::Rotate90); } void ImportIconView::activated(const CamItemInfo& info) { if (info.isNull()) { return; } if (ImportSettings::instance()->getItemLeftClickAction() == ImportSettings::ShowPreview) { emit previewRequested(info, false); } else { - //TODO: openInEditor(info); + //TODO: openFile(info); } } void ImportIconView::showContextMenuOnInfo(QContextMenuEvent* event, const CamItemInfo& /*info*/) { QList selectedInfos = selectedCamItemInfosCurrentFirst(); QList selectedItemIDs; foreach(const CamItemInfo& info, selectedInfos) { selectedItemIDs << info.id; } // -------------------------------------------------------- KMenu popmenu(this); ImportContextMenuHelper cmhelper(&popmenu); cmhelper.addAction("importui_fullscreen"); cmhelper.addAction("options_show_menubar"); cmhelper.addAction("import_zoomfit2window"); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addAction("importui_imagedownload"); cmhelper.addAction("importui_imagemarkasdownloaded"); cmhelper.addAction("importui_imagelock"); cmhelper.addAction("importui_delete"); cmhelper.addSeparator(); cmhelper.addAction("importui_item_view"); cmhelper.addServicesMenu(selectedUrls()); //TODO: cmhelper.addRotateMenu(selectedItemIDs); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addAction("importui_selectall"); cmhelper.addAction("importui_selectnone"); cmhelper.addAction("importui_selectinvert"); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addAssignTagsMenu(selectedItemIDs); cmhelper.addRemoveTagsMenu(selectedItemIDs); cmhelper.addSeparator(); // -------------------------------------------------------- cmhelper.addLabelsAction(); //if (!d->faceMode) //{ // cmhelper.addGroupMenu(selectedItemIDs); //} // special action handling -------------------------------- connect(&cmhelper, SIGNAL(signalAssignTag(int)), this, SLOT(assignTagToSelected(int))); //TODO: Implement tag view for import tool. connect(&cmhelper, SIGNAL(signalPopupTagsView()), this, SIGNAL(signalPopupTagsView())); connect(&cmhelper, SIGNAL(signalRemoveTag(int)), this, SLOT(removeTagFromSelected(int))); //connect(&cmhelper, SIGNAL(signalGotoTag(int)), //this, SIGNAL(gotoTagAndImageRequested(int))); connect(&cmhelper, SIGNAL(signalAssignPickLabel(int)), this, SLOT(assignPickLabelToSelected(int))); connect(&cmhelper, SIGNAL(signalAssignColorLabel(int)), this, SLOT(assignColorLabelToSelected(int))); connect(&cmhelper, SIGNAL(signalAssignRating(int)), this, SLOT(assignRatingToSelected(int))); //connect(&cmhelper, SIGNAL(signalAddToExistingQueue(int)), //this, SLOT(insertSelectedToExistingQueue(int))); //FIXME: connect(&cmhelper, SIGNAL(signalCreateGroup()), //this, SLOT(createGroupFromSelection())); //connect(&cmhelper, SIGNAL(signalUngroup()), //this, SLOT(ungroupSelected())); //connect(&cmhelper, SIGNAL(signalRemoveFromGroup()), //this, SLOT(removeSelectedFromGroup())); // -------------------------------------------------------- cmhelper.exec(event->globalPos()); } void ImportIconView::showContextMenu(QContextMenuEvent* event) { KMenu popmenu(this); ImportContextMenuHelper cmhelper(&popmenu); cmhelper.addAction("importui_fullscreen"); cmhelper.addAction("options_show_menubar"); cmhelper.addSeparator(); cmhelper.addAction("importui_close"); // -------------------------------------------------------- cmhelper.exec(event->globalPos()); } void ImportIconView::assignTagToSelected(int tagID) { CamItemInfoList infos = selectedCamItemInfos(); foreach(const CamItemInfo& info, infos) { importImageModel()->camItemInfoRef(importImageModel()->indexForCamItemInfo(info)).tagIds.append(tagID); } } void ImportIconView::removeTagFromSelected(int tagID) { CamItemInfoList infos = selectedCamItemInfos(); foreach(const CamItemInfo& info, infos) { importImageModel()->camItemInfoRef(importImageModel()->indexForCamItemInfo(info)).tagIds.removeAll(tagID); } } void ImportIconView::assignPickLabel(const QModelIndex& index, int pickId) { importImageModel()->camItemInfoRef(index).pickLabel = pickId; } void ImportIconView::assignPickLabelToSelected(int pickId) { CamItemInfoList infos = selectedCamItemInfos(); foreach(const CamItemInfo& info, infos) { importImageModel()->camItemInfoRef(importImageModel()->indexForCamItemInfo(info)).pickLabel = pickId; } } void ImportIconView::assignColorLabel(const QModelIndex& index, int colorId) { importImageModel()->camItemInfoRef(index).colorLabel = colorId; } void ImportIconView::assignColorLabelToSelected(int colorId) { CamItemInfoList infos = selectedCamItemInfos(); foreach(const CamItemInfo& info, infos) { importImageModel()->camItemInfoRef(importImageModel()->indexForCamItemInfo(info)).colorLabel = colorId; } } void ImportIconView::assignRating(const QList& indexes, int rating) { foreach(const QModelIndex& index, indexes) { if (index.isValid()) { importImageModel()->camItemInfoRef(index).rating = rating; } } } void ImportIconView::assignRatingToSelected(int rating) { CamItemInfoList infos = selectedCamItemInfos(); foreach(const CamItemInfo& info, infos) { importImageModel()->camItemInfoRef(importImageModel()->indexForCamItemInfo(info)).rating = rating; } } } // namespace Digikam