diff --git a/core/app/CMakeLists.txt b/core/app/CMakeLists.txt index 4e5ba8c62d..8613467ba6 100644 --- a/core/app/CMakeLists.txt +++ b/core/app/CMakeLists.txt @@ -1,586 +1,586 @@ # # Copyright (c) 2010-2018 by Gilles Caulier, # Copyright (c) 2015 by Veaceslav Munteanu, # # Redistribution and use is allowed according to the terms of the BSD license. # For details see the accompanying COPYING-CMAKE-SCRIPTS file. if (POLICY CMP0063) cmake_policy(SET CMP0063 NEW) endif (POLICY CMP0063) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utils/digikam_version.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/utils/digikam_version.h) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utils/digikam_dbconfig.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/utils/digikam_dbconfig.h) # digikam core set(DIGIKAMCORE_OBJECTS $ $ $ $ $ $ $ $ $ $ $ $ $ # widgets $ $ $ $ $ # utilities $ $ $ $ $ $ $ $ $ $ $ $ $ utils/digikam_debug.cpp ) if(Marble_FOUND) set(DIGIKAMCORE_OBJECTS ${DIGIKAMCORE_OBJECTS} $ $ $ ) endif() if(KF5AkonadiContact_FOUND) set(DIGIKAMCORE_OBJECTS ${DIGIKAMCORE_OBJECTS} $ ) endif() if(KF5Sane_FOUND) set(DIGIKAMCORE_OBJECTS ${DIGIKAMCORE_OBJECTS} $ ) endif() if(FLEX_FOUND AND BISON_FOUND AND KF5ThreadWeaver_FOUND) set(DIGIKAMCORE_OBJECTS ${DIGIKAMCORE_OBJECTS} $ ) endif() if(LibXml2_FOUND AND LibXslt_FOUND) set(DIGIKAMCORE_OBJECTS ${DIGIKAMCORE_OBJECTS} $ ) endif() if(ENABLE_MEDIAPLAYER) set(DIGIKAMCORE_OBJECTS ${DIGIKAMCORE_OBJECTS} $ ) endif() include_directories($ $ $ $ $ $ $ $ $ $ $ $ $) if(ENABLE_QWEBENGINE) include_directories($) else() include_directories($) endif() if(KF5KIO_FOUND) include_directories($) endif() if(HAVE_OPENGL) include_directories($) endif() if(Gphoto2_FOUND) include_directories(${GPHOTO2_INCLUDE_DIRS}) endif() add_library(digikamcore SHARED ${DIGIKAMCORE_OBJECTS} ) add_dependencies(digikamcore digikam-gitversion) generate_export_header(digikamcore BASE_NAME digikam EXPORT_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/utils/digikam_core_export.h") target_link_libraries(digikamcore PUBLIC Qt5::Core Qt5::Gui Qt5::Xml Qt5::XmlPatterns Qt5::Widgets Qt5::Sql Qt5::PrintSupport Qt5::Concurrent KF5::Solid KF5::WindowSystem KF5::ConfigGui KF5::CoreAddons KF5::Service KF5::XmlGui KF5::I18n # Required by CImg which use pthread internally. ${CMAKE_THREAD_LIBS_INIT} ${LCMS2_LIBRARIES} # filters ${TIFF_LIBRARIES} PNG::PNG ${JPEG_LIBRARIES} ${EXIV2_LIBRARIES} ${FFMPEG_LIBRARIES} ${OPENMP_LDFLAGS} libdng ) if(ENABLE_QWEBENGINE) target_link_libraries(digikamcore PUBLIC Qt5::WebEngineWidgets) else() target_link_libraries(digikamcore PUBLIC Qt5::WebKitWidgets) endif() if(ENABLE_DBUS) target_link_libraries(digikamcore PUBLIC Qt5::DBus) endif() if(KF5IconThemes_FOUND) target_link_libraries(digikamcore PUBLIC KF5::IconThemes) endif() if(KF5KIO_FOUND) target_link_libraries(digikamcore PUBLIC KF5::KIOCore) target_link_libraries(digikamcore PUBLIC KF5::KIOWidgets) endif() if(KF5Notifications_FOUND) target_link_libraries(digikamcore PUBLIC KF5::Notifications) endif() if(KF5NotifyConfig_FOUND) target_link_libraries(digikamcore PUBLIC KF5::NotifyConfig) endif() if(Marble_FOUND) target_link_libraries(digikamcore PUBLIC ${MARBLE_LIBRARIES}) endif() if(X11_FOUND) target_link_libraries(digikamcore PUBLIC Qt5::X11Extras ${X11_LIBRARIES}) endif() if(Jasper_FOUND) target_link_libraries(digikamcore PUBLIC ${JASPER_LIBRARIES}) endif() # LibLqr-1 library rules for content-aware filter if(Lqr-1_FOUND) target_link_libraries(digikamcore PRIVATE ${LQR-1_LIBRARIES}) endif() if(LensFun_FOUND) target_include_directories(digikamcore PUBLIC ${LENSFUN_INCLUDE_DIRS}) target_link_libraries(digikamcore PUBLIC ${LENSFUN_LIBRARIES}) endif() # for nrfilter if(OpenCV_FOUND) target_link_libraries(digikamcore PRIVATE ${OpenCV_LIBRARIES}) endif() if(KF5FileMetaData_FOUND) target_link_libraries(digikamcore PUBLIC baloowrap) endif() if(HAVE_OPENGL) target_link_libraries(digikamcore PUBLIC Qt5::OpenGL ${OPENGL_LIBRARIES} ) endif() if(KF5Sane_FOUND) target_link_libraries(digikamcore PUBLIC KF5::Sane) endif() if(KF5AkonadiContact_FOUND) target_link_libraries(digikamcore PUBLIC KF5::AkonadiContact) endif() if(KF5CalendarCore_FOUND) target_link_libraries(digikamcore PUBLIC KF5::CalendarCore) endif() if(FLEX_FOUND AND BISON_FOUND AND KF5ThreadWeaver_FOUND) target_link_libraries(digikamcore PUBLIC KF5::ThreadWeaver) endif() if(LibXml2_FOUND AND LibXslt_FOUND) target_link_libraries(digikamcore PUBLIC ${LIBXSLT_EXSLT_LIBRARIES} ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES}) endif() if(KF5Vkontakte_FOUND) target_link_libraries(digikamcore PUBLIC KF5::Vkontakte) endif() if(APPLE) target_link_libraries(digikamcore PUBLIC /System/Library/Frameworks/AppKit.framework) endif() if(WIN32) target_link_libraries(digikamcore PUBLIC wsock32 ws2_32) endif() if(ENABLE_MEDIAPLAYER) target_link_libraries(digikamcore PUBLIC ${QTAV_LIBRARIES}) endif() set_target_properties(digikamcore PROPERTIES VERSION ${DIGIKAM_VERSION_SHORT} SOVERSION ${DIGIKAM_VERSION_SHORT}) install(TARGETS digikamcore ${INSTALL_TARGETS_DEFAULT_ARGS}) ########################## digiKam GUI sources ############################# if(ENABLE_DBUS) qt5_add_dbus_adaptor(digikamadaptor_SRCS main/org.kde.digikam.xml main/digikamapp.h Digikam::DigikamApp) endif() set(libdigikamgui_SRCS main/digikamapp.cpp main/digikamapp_solid.cpp main/digikamapp_camera.cpp main/digikamapp_import.cpp main/digikamapp_export.cpp main/digikamapp_config.cpp main/digikamapp_tools.cpp main/digikamapp_setup.cpp date/dpopupframe.cpp date/ddateedit.cpp date/ddatetable.cpp date/ddatetable_p.cpp date/ddatepicker.cpp date/ddatepicker_p.cpp date/ddatetimeedit.cpp date/ddatepickerpopup.cpp date/datefolderview.cpp date/monthwidget.cpp date/timelinewidget.cpp dragdrop/importdragdrop.cpp dragdrop/albumdragdrop.cpp dragdrop/ddragobjects.cpp dragdrop/itemdragdrop.cpp dragdrop/tagdragdrop.cpp filters/filtersidebarwidget.cpp filters/tagfilterview.cpp items/digikamimageview.cpp items/digikamimageview_p.cpp items/digikamimagedelegate.cpp - items/digikamimagefacedelegate.cpp items/imagecategorizedview.cpp items/imagecategorydrawer.cpp items/imagedelegate.cpp + items/itemfacedelegate.cpp items/thumbbar/itemthumbnailbar.cpp items/thumbbar/itemthumbnaildelegate.cpp items/overlays/assignnameoverlay.cpp items/overlays/facerejectionoverlay.cpp items/overlays/groupindicatoroverlay.cpp items/overlays/itemfullscreenoverlay.cpp items/overlays/itemratingoverlay.cpp items/overlays/itemrotationoverlay.cpp items/overlays/itemcoordinatesoverlay.cpp items/overlays/itemselectionoverlay.cpp items/utils/itemviewutilities.cpp items/utils/tooltipfiller.cpp utils/contextmenuhelper.cpp utils/digikam_debug.cpp utils/componentsinfo.cpp utils/groupingviewimplementation.cpp views/tableview/tableview.cpp views/tableview/tableview_treeview.cpp views/tableview/tableview_treeview_delegate.cpp views/tableview/tableview_column_configuration_dialog.cpp views/tableview/tableview_model.cpp views/tableview/tableview_columns.cpp views/tableview/tableview_column_audiovideo.cpp views/tableview/tableview_column_file.cpp views/tableview/tableview_column_geo.cpp views/tableview/tableview_column_digikam.cpp views/tableview/tableview_column_item.cpp views/tableview/tableview_column_photo.cpp views/tableview/tableview_column_thumbnail.cpp views/tableview/tableview_columnfactory.cpp views/tableview/tableview_selection_model_syncer.cpp views/imagepreviewviewitem.cpp views/imagepreviewview.cpp views/welcomepageview.cpp views/leftsidebarwidgets.cpp views/digikamview.cpp views/trashview.cpp views/stackedview.cpp views/sidebarwidget.cpp views/digikammodelcollection.cpp views/slideshowbuilder.cpp ${digikamadaptor_SRCS} ) if(${Marble_FOUND}) set(libdigikamgui_SRCS ${libdigikamgui_SRCS} views/mapwidgetview.cpp ) endif() add_library(digikamgui_src OBJECT ${libdigikamgui_SRCS} ) ######################### digiKam GUI objects ############################ set(DIGIKAM_OBJECTS $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ ) if(${Marble_FOUND}) set(DIGIKAM_OBJECTS ${DIGIKAM_OBJECTS} $ $ ) endif() #################### Digikam GUI shared Lib ################################ add_library(digikamgui SHARED ${DIGIKAM_OBJECTS} ) target_link_libraries(digikamgui PUBLIC digikamdatabase digikamcore Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Sql Qt5::PrintSupport KF5::Solid KF5::Service KF5::WindowSystem KF5::I18n ${OpenCV_LIBRARIES} ) if(ENABLE_QWEBENGINE) target_link_libraries(digikamgui PUBLIC Qt5::WebEngineWidgets) else() target_link_libraries(digikamgui PUBLIC Qt5::WebKitWidgets) endif() if(ENABLE_DBUS) target_link_libraries(digikamgui PUBLIC Qt5::DBus) endif() if(KF5IconThemes_FOUND) target_link_libraries(digikamgui PUBLIC KF5::IconThemes) endif() if(KF5KIO_FOUND) target_link_libraries(digikamgui PUBLIC KF5::KIOWidgets) endif() if(${Marble_FOUND}) target_link_libraries(digikamgui PUBLIC ${MARBLE_LIBRARIES}) endif() if(APPLE) target_link_libraries(digikamgui PRIVATE /System/Library/Frameworks/AppKit.framework) endif() if(HAVE_OPENGL) target_link_libraries(digikamgui PUBLIC Qt5::OpenGL ${OPENGL_LIBRARIES} ) endif() if(NOT WIN32) # To link under Solaris (see bug #274484) target_link_libraries(digikamgui PUBLIC ${MATH_LIBRARY}) endif() if(WIN32) set_target_properties(digikamgui PROPERTIES COMPILE_FLAGS -DJPEG_STATIC) endif() if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD) target_link_libraries(digikamcore PRIVATE ${KVM_LIBRARY}) endif() if(Gphoto2_FOUND) # See bug #258931: libgphoto2 library must be the last arg for linker. # See bug #268267 : digiKam need to be linked to libusb to prevent crash # at gphoto2 init if opencv is linked with libdc1394. Libusb linking rules are # add to gphoto2 linking rules by Gphoto2 cmake detection script. target_link_libraries(digikamgui PUBLIC ${GPHOTO2_LIBRARIES}) endif() set_target_properties(digikamgui PROPERTIES VERSION ${DIGIKAM_VERSION_SHORT} SOVERSION ${DIGIKAM_VERSION_SHORT}) install(TARGETS digikamgui ${INSTALL_TARGETS_DEFAULT_ARGS}) #################### digiKam Executable #################################### set(digikam_SRCS main/main.cpp ) # this is only required by Win & OSX file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/../data/icons/apps/*-apps-digikam.png") ecm_add_app_icon(digikam_SRCS ICONS ${ICONS_SRCS}) add_executable(digikam ${digikam_SRCS}) add_dependencies(digikam digikam-gitversion) # To fill plist XML file for OSX ############ set(MACOSX_APP_NAME_STRING "digikam") set(MACOSX_APP_DESCRIPTION "Advanced digital photo management application") set(MACOSX_BUNDLE_LONG_VERSION_STRING ${DIGIKAM_VERSION_STRING}) set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${DIGIKAM_VERSION_SHORT}) set(MACOSX_BUNDLE_BUNDLE_VERSION ${DIGIKAM_VERSION_STRING}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/templates/Info.plist.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) set_target_properties(digikam PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist) target_link_libraries(digikam PUBLIC digikamcore digikamgui libdng Qt5::Core Qt5::Gui Qt5::Widgets KF5::WindowSystem KF5::I18n ) if(ENABLE_DBUS) target_link_libraries(digikam PUBLIC Qt5::DBus) endif() if(KF5IconThemes_FOUND) target_link_libraries(digikam PUBLIC KF5::IconThemes) endif() if(KF5KIO_FOUND) target_link_libraries(digikam PUBLIC KF5::KIOWidgets) endif() install(TARGETS digikam ${INSTALL_TARGETS_DEFAULT_ARGS}) # Others Files to install ####################################################### install(PROGRAMS main/org.kde.digikam.desktop DESTINATION ${XDG_APPS_INSTALL_DIR}) install(FILES main/org.kde.digikam.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install(FILES main/digikamui5.rc DESTINATION ${KXMLGUI_INSTALL_DIR}/digikam) install(FILES main/digikam.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR}) diff --git a/core/app/items/digikamimagedelegatepriv.h b/core/app/items/digikamimagedelegatepriv.h index 2d2e685e85..966fc8b6d8 100644 --- a/core/app/items/digikamimagedelegatepriv.h +++ b/core/app/items/digikamimagedelegatepriv.h @@ -1,67 +1,67 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-04-19 * Description : Qt item view for images - the delegate * * Copyright (C) 2002-2005 by Renchi Raju * Copyright (C) 2002-2018 by Gilles Caulier * Copyright (C) 2009-2011 by Andi Clemens * Copyright (C) 2006-2011 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 DIGIKAM_IMAGE_DELEGATE_PRIVATE_H #define DIGIKAM_IMAGE_DELEGATE_PRIVATE_H // Qt includes #include // Local includes #include "imagedelegatepriv.h" namespace Digikam { class Q_DECL_HIDDEN DigikamImageDelegatePrivate : public ImageDelegate::ImageDelegatePrivate { public: explicit DigikamImageDelegatePrivate() { } virtual ~DigikamImageDelegatePrivate(); void init(DigikamImageDelegate* const q, ImageCategorizedView* const parent); }; // ----------------------------------------------------------------------------------------- -class Q_DECL_HIDDEN DigikamImageFaceDelegatePrivate : public DigikamImageDelegatePrivate +class Q_DECL_HIDDEN ItemFaceDelegatePrivate : public DigikamImageDelegatePrivate { public: - explicit DigikamImageFaceDelegatePrivate() + explicit ItemFaceDelegatePrivate() { } }; } // namespace Digikam #endif // DIGIKAM_IMAGE_DELEGATE_PRIVATE_H diff --git a/core/app/items/digikamimageview.cpp b/core/app/items/digikamimageview.cpp index a4e8a933e1..c79e53b10e 100644 --- a/core/app/items/digikamimageview.cpp +++ b/core/app/items/digikamimageview.cpp @@ -1,600 +1,600 @@ /* ============================================================ * * 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-2018 by Gilles Caulier * Copyright (C) 2011 by Andi Clemens * Copyright (C) 2013 by Michael G. Hansen * Copyright (C) 2014 by Mohamed_Anwer * Copyright (C) 2017 by Simon Frei * * 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.h" #include "digikamimageview_p.h" // Qt includes #include #include #include #include #include #include // Local includes #include "digikam_debug.h" #include "albummanager.h" #include "coredb.h" #include "coredboperationgroup.h" #include "advancedrenamedialog.h" #include "advancedrenameprocessdialog.h" #include "applicationsettings.h" #include "assignnameoverlay.h" #include "contextmenuhelper.h" #include "coredbaccess.h" #include "ddragobjects.h" #include "digikamapp.h" #include "digikamimagedelegate.h" -#include "digikamimagefacedelegate.h" +#include "itemfacedelegate.h" #include "dio.h" #include "groupindicatoroverlay.h" #include "itemalbumfiltermodel.h" #include "itemalbummodel.h" #include "itemdragdrop.h" #include "itemratingoverlay.h" #include "itemfullscreenoverlay.h" #include "itemcoordinatesoverlay.h" #include "tagslineeditoverlay.h" #include "itemviewutilities.h" #include "imagewindow.h" #include "fileactionmngr.h" #include "fileactionprogress.h" #include "thumbnailloadthread.h" #include "tagregion.h" #include "addtagslineedit.h" #include "facerejectionoverlay.h" #include "facetagsiface.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); + d->faceDelegate = new ItemFaceDelegate(this); setItemDelegate(d->normalDelegate); setSpacing(10); ApplicationSettings* const settings = ApplicationSettings::instance(); imageFilterModel()->setCategorizationMode(ItemSortSettings::CategoryByAlbum); imageAlbumModel()->setThumbnailLoadThread(ThumbnailLoadThread::defaultIconViewThread()); setThumbnailSize(ThumbnailSize(settings->getDefaultIconSize())); imageAlbumModel()->setPreloadThumbnails(true); imageModel()->setDragDropHandler(new ItemDragDropHandler(imageModel())); setDragEnabled(true); setAcceptDrops(true); setDropIndicatorShown(false); setToolTipEnabled(settings->showToolTipsIsValid()); imageFilterModel()->setStringTypeNatural(settings->isStringTypeNatural()); imageFilterModel()->setSortRole((ItemSortSettings::SortRole)settings->getImageSortOrder()); imageFilterModel()->setSortOrder((ItemSortSettings::SortOrder)settings->getImageSorting()); imageFilterModel()->setCategorizationMode((ItemSortSettings::CategorizationMode)settings->getImageSeparationMode()); imageFilterModel()->setCategorizationSortOrder((ItemSortSettings::SortOrder) settings->getImageSeparationSortOrder()); // selection overlay addSelectionOverlay(d->normalDelegate); addSelectionOverlay(d->faceDelegate); // rotation overlays d->rotateLeftOverlay = ItemRotateOverlay::left(this); d->rotateRightOverlay = ItemRotateOverlay::right(this); d->fullscreenOverlay = ItemFullScreenOverlay::instance(this); d->updateOverlays(); // rating overlay ItemRatingOverlay* const ratingOverlay = new ItemRatingOverlay(this); addOverlay(ratingOverlay); // face overlays // NOTE: order to plug this overlay is important, else rejection cant be suitable (see bug #324759). addAssignNameOverlay(d->faceDelegate); addRejectionOverlay(d->faceDelegate); GroupIndicatorOverlay* const groupOverlay = new GroupIndicatorOverlay(this); addOverlay(groupOverlay); addOverlay(new ItemCoordinatesOverlay(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 ItemViewUtilities(this); connect(imageModel()->dragDropHandler(), SIGNAL(assignTags(QList,QList)), FileActionMngr::instance(), SLOT(assignTags(QList,QList))); connect(imageModel()->dragDropHandler(), SIGNAL(addToGroup(ItemInfo,QList)), FileActionMngr::instance(), SLOT(addToGroup(ItemInfo,QList))); connect(imageModel()->dragDropHandler(), SIGNAL(dragDropSort(ItemInfo,QList)), this, SLOT(dragDropSort(ItemInfo,QList))); connect(d->utilities, SIGNAL(editorCurrentUrlChanged(QUrl)), this, SLOT(setCurrentUrlWhenAvailable(QUrl))); connect(settings, SIGNAL(setupChanged()), this, SLOT(slotSetupChanged())); slotSetupChanged(); } DigikamImageView::~DigikamImageView() { delete d; } ItemViewUtilities* DigikamImageView::utilities() const { return d->utilities; } void DigikamImageView::setThumbnailSize(const ThumbnailSize& size) { imageThumbnailModel()->setPreloadThumbnailSize(size); ImageCategorizedView::setThumbnailSize(size); } ItemInfoList DigikamImageView::allItemInfos(bool grouping) const { if (grouping) { return resolveGrouping(ImageCategorizedView::allItemInfos()); } return ImageCategorizedView::allItemInfos(); } ItemInfoList DigikamImageView::selectedItemInfos(bool grouping) const { if (grouping) { return resolveGrouping(ImageCategorizedView::selectedItemInfos()); } return ImageCategorizedView::selectedItemInfos(); } ItemInfoList DigikamImageView::selectedItemInfosCurrentFirst(bool grouping) const { if (grouping) { return resolveGrouping(ImageCategorizedView::selectedItemInfosCurrentFirst()); } return ImageCategorizedView::selectedItemInfosCurrentFirst(); } void DigikamImageView::dragDropSort(const ItemInfo& pick, const QList& infos) { if (pick.isNull() || infos.isEmpty()) { return; } ItemInfoList infoList = allItemInfos(false); qlonglong counter = pick.manualOrder(); bool order = (ApplicationSettings::instance()-> getImageSorting() == Qt::AscendingOrder); bool found = false; QApplication::setOverrideCursor(Qt::WaitCursor); CoreDbOperationGroup group; group.setMaximumTime(200); foreach (ItemInfo info, infoList) { if (!found && info.id() == pick.id()) { foreach (ItemInfo dropInfo, infos) { dropInfo.setManualOrder(counter); counter += (order ? 1 : -1); } info.setManualOrder(counter); found = true; } else if (found && !infos.contains(info)) { if (( order && info.manualOrder() > counter) || (!order && info.manualOrder() < counter)) { break; } counter += (order ? 100 : -100); info.setManualOrder(counter); } group.allowLift(); } QApplication::restoreOverrideCursor(); imageFilterModel()->invalidate(); } bool DigikamImageView::allNeedGroupResolving(const ApplicationSettings::OperationType type) const { return needGroupResolving(type, allItemInfos()); } bool DigikamImageView::selectedNeedGroupResolving(const ApplicationSettings::OperationType type) const { return needGroupResolving(type, selectedItemInfos()); } int DigikamImageView::fitToWidthIcons() { return delegate()->calculatethumbSizeToFit(viewport()->size().width()); } void DigikamImageView::slotSetupChanged() { imageFilterModel()->setStringTypeNatural(ApplicationSettings::instance()->isStringTypeNatural()); setToolTipEnabled(ApplicationSettings::instance()->showToolTipsIsValid()); setFont(ApplicationSettings::instance()->getIconViewFont()); d->updateOverlays(); ImageCategorizedView::slotSetupChanged(); } bool DigikamImageView::hasHiddenGroupedImages(const ItemInfo& info) const { return info.hasGroupedImages() && !imageFilterModel()->isGroupOpen(info.id()); } ItemInfoList DigikamImageView::imageInfos(const QList& indexes, ApplicationSettings::OperationType type) const { ItemInfoList infos = ImageCategorizedView::imageInfos(indexes); if (needGroupResolving(type, infos)) { return resolveGrouping(infos); } return infos; } void DigikamImageView::setFaceMode(bool on) { d->faceMode = on; if (on) { // See ItemLister, which creates a search the implements listing tag in the ioslave imageAlbumModel()->setSpecialTagListing(QLatin1String("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 << ItemModel::retrieveItemInfo(index); faces << d->faceDelegate->face(index); if (needFastRemove) { sourceIndexes << imageSortFilterModel()->mapToSourceItemModel(index); } } imageAlbumModel()->removeIndexes(sourceIndexes); for (int i = 0 ; i < infos.size() ; i++) { d->editPipeline.confirm(infos[i], faces[i], tagId); } } void DigikamImageView::removeFaces(const QList& indexes) { QList infos; QList faces; QList sourceIndexes; foreach (const QModelIndex& index, indexes) { infos << ItemModel::retrieveItemInfo(index); faces << d->faceDelegate->face(index); sourceIndexes << imageSortFilterModel()->mapToSourceItemModel(index); } imageAlbumModel()->removeIndexes(sourceIndexes); for (int i = 0 ; i < infos.size() ; i++) { d->editPipeline.remove(infos[i], faces[i]); } } void DigikamImageView::activated(const ItemInfo& info, Qt::KeyboardModifiers modifiers) { if (info.isNull()) { return; } if (modifiers != Qt::MetaModifier) { if (ApplicationSettings::instance()->getItemLeftClickAction() == ApplicationSettings::ShowPreview) { emit previewRequested(info); } else { openFile(info); } } else { d->utilities->openInfosWithDefaultApplication(QList() << info); } } void DigikamImageView::showContextMenuOnInfo(QContextMenuEvent* event, const ItemInfo& info) { emit signalShowContextMenuOnInfo(event, info, QList(), imageFilterModel()); } void DigikamImageView::showGroupContextMenu(const QModelIndex& index, QContextMenuEvent* event) { Q_UNUSED(index); emit signalShowGroupContextMenu(event, selectedItemInfosCurrentFirst(), imageFilterModel()); } void DigikamImageView::showContextMenu(QContextMenuEvent* event) { emit signalShowContextMenu(event); } void DigikamImageView::openFile(const ItemInfo& info) { d->utilities->openInfos(info, allItemInfos(), currentAlbum()); } void DigikamImageView::deleteSelected(const ItemViewUtilities::DeleteMode deleteMode) { ItemInfoList imageInfoList = selectedItemInfos(true); if (d->utilities->deleteImages(imageInfoList, deleteMode)) { awayFromSelection(); } } void DigikamImageView::deleteSelectedDirectly(const ItemViewUtilities::DeleteMode deleteMode) { ItemInfoList imageInfoList = selectedItemInfos(true); d->utilities->deleteImagesDirectly(imageInfoList, deleteMode); awayFromSelection(); } void DigikamImageView::assignRating(const QList& indexes, int rating) { ItemInfoList infos = imageInfos(indexes, ApplicationSettings::Metadata); FileActionMngr::instance()->assignRating(infos, rating); } void DigikamImageView::groupIndicatorClicked(const QModelIndex& index) { ItemInfo info = imageFilterModel()->imageInfo(index); if (info.isNull()) { return; } setCurrentIndex(index); imageFilterModel()->toggleGroupOpen(info.id()); imageAlbumModel()->ensureHasGroupedImages(info); } void DigikamImageView::rename() { ItemInfoList infos = selectedItemInfos(); if (needGroupResolving(ApplicationSettings::Rename, infos)) { infos = resolveGrouping(infos); } QList urls = infos.toImageUrlList(); bool loop = false; NewNamesList newNamesList; do { qCDebug(DIGIKAM_GENERAL_LOG) << "Selected URLs to rename: " << urls; QPointer dlg = new AdvancedRenameDialog(this); dlg->slotAddImages(urls); if (dlg->exec() != QDialog::Accepted) { delete dlg; break; } if (!loop) { QUrl nextUrl = nextInOrder(infos.last(), 1).fileUrl(); setCurrentUrl(nextUrl); loop = true; } newNamesList = dlg->newNames(); delete dlg; setFocus(); qApp->processEvents(); if (!newNamesList.isEmpty()) { QPointer dlg = new AdvancedRenameProcessDialog(newNamesList, this); dlg->exec(); imageFilterModel()->invalidate(); urls = dlg->failedUrls(); delete dlg; } } while (!urls.isEmpty() && !newNamesList.isEmpty()); } void DigikamImageView::slotRotateLeft(const QList& indexes) { ItemInfoList infos = imageInfos(indexes, ApplicationSettings::Metadata); FileActionMngr::instance()->transform(infos, MetaEngineRotation::Rotate270); } void DigikamImageView::slotRotateRight(const QList& indexes) { ItemInfoList infos = imageInfos(indexes, ApplicationSettings::Metadata); FileActionMngr::instance()->transform(infos, MetaEngineRotation::Rotate90); } void DigikamImageView::slotFullscreen(const QList& indexes) { QList infos = imageInfos(indexes, ApplicationSettings::Slideshow); if (infos.isEmpty()) { return; } // Just fullscreen the first. const ItemInfo& info = infos.at(0); emit fullscreenRequested(info); } void DigikamImageView::slotInitProgressIndicator() { if (!ProgressManager::instance()->findItembyId(QLatin1String("FaceActionProgress"))) { FileActionProgress* const item = new FileActionProgress(QLatin1String("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/core/app/items/digikamimageview_p.h b/core/app/items/digikamimageview_p.h index eac7977fc3..514f77212a 100644 --- a/core/app/items/digikamimageview_p.h +++ b/core/app/items/digikamimageview_p.h @@ -1,91 +1,91 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-10-03 * Description : Private Qt item view for images * * Copyright (C) 2009-2011 by Marcel Wiesweg * Copyright (C) 2009-2018 by Gilles Caulier * Copyright (C) 2009-2010 by Johannes Wienke * * 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 DIGIKAM_IMAGE_VIEW_PRIVATE_H #define DIGIKAM_IMAGE_VIEW_PRIVATE_H // Qt includes #include // Local includes #include "digikam_config.h" #include "digikamimageview.h" #include "digikamimagedelegate.h" #include "itemrotationoverlay.h" #include "itemfullscreenoverlay.h" #include "applicationsettings.h" #include "facepipeline.h" namespace Digikam { class DigikamImageDelegate; -class DigikamImageFaceDelegate; +class ItemFaceDelegate; class Q_DECL_HIDDEN DigikamImageView::Private : public QObject { Q_OBJECT Q_DECLARE_PUBLIC(DigikamImageView) public: explicit Private(DigikamImageView* const qq); ~Private(); void updateOverlays(); void triggerRotateAction(const char* actionName); public: ItemViewUtilities* utilities; FacePipeline editPipeline; DigikamImageDelegate* normalDelegate; - DigikamImageFaceDelegate* faceDelegate; + ItemFaceDelegate* faceDelegate; bool overlaysActive; bool fullscreenActive; ItemRotateOverlay* rotateLeftOverlay; ItemRotateOverlay* rotateRightOverlay; ItemFullScreenOverlay* fullscreenOverlay; bool faceMode; private: DigikamImageView* q_ptr; private: Private() {}; // disable default constructor. }; } // namespace Digikam #endif // DIGIKAM_IMAGE_VIEW_PRIVATE_H diff --git a/core/app/items/imagecategorizedview.cpp b/core/app/items/imagecategorizedview.cpp index 8759ea85aa..d8b71b8e9a 100644 --- a/core/app/items/imagecategorizedview.cpp +++ b/core/app/items/imagecategorizedview.cpp @@ -1,740 +1,740 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-04-22 * Description : Qt item view for images * * Copyright (C) 2009-2012 by Marcel Wiesweg * Copyright (C) 2017 by Simon Frei * * 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 "imagecategorizedview.h" // Qt includes #include #include // Local includes #include "digikam_debug.h" #include "album.h" #include "albummanager.h" #include "coredbfields.h" #include "iccsettings.h" #include "itemalbummodel.h" #include "itemalbumfiltermodel.h" #include "imagecategorydrawer.h" #include "imagedelegate.h" #include "itemdelegateoverlay.h" #include "itemthumbnailmodel.h" #include "itemselectionoverlay.h" #include "itemviewtooltip.h" #include "loadingcacheinterface.h" #include "thumbnailloadthread.h" #include "tooltipfiller.h" -#include "digikamimagefacedelegate.h" +#include "itemfacedelegate.h" namespace Digikam { class Q_DECL_HIDDEN ImageItemViewToolTip : public ItemViewToolTip { public: explicit ImageItemViewToolTip(ImageCategorizedView* const view) : ItemViewToolTip(view) { } ImageCategorizedView* view() const { return static_cast(ItemViewToolTip::view()); } protected: virtual QString tipContents() { ItemInfo info = ItemModel::retrieveItemInfo(currentIndex()); return ToolTipFiller::imageInfoTipContents(info); } }; // ------------------------------------------------------------------------------- class Q_DECL_HIDDEN ImageCategorizedView::Private { public: explicit Private() : model(0), filterModel(0), delegate(0), showToolTip(false), scrollToItemId(0), delayedEnterTimer(0), currentMouseEvent(0) { } ItemModel* model; ImageSortFilterModel* filterModel; ImageDelegate* delegate; bool showToolTip; qlonglong scrollToItemId; QUrl unknownCurrentUrl; QTimer* delayedEnterTimer; QMouseEvent* currentMouseEvent; }; // ------------------------------------------------------------------------------- ImageCategorizedView::ImageCategorizedView(QWidget* const parent) : ItemViewCategorized(parent), d(new Private) { setToolTip(new ImageItemViewToolTip(this)); LoadingCacheInterface::connectToSignalFileChanged(this, SLOT(slotFileChanged(QString))); connect(IccSettings::instance(), SIGNAL(settingsChanged(ICCSettingsContainer,ICCSettingsContainer)), this, SLOT(slotIccSettingsChanged(ICCSettingsContainer,ICCSettingsContainer))); d->delayedEnterTimer = new QTimer(this); d->delayedEnterTimer->setInterval(10); d->delayedEnterTimer->setSingleShot(true); connect(d->delayedEnterTimer, SIGNAL(timeout()), this, SLOT(slotDelayedEnter())); } ImageCategorizedView::~ImageCategorizedView() { d->delegate->removeAllOverlays(); delete d; } void ImageCategorizedView::installDefaultModels() { ItemAlbumModel* model = new ItemAlbumModel(this); ItemAlbumFilterModel* filterModel = new ItemAlbumFilterModel(this); filterModel->setSourceItemModel(model); filterModel->setSortRole(ItemSortSettings::SortByFileName); filterModel->setCategorizationMode(ItemSortSettings::CategoryByAlbum); filterModel->sort(0); // an initial sorting is necessary // set flags that we want to get dataChanged() signals for model->setWatchFlags(filterModel->suggestedWatchFlags()); setModels(model, filterModel); } void ImageCategorizedView::setModels(ItemModel* model, ImageSortFilterModel* filterModel) { if (d->delegate) { d->delegate->setAllOverlaysActive(false); } if (d->filterModel) { disconnect(d->filterModel, SIGNAL(layoutAboutToBeChanged()), this, SLOT(layoutAboutToBeChanged())); disconnect(d->filterModel, SIGNAL(layoutChanged()), this, SLOT(layoutWasChanged())); } if (d->model) { disconnect(d->model, SIGNAL(imageInfosAdded(QList)), this, SLOT(slotItemInfosAdded())); } d->model = model; d->filterModel = filterModel; setModel(d->filterModel); connect(d->filterModel, SIGNAL(layoutAboutToBeChanged()), this, SLOT(layoutAboutToBeChanged())); connect(d->filterModel, SIGNAL(layoutChanged()), this, SLOT(layoutWasChanged()), Qt::QueuedConnection); connect(d->model, SIGNAL(imageInfosAdded(QList)), this, SLOT(slotItemInfosAdded())); emit modelChanged(); if (d->delegate) { d->delegate->setAllOverlaysActive(true); } } ItemModel* ImageCategorizedView::imageModel() const { return d->model; } ImageSortFilterModel* ImageCategorizedView::imageSortFilterModel() const { return d->filterModel; } ItemFilterModel* ImageCategorizedView::imageFilterModel() const { return d->filterModel->imageFilterModel(); } ItemThumbnailModel* ImageCategorizedView::imageThumbnailModel() const { return qobject_cast(d->model); } ItemAlbumModel* ImageCategorizedView::imageAlbumModel() const { return qobject_cast(d->model); } ItemAlbumFilterModel* ImageCategorizedView::imageAlbumFilterModel() const { return qobject_cast(d->filterModel->imageFilterModel()); } QSortFilterProxyModel* ImageCategorizedView::filterModel() const { return d->filterModel; } ImageDelegate* ImageCategorizedView::delegate() const { return d->delegate; } void ImageCategorizedView::setItemDelegate(ImageDelegate* delegate) { ThumbnailSize oldSize = thumbnailSize(); ImageDelegate* oldDelegate = d->delegate; if (oldDelegate) { hideIndexNotification(); d->delegate->setAllOverlaysActive(false); d->delegate->setViewOnAllOverlays(0); // Note: Be precise, no wildcard disconnect! disconnect(d->delegate, SIGNAL(requestNotification(QModelIndex,QString)), this, SLOT(showIndexNotification(QModelIndex,QString))); disconnect(d->delegate, SIGNAL(hideNotification()), this, SLOT(hideIndexNotification())); } d->delegate = delegate; d->delegate->setThumbnailSize(oldSize); if (oldDelegate) { d->delegate->setSpacing(oldDelegate->spacing()); } ItemViewCategorized::setItemDelegate(d->delegate); setCategoryDrawer(d->delegate->categoryDrawer()); updateDelegateSizes(); d->delegate->setViewOnAllOverlays(this); d->delegate->setAllOverlaysActive(true); connect(d->delegate, SIGNAL(requestNotification(QModelIndex,QString)), this, SLOT(showIndexNotification(QModelIndex,QString))); connect(d->delegate, SIGNAL(hideNotification()), this, SLOT(hideIndexNotification())); } Album* ImageCategorizedView::currentAlbum() const { ItemAlbumModel* albumModel = imageAlbumModel(); /** TODO: Change to QList return type **/ if (albumModel && !(albumModel->currentAlbums().isEmpty())) { return albumModel->currentAlbums().first(); } return 0; } ItemInfo ImageCategorizedView::currentInfo() const { return imageInfo(currentIndex()); } QUrl ImageCategorizedView::currentUrl() const { return currentInfo().fileUrl(); } ItemInfo ImageCategorizedView::imageInfo(const QModelIndex& index) const { return d->filterModel->imageInfo(index); } ItemInfoList ImageCategorizedView::imageInfos(const QList& indexes) const { return ItemInfoList(d->filterModel->imageInfos(indexes)); } ItemInfoList ImageCategorizedView::allItemInfos() const { return ItemInfoList(d->filterModel->imageInfosSorted()); } QList ImageCategorizedView::allUrls() const { return allItemInfos().toImageUrlList(); } ItemInfoList ImageCategorizedView::selectedItemInfos() const { return imageInfos(selectedIndexes()); } ItemInfoList ImageCategorizedView::selectedItemInfosCurrentFirst() const { QModelIndexList indexes = selectedIndexes(); const QModelIndex current = currentIndex(); if (!indexes.isEmpty()) { if (indexes.first() != current) { if (indexes.removeOne(current)) { indexes.prepend(current); } } } return imageInfos(indexes); } void ImageCategorizedView::toIndex(const QUrl& url) { ItemViewCategorized::toIndex(d->filterModel->indexForPath(url.toLocalFile())); } QModelIndex ImageCategorizedView::indexForInfo(const ItemInfo& info) const { return d->filterModel->indexForItemInfo(info); } ItemInfo ImageCategorizedView::nextInOrder(const ItemInfo& startingPoint, int nth) { QModelIndex index = d->filterModel->indexForItemInfo(startingPoint); if (!index.isValid()) { return ItemInfo(); } return imageInfo(d->filterModel->index(index.row() + nth, 0, QModelIndex())); } QModelIndex ImageCategorizedView::nextIndexHint(const QModelIndex& anchor, const QItemSelectionRange& removed) const { QModelIndex hint = ItemViewCategorized::nextIndexHint(anchor, removed); ItemInfo info = imageInfo(anchor); //qCDebug(DIGIKAM_GENERAL_LOG) << "Having initial hint" << hint << "for" << anchor << d->model->numberOfIndexesForItemInfo(info); // Fixes a special case of multiple (face) entries for the same image. // If one is removed, any entry of the same image shall be preferred. if (d->model->numberOfIndexesForItemInfo(info) > 1) { // The hint is for a different info, but we may have a hint for the same info if (info != imageInfo(hint)) { int minDiff = d->filterModel->rowCount(); QList indexesForItemInfo = d->filterModel->mapListFromSource(d->model->indexesForItemInfo(info)); foreach(const QModelIndex& index, indexesForItemInfo) { if (index == anchor || !index.isValid() || removed.contains(index)) { continue; } int distance = qAbs(index.row() - anchor.row()); if (distance < minDiff) { minDiff = distance; hint = index; //qCDebug(DIGIKAM_GENERAL_LOG) << "Chose index" << hint << "at distance" << minDiff << "to" << anchor; } } } } return hint; } void ImageCategorizedView::openAlbum(const QList& albums) { ItemAlbumModel* const albumModel = imageAlbumModel(); if (albumModel) { albumModel->openAlbum(albums); } } ThumbnailSize ImageCategorizedView::thumbnailSize() const { /* ItemThumbnailModel* const thumbModel = imageThumbnailModel(); if (thumbModel) return thumbModel->thumbnailSize(); */ if (d->delegate) { return d->delegate->thumbnailSize(); } return ThumbnailSize(); } void ImageCategorizedView::setThumbnailSize(int size) { setThumbnailSize(ThumbnailSize(size)); } void ImageCategorizedView::setThumbnailSize(const ThumbnailSize& s) { // we abuse this pair of method calls to restore scroll position layoutAboutToBeChanged(); d->delegate->setThumbnailSize(s); layoutWasChanged(); } void ImageCategorizedView::setCurrentWhenAvailable(qlonglong imageId) { d->scrollToItemId = imageId; } void ImageCategorizedView::setCurrentUrlWhenAvailable(const QUrl& url) { if (url.isEmpty()) { clearSelection(); setCurrentIndex(QModelIndex()); return; } QString path = url.toLocalFile(); QModelIndex index = d->filterModel->indexForPath(path); if (!index.isValid()) { d->unknownCurrentUrl = url; return; } clearSelection(); setCurrentIndex(index); d->unknownCurrentUrl.clear(); } void ImageCategorizedView::setCurrentUrl(const QUrl& url) { if (url.isEmpty()) { clearSelection(); setCurrentIndex(QModelIndex()); return; } QString path = url.toLocalFile(); QModelIndex index = d->filterModel->indexForPath(path); if (!index.isValid()) { return; } clearSelection(); setCurrentIndex(index); } void ImageCategorizedView::setCurrentInfo(const ItemInfo& info) { QModelIndex index = d->filterModel->indexForItemInfo(info); clearSelection(); setCurrentIndex(index); } void ImageCategorizedView::setSelectedUrls(const QList& urlList) { QItemSelection mySelection; for (QList::const_iterator it = urlList.constBegin(); it!=urlList.constEnd(); ++it) { const QString path = it->toLocalFile(); const QModelIndex index = d->filterModel->indexForPath(path); if (!index.isValid()) { qCWarning(DIGIKAM_GENERAL_LOG) << "no QModelIndex found for" << *it; } else { // TODO: is there a better way? mySelection.select(index, index); } } clearSelection(); selectionModel()->select(mySelection, QItemSelectionModel::Select); } void ImageCategorizedView::setSelectedItemInfos(const QList& infos) { QItemSelection mySelection; foreach(const ItemInfo& info, infos) { QModelIndex index = d->filterModel->indexForItemInfo(info); mySelection.select(index, index); } selectionModel()->select(mySelection, QItemSelectionModel::ClearAndSelect); } void ImageCategorizedView::hintAt(const ItemInfo& info) { if (info.isNull()) { return; } QModelIndex index = d->filterModel->indexForItemInfo(info); if (!index.isValid()) { return; } selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); scrollTo(index); } void ImageCategorizedView::addOverlay(ItemDelegateOverlay* overlay, ImageDelegate* delegate) { if (!delegate) { delegate = d->delegate; } delegate->installOverlay(overlay); if (delegate == d->delegate) { overlay->setView(this); overlay->setActive(true); } } void ImageCategorizedView::removeOverlay(ItemDelegateOverlay* overlay) { ImageDelegate* delegate = dynamic_cast(overlay->delegate()); if (delegate) { delegate->removeOverlay(overlay); } overlay->setView(0); } void ImageCategorizedView::updateGeometries() { ItemViewCategorized::updateGeometries(); d->delayedEnterTimer->start(); } void ImageCategorizedView::slotDelayedEnter() { // re-emit entered() for index under mouse (after layout). QModelIndex mouseIndex = indexAt(mapFromGlobal(QCursor::pos())); if (mouseIndex.isValid()) { emit DCategorizedView::entered(mouseIndex); } } void ImageCategorizedView::addSelectionOverlay(ImageDelegate* delegate) { addOverlay(new ItemSelectionOverlay(this), delegate); } void ImageCategorizedView::scrollToStoredItem() { if (d->scrollToItemId) { if (d->model->hasImage(d->scrollToItemId)) { QModelIndex index = d->filterModel->indexForImageId(d->scrollToItemId); setCurrentIndex(index); scrollToRelaxed(index, QAbstractItemView::PositionAtCenter); d->scrollToItemId = 0; } } } void ImageCategorizedView::slotItemInfosAdded() { if (d->scrollToItemId) { scrollToStoredItem(); } else if (!d->unknownCurrentUrl.isEmpty()) { QTimer::singleShot(100, this, SLOT(slotCurrentUrlTimer())); } } void ImageCategorizedView::slotCurrentUrlTimer() { setCurrentUrl(d->unknownCurrentUrl); d->unknownCurrentUrl.clear(); } void ImageCategorizedView::slotFileChanged(const QString& filePath) { QModelIndex index = d->filterModel->indexForPath(filePath); if (index.isValid()) { update(index); } } void ImageCategorizedView::indexActivated(const QModelIndex& index, Qt::KeyboardModifiers modifiers) { ItemInfo info = imageInfo(index); if (!info.isNull()) { activated(info, modifiers); emit imageActivated(info); } } void ImageCategorizedView::currentChanged(const QModelIndex& index, const QModelIndex& previous) { ItemViewCategorized::currentChanged(index, previous); emit currentChanged(imageInfo(index)); } void ImageCategorizedView::selectionChanged(const QItemSelection& selectedItems, const QItemSelection& deselectedItems) { ItemViewCategorized::selectionChanged(selectedItems, deselectedItems); if (!selectedItems.isEmpty()) { emit selected(imageInfos(selectedItems.indexes())); } if (!deselectedItems.isEmpty()) { emit deselected(imageInfos(deselectedItems.indexes())); } } Album* ImageCategorizedView::albumAt(const QPoint& pos) const { if (imageFilterModel()->imageSortSettings().categorizationMode == ItemSortSettings::CategoryByAlbum) { QModelIndex categoryIndex = indexForCategoryAt(pos); if (categoryIndex.isValid()) { int albumId = categoryIndex.data(ItemFilterModel::CategoryAlbumIdRole).toInt(); return AlbumManager::instance()->findPAlbum(albumId); } } return currentAlbum(); } void ImageCategorizedView::activated(const ItemInfo&, Qt::KeyboardModifiers) { // implemented in subclass } void ImageCategorizedView::showContextMenuOnIndex(QContextMenuEvent* event, const QModelIndex& index) { showContextMenuOnInfo(event, imageInfo(index)); } void ImageCategorizedView::showContextMenuOnInfo(QContextMenuEvent*, const ItemInfo&) { // implemented in subclass } void ImageCategorizedView::paintEvent(QPaintEvent* e) { // We want the thumbnails to be loaded in order. ItemThumbnailModel* const thumbModel = imageThumbnailModel(); if (thumbModel) { QModelIndexList indexesToThumbnail = imageFilterModel()->mapListToSource(categorizedIndexesIn(viewport()->rect())); d->delegate->prepareThumbnails(thumbModel, indexesToThumbnail); } ItemViewCategorized::paintEvent(e); } QItemSelectionModel* ImageCategorizedView::getSelectionModel() const { return selectionModel(); } AbstractItemDragDropHandler* ImageCategorizedView::dragDropHandler() const { return d->model->dragDropHandler(); } void ImageCategorizedView::slotIccSettingsChanged(const ICCSettingsContainer&, const ICCSettingsContainer&) { viewport()->update(); } } // namespace Digikam diff --git a/core/app/items/digikamimagefacedelegate.cpp b/core/app/items/itemfacedelegate.cpp similarity index 74% rename from core/app/items/digikamimagefacedelegate.cpp rename to core/app/items/itemfacedelegate.cpp index f14e81ce9b..0f8feec9f6 100644 --- a/core/app/items/digikamimagefacedelegate.cpp +++ b/core/app/items/itemfacedelegate.cpp @@ -1,121 +1,121 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-04-19 - * Description : Qt item view for images - the delegate + * Description : Qt model-view for face item - the delegate * * Copyright (C) 2002-2005 by Renchi Raju * Copyright (C) 2002-2018 by Gilles Caulier * Copyright (C) 2009-2010 by Andi Clemens * Copyright (C) 2006-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. * * ============================================================ */ -#include "digikamimagefacedelegate.h" +#include "itemfacedelegate.h" #include "imagedelegatepriv.h" // Local includes #include "digikam_debug.h" #include "applicationsettings.h" #include "facetagsiface.h" #include "itemmodel.h" #include "tagregion.h" #include "digikamimagedelegatepriv.h" #include "faceutils.h" namespace Digikam { -DigikamImageFaceDelegate::DigikamImageFaceDelegate(ImageCategorizedView* const parent) - : DigikamImageDelegate(*new DigikamImageFaceDelegatePrivate, parent) +ItemFaceDelegate::ItemFaceDelegate(ImageCategorizedView* const parent) + : DigikamImageDelegate(*new ItemFaceDelegatePrivate, parent) { } -DigikamImageFaceDelegate::~DigikamImageFaceDelegate() +ItemFaceDelegate::~ItemFaceDelegate() { } -void DigikamImageFaceDelegate::prepareThumbnails(ItemThumbnailModel* thumbModel, const QList& indexes) +void ItemFaceDelegate::prepareThumbnails(ItemThumbnailModel* thumbModel, const QList& indexes) { //TODO DigikamImageDelegate::prepareThumbnails(thumbModel, indexes); } -QPixmap DigikamImageFaceDelegate::thumbnailPixmap(const QModelIndex& index) const +QPixmap ItemFaceDelegate::thumbnailPixmap(const QModelIndex& index) const { QRect rect = largerFaceRect(index); if (rect.isNull()) { return DigikamImageDelegate::thumbnailPixmap(index); } // set requested thumbnail detail if (rect.isValid()) { const_cast(index.model())->setData(index, rect, ItemModel::ThumbnailRole); } // parent implementation already resets the thumb size and rect set on model return DigikamImageDelegate::thumbnailPixmap(index); } -QRect DigikamImageFaceDelegate::faceRect(const QModelIndex& index) const +QRect ItemFaceDelegate::faceRect(const QModelIndex& index) const { return face(index).region().toRect(); } -QRect DigikamImageFaceDelegate::largerFaceRect(const QModelIndex& index) const +QRect ItemFaceDelegate::largerFaceRect(const QModelIndex& index) const { QRect rect = faceRect(index); if (rect.isNull()) { return rect; } const int margin = FaceUtils::faceRectDisplayMargin(); return rect.adjusted(-margin, -margin, margin, margin); } -FaceTagsIface DigikamImageFaceDelegate::face(const QModelIndex& index) const +FaceTagsIface ItemFaceDelegate::face(const QModelIndex& index) const { QVariant extraData = index.data(ItemModel::ExtraDataRole); if (extraData.isNull()) { return FaceTagsIface(); } FaceTagsIface face = FaceTagsIface::fromVariant(extraData); return face; } -void DigikamImageFaceDelegate::updateRects() +void ItemFaceDelegate::updateRects() { - Q_D(DigikamImageFaceDelegate); + Q_D(ItemFaceDelegate); DigikamImageDelegate::updateRects(); d->groupRect = QRect(); } -void DigikamImageFaceDelegate::clearModelDataCaches() +void ItemFaceDelegate::clearModelDataCaches() { DigikamImageDelegate::clearModelDataCaches(); } } // namespace Digikam diff --git a/core/app/items/digikamimagefacedelegate.h b/core/app/items/itemfacedelegate.h similarity index 76% rename from core/app/items/digikamimagefacedelegate.h rename to core/app/items/itemfacedelegate.h index 835309a708..5a9720c2b9 100644 --- a/core/app/items/digikamimagefacedelegate.h +++ b/core/app/items/itemfacedelegate.h @@ -1,66 +1,66 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-04-19 - * Description : Qt item view for images - the delegate + * Description : Qt model-view for face item - the delegate * * 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 DIGIKAM_IMAGE_FACE_DELEGATE_H -#define DIGIKAM_IMAGE_FACE_DELEGATE_H +#ifndef DIGIKAM_ITEM_FACE_DELEGATE_H +#define DIGIKAM_ITEM_FACE_DELEGATE_H // Local includes #include "digikamimagedelegate.h" namespace Digikam { class ImageCategoryDrawer; class FaceTagsIface; -class DigikamImageFaceDelegatePrivate; +class ItemFaceDelegatePrivate; -class DigikamImageFaceDelegate : public DigikamImageDelegate +class ItemFaceDelegate : public DigikamImageDelegate { Q_OBJECT public: - explicit DigikamImageFaceDelegate(ImageCategorizedView* const parent); - ~DigikamImageFaceDelegate(); + explicit ItemFaceDelegate(ImageCategorizedView* const parent); + ~ItemFaceDelegate(); virtual void prepareThumbnails(ItemThumbnailModel* thumbModel, const QList& indexes); QRect faceRect(const QModelIndex& index) const; QRect largerFaceRect(const QModelIndex& index) const; FaceTagsIface face(const QModelIndex& index) const; protected: virtual QPixmap thumbnailPixmap(const QModelIndex& index) const; virtual void updateRects(); virtual void clearModelDataCaches(); private: - Q_DECLARE_PRIVATE(DigikamImageFaceDelegate) + Q_DECLARE_PRIVATE(ItemFaceDelegate) }; } // namespace Digikam -#endif // DIGIKAM_IMAGE_FACE_DELEGATE_H +#endif // DIGIKAM_ITEM_FACE_DELEGATE_H diff --git a/core/app/items/overlays/facerejectionoverlay.cpp b/core/app/items/overlays/facerejectionoverlay.cpp index 3fd58a1ecc..990b11d94c 100644 --- a/core/app/items/overlays/facerejectionoverlay.cpp +++ b/core/app/items/overlays/facerejectionoverlay.cpp @@ -1,126 +1,126 @@ /* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2009-04-30 * Description : selection icon view item at mouse hover * * Copyright (C) 2008 by Peter Penz * Copyright (C) 2009-2011 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. * * ============================================================ */ #include "facerejectionoverlay.h" // KDE includes #include // Local includes #include "imagecategorizedview.h" #include "itemviewhoverbutton.h" #include "iteminfo.h" -#include "digikamimagefacedelegate.h" +#include "itemfacedelegate.h" #include "itemmodel.h" namespace Digikam { FaceRejectionOverlayButton::FaceRejectionOverlayButton(QAbstractItemView* const parentView) : ItemViewHoverButton(parentView) { setup(); } QSize FaceRejectionOverlayButton::sizeHint() const { return QSize(32, 32); } QIcon FaceRejectionOverlayButton::icon() { return QIcon::fromTheme(QLatin1String("window-close")); } void FaceRejectionOverlayButton::updateToolTip() { setToolTip(i18nc("@info:tooltip", "If this is not a face, click to reject it.")); } // -------------------------------------------------------------------- FaceRejectionOverlay::FaceRejectionOverlay(QObject* const parent) : HoverButtonDelegateOverlay(parent) { } void FaceRejectionOverlay::setActive(bool active) { HoverButtonDelegateOverlay::setActive(active); if (active) { connect(button(), SIGNAL(clicked(bool)), this, SLOT(slotClicked())); } else { // button is deleted } } ItemViewHoverButton* FaceRejectionOverlay::createButton() { return new FaceRejectionOverlayButton(view()); } void FaceRejectionOverlay::updateButton(const QModelIndex& index) { const QRect rect = m_view->visualRect(index); const int size = qBound(16, rect.width() / 8 - 2, 48); const int gap = 5; const int x = rect.right() - gap - size; const int y = rect.top() + gap; button()->resize(size, size); button()->move(QPoint(x, y)); } void FaceRejectionOverlay::slotClicked() { QModelIndex index = button()->index(); if (index.isValid()) { emit rejectFaces(affectedIndexes(index)); } } bool FaceRejectionOverlay::checkIndex(const QModelIndex& index) const { return !index.data(ItemModel::ExtraDataRole).isNull(); } void FaceRejectionOverlay::widgetEnterEvent() { widgetEnterNotifyMultiple(button()->index()); } void FaceRejectionOverlay::widgetLeaveEvent() { widgetLeaveNotifyMultiple(); } } // namespace Digikam