File indexing completed on 2025-01-19 03:57:56
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2010-09-17 0007 * Description : Managing of face tag region items on a GraphicsDImgView 0008 * 0009 * SPDX-FileCopyrightText: 2010 by Aditya Bhatt <adityabhatt1991 at gmail dot com> 0010 * SPDX-FileCopyrightText: 2010-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0011 * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "facegroup_p.h" 0018 0019 namespace Digikam 0020 { 0021 0022 FaceGroup::Private::Private(FaceGroup* const q) 0023 : view (nullptr), 0024 exifRotate (true), 0025 autoSuggest (false), 0026 showOnHover (false), 0027 manuallyAddWrapItem (nullptr), 0028 manuallyAddedItem (nullptr), 0029 state (NoFaces), 0030 visibilityController (nullptr), 0031 tagModel (nullptr), 0032 filterModel (nullptr), 0033 filteredModel (nullptr), 0034 q (q) 0035 { 0036 } 0037 0038 QList<QGraphicsItem*> FaceGroup::Private::hotItems(const QPointF& scenePos) 0039 { 0040 if (!q->hasVisibleItems()) 0041 { 0042 return QList<QGraphicsItem*>(); 0043 } 0044 0045 const int distance = 15; 0046 QRectF hotSceneRect = QRectF(scenePos, QSize(0, 0)).adjusted(-distance, -distance, distance, distance); 0047 QList<QGraphicsItem*> closeItems = view->scene()->items(hotSceneRect, Qt::IntersectsItemBoundingRect); 0048 0049 closeItems.removeOne(view->previewItem()); 0050 0051 return closeItems; 0052 0053 /* 0054 qreal distance; 0055 d->faceGroup->closestItem(mapToScene(e->pos()), &distance); 0056 0057 if (distance < 15) 0058 { 0059 return false; 0060 } 0061 */ 0062 } 0063 0064 void FaceGroup::Private::applyVisible() 0065 { 0066 if (state == NoFaces) 0067 { 0068 // If not yet loaded, load. load() will transitionToVisible after loading. 0069 0070 q->load(); 0071 } 0072 else if (state == FacesLoaded) 0073 { 0074 // show existing faces, if we have an image 0075 0076 if (view->previewItem()->isLoaded()) 0077 { 0078 visibilityController->show(); 0079 } 0080 } 0081 } 0082 0083 FaceItem* FaceGroup::Private::createItem(const FaceTagsIface& face) 0084 { 0085 FaceItem* const item = new FaceItem(view->previewItem()); 0086 item->setFace(face); 0087 0088 QRect faceRect = face.region().toRect(); 0089 0090 if (!exifRotate) 0091 { 0092 TagRegion::reverseToOrientation(faceRect, 0093 info.orientation(), 0094 info.dimensions()); 0095 } 0096 0097 item->setOriginalRect(faceRect); 0098 item->setVisible(false); 0099 0100 return item; 0101 } 0102 0103 FaceItem* FaceGroup::Private::addItem(const FaceTagsIface& face) 0104 { 0105 FaceItem* const item = createItem(face); 0106 0107 // for identification, use index in our list 0108 0109 QList<QVariant> identifier(face.toVariant().toList()); 0110 identifier << items.size(); 0111 0112 AssignNameWidget* const assignWidget = createAssignNameWidget(face, identifier); 0113 item->setHudWidget(assignWidget); 0114 /* 0115 new StyleSheetDebugger(assignWidget); 0116 */ 0117 visibilityController->addItem(item); 0118 0119 items << item; 0120 0121 return item; 0122 } 0123 0124 void FaceGroup::Private::checkModels() 0125 { 0126 if (!tagModel) 0127 { 0128 tagModel = new TagModel(AbstractAlbumModel::IgnoreRootAlbum, q); 0129 } 0130 0131 if (!filterModel) 0132 { 0133 filterModel = new CheckableAlbumFilterModel(q); 0134 } 0135 0136 if (!filteredModel) 0137 { 0138 filteredModel = new TagPropertiesFilterModel(q); 0139 } 0140 } 0141 0142 AssignNameWidget::Mode FaceGroup::Private::assignWidgetMode(FaceTagsIface::Type type) 0143 { 0144 switch (type) 0145 { 0146 case FaceTagsIface::UnknownName: 0147 case FaceTagsIface::UnconfirmedName: 0148 { 0149 return AssignNameWidget::UnconfirmedEditMode; 0150 } 0151 0152 case FaceTagsIface::Type::IgnoredName: 0153 { 0154 return AssignNameWidget::IgnoredMode; 0155 } 0156 0157 case FaceTagsIface::ConfirmedName: 0158 { 0159 return AssignNameWidget::ConfirmedMode; 0160 } 0161 0162 default: 0163 { 0164 return AssignNameWidget::InvalidMode; 0165 } 0166 } 0167 } 0168 0169 AssignNameWidget* FaceGroup::Private::createAssignNameWidget(const FaceTagsIface& face, const QVariant& identifier) 0170 { 0171 AssignNameWidget* const assignWidget = new AssignNameWidget(view); 0172 assignWidget->setMode(assignWidgetMode(face.type())); 0173 assignWidget->setTagEntryWidgetMode(AssignNameWidget::AddTagsComboBoxMode); 0174 assignWidget->setVisualStyle(AssignNameWidget::TranslucentDarkRound); 0175 assignWidget->setLayoutMode(AssignNameWidget::TwoLines); 0176 assignWidget->setUserData(info, identifier); 0177 checkModels(); 0178 assignWidget->setAlbumModels(tagModel, filteredModel, filterModel); 0179 assignWidget->setParentTag(AlbumManager::instance()->findTAlbum(FaceTags::personParentTag())); 0180 0181 q->connect(assignWidget, SIGNAL(assigned(TaggingAction,ItemInfo,QVariant)), 0182 q, SLOT(slotAssigned(TaggingAction,ItemInfo,QVariant))); 0183 0184 q->connect(assignWidget, SIGNAL(rejected(ItemInfo,QVariant)), 0185 q, SLOT(slotRejected(ItemInfo,QVariant))); 0186 0187 q->connect(assignWidget, SIGNAL(ignored(ItemInfo,QVariant)), 0188 q, SLOT(slotIgnored(ItemInfo,QVariant))); 0189 0190 q->connect(assignWidget, SIGNAL(ignoredClicked(ItemInfo,QVariant)), 0191 q, SLOT(slotIgnoredClicked(ItemInfo,QVariant))); 0192 0193 q->connect(assignWidget, SIGNAL(labelClicked(ItemInfo,QVariant)), 0194 q, SLOT(slotLabelClicked(ItemInfo,QVariant))); 0195 0196 return assignWidget; 0197 } 0198 0199 } // namespace Digikam