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"