File indexing completed on 2025-01-19 03:50:43

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2006-21-12
0007  * Description : a embedded view to show item preview widget.
0008  *
0009  * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2009-2012 by Andi Clemens <andi dot clemens at gmail dot com>
0011  * SPDX-FileCopyrightText: 2010-2011 by Aditya Bhatt <adityabhatt1991 at gmail dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "itempreviewview.h"
0018 
0019 // Qt includes
0020 
0021 #include <QApplication>
0022 #include <QGraphicsSceneContextMenuEvent>
0023 #include <QMouseEvent>
0024 #include <QToolBar>
0025 #include <QDragMoveEvent>
0026 #include <QDropEvent>
0027 #include <QDragEnterEvent>
0028 #include <QMenu>
0029 #include <QAction>
0030 #include <QIcon>
0031 
0032 // KDE includes
0033 
0034 #if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU)
0035 #   pragma GCC diagnostic push
0036 #   pragma GCC diagnostic ignored "-Wdeprecated-declarations"
0037 #endif
0038 
0039 #if defined(Q_CC_CLANG)
0040 #   pragma clang diagnostic push
0041 #   pragma clang diagnostic ignored "-Wdeprecated-declarations"
0042 #endif
0043 
0044 #include <kactioncollection.h>
0045 #include <klocalizedstring.h>
0046 
0047 // Restore warnings
0048 #if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU)
0049 #   pragma GCC diagnostic pop
0050 #endif
0051 
0052 #if defined(Q_CC_CLANG)
0053 #   pragma clang diagnostic pop
0054 #endif
0055 
0056 // Local includes
0057 
0058 #include "digikam_debug.h"
0059 #include "digikam_config.h"
0060 #include "digikam_globals.h"
0061 #include "itempreviewcanvas.h"
0062 #include "applicationsettings.h"
0063 #include "contextmenuhelper.h"
0064 #include "ddragobjects.h"
0065 #include "digikamapp.h"
0066 #include "dimg.h"
0067 #include "dimgpreviewitem.h"
0068 #include "fileactionmngr.h"
0069 #include "metaenginesettings.h"
0070 #include "regionframeitem.h"
0071 #include "tagspopupmenu.h"
0072 #include "thememanager.h"
0073 #include "previewlayout.h"
0074 #include "previewsettings.h"
0075 #include "tagscache.h"
0076 #include "itemtagpair.h"
0077 #include "albummanager.h"
0078 #include "facegroup.h"
0079 #include "focuspointgroup.h"
0080 
0081 namespace Digikam
0082 {
0083 
0084 class Q_DECL_HIDDEN ItemPreviewView::Private
0085 {
0086 public:
0087 
0088     explicit Private()
0089       : fullSize            (false),
0090         scale               (1.0),
0091         isValid             (false),
0092         rotationLock        (false),
0093         mode                (ItemPreviewView::IconViewPreview),
0094         item                (nullptr),
0095         prevAction          (nullptr),
0096         nextAction          (nullptr),
0097         rotLeftAction       (nullptr),
0098         rotRightAction      (nullptr),
0099         toolBar             (nullptr),
0100         faceGroup           (nullptr),
0101         peopleToggleAction  (nullptr),
0102         addPersonAction     (nullptr),
0103         forgetFacesAction   (nullptr),
0104         markAsIgnoredAction (nullptr),
0105         focusPointGroup     (nullptr),
0106         addFocusPointAction (nullptr),
0107         showFocusPointAction(nullptr),
0108         fullscreenAction    (nullptr),
0109         currAlbum           (nullptr)
0110     {
0111     }
0112 
0113     bool                   fullSize;
0114     double                 scale;
0115     bool                   isValid;
0116     bool                   rotationLock;
0117 
0118     ItemPreviewView::Mode  mode;
0119 
0120     ItemPreviewCanvas*     item;
0121 
0122     QAction*               prevAction;
0123     QAction*               nextAction;
0124     QAction*               rotLeftAction;
0125     QAction*               rotRightAction;
0126 
0127     QToolBar*              toolBar;
0128 
0129     FaceGroup*             faceGroup;
0130     QAction*               peopleToggleAction;
0131     QAction*               addPersonAction;
0132     QAction*               forgetFacesAction;
0133     QAction*               markAsIgnoredAction;
0134 
0135     FocusPointGroup*       focusPointGroup;
0136     QAction*               addFocusPointAction;
0137     QAction*               showFocusPointAction;
0138 
0139     QAction*               fullscreenAction;
0140 
0141     Album*                 currAlbum;
0142 };
0143 
0144 ItemPreviewView::ItemPreviewView(QWidget* const parent, Mode mode, Album* const currAlbum)
0145     : GraphicsDImgView(parent),
0146       d               (new Private())
0147 {
0148     d->mode      = mode;
0149     d->item      = new ItemPreviewCanvas();
0150     d->currAlbum = currAlbum;
0151     setItem(d->item);
0152 
0153     d->faceGroup = new FaceGroup(this);
0154     d->faceGroup->setShowOnHover(true);
0155     d->item->setFaceGroup(d->faceGroup);
0156 
0157     d->focusPointGroup = new FocusPointGroup(this);
0158 
0159     connect(d->item, SIGNAL(loaded()),
0160             this, SLOT(imageLoaded()));
0161 
0162     connect(d->item, SIGNAL(loadingFailed()),
0163             this, SLOT(imageLoadingFailed()));
0164 
0165     connect(d->item, SIGNAL(imageChanged()),
0166             this, SLOT(slotUpdateFaces()));
0167 
0168     connect(d->item, SIGNAL(showContextMenu(QGraphicsSceneContextMenuEvent*)),
0169             this, SLOT(slotShowContextMenu(QGraphicsSceneContextMenuEvent*)));
0170 
0171     // set default zoom
0172     layout()->fitToWindow();
0173 
0174     // ------------------------------------------------------------
0175 
0176     installPanIcon();
0177 
0178     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0179 
0180     // ------------------------------------------------------------
0181 
0182     KActionCollection* const ac = DigikamApp::instance()->actionCollection();
0183 
0184     d->prevAction               = new QAction(QIcon::fromTheme(QLatin1String("go-previous")),
0185                                               i18nc("go to previous image", "Back"),  this);
0186     d->nextAction               = new QAction(QIcon::fromTheme(QLatin1String("go-next")),
0187                                               i18nc("go to next image", "Forward"),   this);
0188     d->rotLeftAction            = new QAction(QIcon::fromTheme(QLatin1String("object-rotate-left")),
0189                                               i18nc("@info:tooltip", "Rotate Left"),  this);
0190     d->rotRightAction           = new QAction(QIcon::fromTheme(QLatin1String("object-rotate-right")),
0191                                               i18nc("@info:tooltip", "Rotate Right"), this);
0192 
0193     d->addPersonAction          = ac->action(QLatin1String("add_face_tag_manually"));
0194 
0195     if (!d->addPersonAction)
0196     {
0197         d->addPersonAction      = new QAction(QIcon::fromTheme(QLatin1String("list-add-user")),
0198                                               i18n("Add a Face Tag"),                 this);
0199         ac->addAction(QLatin1String("add_face_tag_manually"), d->addPersonAction);
0200     }
0201 
0202     d->forgetFacesAction        = new QAction(QIcon::fromTheme(QLatin1String("list-remove-user")),
0203                                               i18n("Clear all faces on this image"),  this);
0204 
0205     d->markAsIgnoredAction      = new QAction(QIcon::fromTheme(QLatin1String("dialog-cancel")),
0206                                               i18n("Mark all unconfirmed faces as ignored"),  this);
0207 
0208     d->peopleToggleAction       = ac->action(QLatin1String("toggle_show_face_tags"));
0209 
0210     if (!d->peopleToggleAction)
0211     {
0212         d->peopleToggleAction   = new QAction(QIcon::fromTheme(QLatin1String("im-user")),
0213                                               i18n("Show Face Tags"),                 this);
0214         ac->addAction(QLatin1String("toggle_show_face_tags"), d->peopleToggleAction);
0215     }
0216 
0217     d->addFocusPointAction      = new QAction(QIcon::fromTheme(QLatin1String("list-add-user")),
0218                                               i18n("Add a focus point"),              this);
0219     d->showFocusPointAction     = new QAction(QIcon::fromTheme(QLatin1String("im-user")),
0220                                               i18n("Show focus points"),              this);
0221 
0222     d->peopleToggleAction->setCheckable(true);
0223     d->showFocusPointAction->setCheckable(true);
0224 
0225     d->fullscreenAction         = new QAction(QIcon::fromTheme(QLatin1String("media-playback-start")),
0226                                               i18n("Show Fullscreen"),                this);
0227     d->toolBar                  = new QToolBar(this);
0228     d->toolBar->setStyleSheet(toolButtonStyleSheet());
0229 
0230     if (mode == IconViewPreview)
0231     {
0232         d->toolBar->addAction(d->prevAction);
0233         d->toolBar->addAction(d->nextAction);
0234     }
0235 
0236     d->toolBar->addAction(d->rotLeftAction);
0237     d->toolBar->addAction(d->rotRightAction);
0238 
0239     d->toolBar->addAction(d->peopleToggleAction);
0240     d->toolBar->addAction(d->addPersonAction);
0241     d->toolBar->addAction(d->fullscreenAction);
0242 
0243     connect(d->prevAction, SIGNAL(triggered()),
0244             this, SIGNAL(toPreviousImage()));
0245 
0246     connect(d->nextAction, SIGNAL(triggered()),
0247             this, SIGNAL(toNextImage()));
0248 
0249     connect(d->rotLeftAction, SIGNAL(triggered()),
0250             this, SLOT(slotRotateLeft()));
0251 
0252     connect(d->rotRightAction, SIGNAL(triggered()),
0253             this, SLOT(slotRotateRight()));
0254 
0255     connect(d->peopleToggleAction, SIGNAL(toggled(bool)),
0256             d->faceGroup, SLOT(setVisible(bool)));
0257 
0258     connect(d->addPersonAction, &QAction::triggered,
0259             this, [this]()
0260         {
0261             if (isVisible() && hasFocus())
0262             {
0263                 d->faceGroup->addFace();
0264             }
0265         }
0266     );
0267 
0268     connect(d->forgetFacesAction, SIGNAL(triggered()),
0269             d->faceGroup, SLOT(rejectAll()));
0270 
0271     connect(d->markAsIgnoredAction, SIGNAL(triggered()),
0272             d->faceGroup, SLOT(markAllAsIgnored()));
0273 
0274     connect(d->addFocusPointAction, SIGNAL(triggered()),
0275             d->focusPointGroup, SLOT(addPoint()));
0276 
0277     connect(d->showFocusPointAction, &QAction::toggled,
0278             this, [this](bool checked)
0279         {
0280             bool add = false;
0281 
0282             if (checked)
0283             {
0284                 d->focusPointGroup->setInfo(d->item->imageInfo());
0285                 add = d->focusPointGroup->isAllowedToAddFocusPoint();
0286             }
0287             else
0288             {
0289                 d->focusPointGroup->setInfo(ItemInfo());
0290             }
0291 
0292             d->focusPointGroup->setVisible(checked);
0293             d->addFocusPointAction->setEnabled(add);
0294         }
0295     );
0296 
0297     connect(d->fullscreenAction, SIGNAL(triggered()),
0298             this, SLOT(slotSlideShowCurrent()));
0299 
0300     // ------------------------------------------------------------
0301 
0302     connect(this, SIGNAL(toNextImage()),
0303             this, SIGNAL(signalNextItem()));
0304 
0305     connect(this, SIGNAL(toPreviousImage()),
0306             this, SIGNAL(signalPrevItem()));
0307 
0308     connect(this, SIGNAL(activated()),
0309             this, SIGNAL(signalEscapePreview()));
0310 
0311     connect(ThemeManager::instance(), SIGNAL(signalThemeChanged()),
0312             this, SLOT(slotThemeChanged()));
0313 
0314     connect(ApplicationSettings::instance(), SIGNAL(setupChanged()),
0315             this, SLOT(slotSetupChanged()));
0316 
0317     slotSetupChanged();
0318 }
0319 
0320 ItemPreviewView::~ItemPreviewView()
0321 {
0322     delete d->item;
0323     delete d->focusPointGroup;
0324     delete d;
0325 }
0326 
0327 void ItemPreviewView::reload()
0328 {
0329     previewItem()->reload();
0330 }
0331 
0332 void ItemPreviewView::imageLoaded()
0333 {
0334     Q_EMIT signalPreviewLoaded(true);
0335     d->rotLeftAction->setEnabled(true);
0336     d->rotRightAction->setEnabled(true);
0337 
0338     d->faceGroup->setInfo(d->item->imageInfo());
0339 
0340     bool add = false;
0341 
0342     if (d->showFocusPointAction->isChecked())
0343     {
0344         d->focusPointGroup->setInfo(d->item->imageInfo());
0345         add = d->focusPointGroup->isAllowedToAddFocusPoint();
0346     }
0347     else
0348     {
0349         d->focusPointGroup->setInfo(ItemInfo());
0350     }
0351 
0352     d->addFocusPointAction->setEnabled(add);
0353 }
0354 
0355 void ItemPreviewView::imageLoadingFailed()
0356 {
0357     Q_EMIT signalPreviewLoaded(false);
0358     d->rotLeftAction->setEnabled(false);
0359     d->rotRightAction->setEnabled(false);
0360     d->addFocusPointAction->setEnabled(false);
0361 
0362     d->faceGroup->setInfo(ItemInfo());
0363     d->focusPointGroup->setInfo(ItemInfo());
0364 
0365 }
0366 
0367 void ItemPreviewView::setItemInfo(const ItemInfo& info, const ItemInfo& previous, const ItemInfo& next)
0368 {
0369     d->faceGroup->aboutToSetInfo(info);
0370     d->item->setItemInfo(info);
0371 
0372     d->prevAction->setEnabled(!previous.isNull());
0373     d->nextAction->setEnabled(!next.isNull());
0374 
0375     QStringList previewPaths;
0376 
0377     if (next.category() == DatabaseItem::Image)
0378     {
0379         previewPaths << next.filePath();
0380     }
0381 
0382     if (previous.category() == DatabaseItem::Image)
0383     {
0384         previewPaths << previous.filePath();
0385     }
0386 
0387     d->item->setPreloadPaths(previewPaths);
0388 }
0389 
0390 ItemInfo ItemPreviewView::getItemInfo() const
0391 {
0392     return d->item->imageInfo();
0393 }
0394 
0395 bool ItemPreviewView::acceptsMouseClick(QMouseEvent* e)
0396 {
0397     if (!GraphicsDImgView::acceptsMouseClick(e))
0398     {
0399         return false;
0400     }
0401 
0402     return d->faceGroup->acceptsMouseClick(mapToScene(e->pos()));
0403 }
0404 
0405 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0406 
0407 void ItemPreviewView::enterEvent(QEnterEvent* e)
0408 
0409 #else
0410 
0411 void ItemPreviewView::enterEvent(QEvent* e)
0412 
0413 #endif
0414 
0415 {
0416     d->faceGroup->enterEvent(e);
0417 }
0418 
0419 void ItemPreviewView::leaveEvent(QEvent* e)
0420 {
0421     d->faceGroup->leaveEvent(e);
0422 }
0423 
0424 void ItemPreviewView::showEvent(QShowEvent* e)
0425 {
0426     GraphicsDImgView::showEvent(e);
0427     d->faceGroup->setVisible(d->peopleToggleAction->isChecked());
0428     d->focusPointGroup->setVisible(d->showFocusPointAction->isChecked());
0429 }
0430 
0431 void ItemPreviewView::slotShowContextMenu(QGraphicsSceneContextMenuEvent* event)
0432 {
0433     ItemInfo info = d->item->imageInfo();
0434 
0435     if (info.isNull())
0436     {
0437         return;
0438     }
0439 
0440     event->accept();
0441 
0442     QList<qlonglong> idList;
0443     idList << info.id();
0444 
0445     // --------------------------------------------------------
0446 
0447     QMenu popmenu(this);
0448     ContextMenuHelper cmHelper(&popmenu);
0449 
0450     cmHelper.addAction(QLatin1String("full_screen"));
0451     cmHelper.addAction(QLatin1String("options_show_menubar"));
0452     cmHelper.addSeparator();
0453 
0454     // --------------------------------------------------------
0455 
0456     if (d->mode == IconViewPreview)
0457     {
0458         cmHelper.addAction(d->prevAction, true);
0459         cmHelper.addAction(d->nextAction, true);
0460         cmHelper.addSeparator();
0461     }
0462 
0463     // --------------------------------------------------------
0464 
0465     cmHelper.addAction(d->peopleToggleAction,  true);
0466     cmHelper.addAction(QLatin1String("image_scan_for_faces"));
0467     cmHelper.addAction(d->addPersonAction,     true);
0468 
0469     // if there is a face in the image, give the option to remove all faces
0470     if (d->faceGroup->items().length() > 0)
0471     {
0472         cmHelper.addAction(d->forgetFacesAction,   true);
0473     }
0474 
0475     // if there is at least one unconfirmed face
0476     if (d->faceGroup->hasUnconfirmed())
0477     {
0478         // give the option to ignore unconfirmed faces
0479         cmHelper.addAction(d->markAsIgnoredAction, true);
0480         // give the option to recognize faces
0481         cmHelper.addAction(QLatin1String("image_recognize_faces"));
0482     }
0483     cmHelper.addSeparator();
0484 
0485     // -------------------------------------------------------
0486 
0487     cmHelper.addAction(d->addFocusPointAction,  true);
0488     cmHelper.addAction(d->showFocusPointAction, true);
0489     cmHelper.addSeparator();
0490 
0491     // --------------------------------------------------------
0492 
0493     cmHelper.addOpenAndNavigateActions(idList, (d->mode == LightTablePreview));
0494     cmHelper.addSeparator();
0495 
0496     // --------------------------------------------------------
0497 
0498     cmHelper.addAction(QLatin1String("image_find_similar"));
0499 
0500     if (d->mode == IconViewPreview)
0501     {
0502         cmHelper.addStandardActionLightTable();
0503     }
0504 
0505     cmHelper.addQueueManagerMenu();
0506     cmHelper.addSeparator();
0507 
0508     // --------------------------------------------------------
0509 
0510     cmHelper.addAction(QLatin1String("image_rotate"));
0511     cmHelper.addStandardActionItemDelete(this, SLOT(slotDeleteItem()));
0512     cmHelper.addSeparator();
0513 
0514     // --------------------------------------------------------
0515 
0516     if (d->mode == IconViewPreview && d->currAlbum)
0517     {
0518         cmHelper.addStandardActionThumbnail(idList, d->currAlbum);
0519     }
0520 
0521     cmHelper.addAssignTagsMenu(idList);
0522     cmHelper.addRemoveTagsMenu(idList);
0523     cmHelper.addRemoveAllTags(idList);
0524     cmHelper.addLabelsAction();
0525 
0526     // special action handling --------------------------------
0527 
0528     connect(&cmHelper, SIGNAL(signalAssignTag(int)),
0529             this, SLOT(slotAssignTag(int)));
0530 
0531     connect(&cmHelper, SIGNAL(signalPopupTagsView()),
0532             this, SIGNAL(signalPopupTagsView()));
0533 
0534     connect(&cmHelper, SIGNAL(signalRemoveTag(int)),
0535             this, SLOT(slotRemoveTag(int)));
0536 
0537     connect(&cmHelper, SIGNAL(signalAssignPickLabel(int)),
0538             this, SLOT(slotAssignPickLabel(int)));
0539 
0540     connect(&cmHelper, SIGNAL(signalAssignColorLabel(int)),
0541             this, SLOT(slotAssignColorLabel(int)));
0542 
0543     connect(&cmHelper, SIGNAL(signalAssignRating(int)),
0544             this, SLOT(slotAssignRating(int)));
0545 
0546     connect(&cmHelper, SIGNAL(signalAddToExistingQueue(int)),
0547             this, SIGNAL(signalAddToExistingQueue(int)));
0548 
0549     connect(&cmHelper, SIGNAL(signalGotoTag(int)),
0550             this, SIGNAL(signalGotoTagAndItem(int)));
0551 
0552     connect(&cmHelper, SIGNAL(signalGotoAlbum(ItemInfo)),
0553             this, SIGNAL(signalGotoAlbumAndItem(ItemInfo)));
0554 
0555     connect(&cmHelper, SIGNAL(signalGotoDate(ItemInfo)),
0556             this, SIGNAL(signalGotoDateAndItem(ItemInfo)));
0557 
0558     cmHelper.exec(event->screenPos());
0559 }
0560 
0561 void ItemPreviewView::slotSlideShowCurrent()
0562 {
0563     QList<DPluginAction*> actions = DPluginLoader::instance()->
0564                                         pluginActions(QLatin1String("org.kde.digikam.plugin.generic.SlideShow"),
0565                                         DigikamApp::instance());
0566 
0567     if (actions.isEmpty())
0568     {
0569         return;
0570     }
0571 
0572     //Trigger SlideShow manual
0573     actions[0]->setData(getItemInfo().fileUrl());
0574 
0575     actions[0]->trigger();
0576 }
0577 
0578 void ItemPreviewView::slotAssignTag(int tagID)
0579 {
0580     FileActionMngr::instance()->assignTag(d->item->imageInfo(), tagID);
0581 }
0582 
0583 void ItemPreviewView::slotRemoveTag(int tagID)
0584 {
0585     FileActionMngr::instance()->removeTag(d->item->imageInfo(), tagID);
0586 }
0587 
0588 void ItemPreviewView::slotAssignPickLabel(int pickId)
0589 {
0590     FileActionMngr::instance()->assignPickLabel(d->item->imageInfo(), pickId);
0591 }
0592 
0593 void ItemPreviewView::slotAssignColorLabel(int colorId)
0594 {
0595     FileActionMngr::instance()->assignColorLabel(d->item->imageInfo(), colorId);
0596 }
0597 
0598 void ItemPreviewView::slotAssignRating(int rating)
0599 {
0600     FileActionMngr::instance()->assignRating(d->item->imageInfo(), rating);
0601 }
0602 
0603 void ItemPreviewView::slotThemeChanged()
0604 {
0605     QPalette plt(palette());
0606     plt.setColor(backgroundRole(), qApp->palette().color(QPalette::Base));
0607     setPalette(plt);
0608 }
0609 
0610 void ItemPreviewView::slotSetupChanged()
0611 {
0612     previewItem()->setPreviewSettings(ApplicationSettings::instance()->getPreviewSettings());
0613 
0614     d->toolBar->setVisible(ApplicationSettings::instance()->getPreviewShowIcons());
0615     setScaleFitToWindow(ApplicationSettings::instance()->getScaleFitToWindow());
0616     setShowText(ApplicationSettings::instance()->getPreviewShowIcons());
0617 
0618     layout()->updateZoomAndSize();
0619 
0620     // pass auto-suggest?
0621 }
0622 
0623 void ItemPreviewView::slotRotateLeft()
0624 {
0625     if (d->rotationLock)
0626     {
0627         return;
0628     }
0629 
0630     d->rotationLock = true;
0631 
0632     /**
0633      * Setting lock won't allow mouse hover events in ItemPreviewCanvas class
0634      */
0635     d->item->setAcceptHoverEvents(false);
0636 
0637     /**
0638      * aboutToSetInfo will delete all face tags from FaceGroup storage
0639      */
0640     d->faceGroup->aboutToSetInfo(ItemInfo());
0641 
0642     FileActionMngr::instance()->transform(QList<ItemInfo>() << d->item->imageInfo(), MetaEngineRotation::Rotate270);
0643 }
0644 
0645 void ItemPreviewView::slotRotateRight()
0646 {
0647     if (d->rotationLock)
0648     {
0649         return;
0650     }
0651 
0652     d->rotationLock = true;
0653 
0654     /**
0655      * Setting lock won't allow mouse hover events in ItemPreviewCanvas class
0656      */
0657     d->item->setAcceptHoverEvents(false);
0658 
0659     /**
0660      * aboutToSetInfo will delete all face tags from FaceGroup storage
0661      */
0662     d->faceGroup->aboutToSetInfo(ItemInfo());
0663 
0664     FileActionMngr::instance()->transform(QList<ItemInfo>() << d->item->imageInfo(), MetaEngineRotation::Rotate90);
0665 }
0666 
0667 void ItemPreviewView::slotDeleteItem()
0668 {
0669     Q_EMIT signalDeleteItem();
0670 }
0671 
0672 void Digikam::ItemPreviewView::slotUpdateFaces()
0673 {
0674     //d->faceGroup->aboutToSetInfo(ItemInfo());
0675     d->faceGroup->aboutToSetInfoAfterRotate(ItemInfo());
0676     d->item->setAcceptHoverEvents(true);
0677 
0678     /**
0679      * Release rotation lock after rotation
0680      */
0681     d->rotationLock = false;
0682 }
0683 
0684 void ItemPreviewView::dragMoveEvent(QDragMoveEvent* e)
0685 {
0686     if (DTagListDrag::canDecode(e->mimeData()))
0687     {
0688         e->accept();
0689         return;
0690     }
0691 
0692     e->ignore();
0693 }
0694 
0695 void ItemPreviewView::dragEnterEvent(QDragEnterEvent* e)
0696 {
0697     if (DTagListDrag::canDecode(e->mimeData()))
0698     {
0699         e->accept();
0700         return;
0701     }
0702 
0703     e->ignore();
0704 }
0705 
0706 void ItemPreviewView::dropEvent(QDropEvent* e)
0707 {
0708     if (DTagListDrag::canDecode(e->mimeData()))
0709     {
0710         QList<int> tagIDs;
0711 
0712         if (!DTagListDrag::decode(e->mimeData(), tagIDs))
0713         {
0714             return;
0715         }
0716 
0717         QMenu popMenu(this);
0718         QAction* const assignToThisAction = popMenu.addAction(QIcon::fromTheme(QLatin1String("tag")), i18n("Assign Tags to &This Item"));
0719         popMenu.addSeparator();
0720         popMenu.addAction(QIcon::fromTheme(QLatin1String("dialog-cancel")), i18n("&Cancel"));
0721         popMenu.setMouseTracking(true);
0722 
0723 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0724 
0725         QAction* const choice             = popMenu.exec(this->mapToGlobal(e->position().toPoint()));
0726 
0727 #else
0728 
0729         QAction* const choice             = popMenu.exec(this->mapToGlobal(e->pos()));
0730 
0731 #endif
0732 
0733         if (choice == assignToThisAction)
0734         {
0735             FileActionMngr::instance()->assignTags(d->item->imageInfo(), tagIDs);
0736         }
0737     }
0738 
0739     e->accept();
0740     return;
0741 }
0742 
0743 void ItemPreviewView::mousePressEvent(QMouseEvent* e)
0744 {
0745     if ((e->button() == Qt::LeftButton) && (QApplication::keyboardModifiers() == Qt::ControlModifier))
0746     {
0747         d->faceGroup->addFace();
0748     }
0749 
0750     GraphicsDImgView::mousePressEvent(e);
0751 }
0752 
0753 } // namespace Digikam
0754 
0755 #include "moc_itempreviewview.cpp"