File indexing completed on 2025-01-19 03:50:44
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2009-12-05 0007 * Description : Side Bar Widget for People 0008 * 0009 * SPDX-FileCopyrightText: 2009-2010 by Johannes Wienke <languitar at semipol dot de> 0010 * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2012 by Andi Clemens <andi dot clemens at gmail dot com> 0012 * SPDX-FileCopyrightText: 2014 by Mohamed_Anwer <m_dot_anwer at gmx dot com> 0013 * SPDX-FileCopyrightText: 2010 by Aditya Bhatt <adityabhatt1991 at gmail dot com> 0014 * 0015 * SPDX-License-Identifier: GPL-2.0-or-later 0016 * 0017 * ============================================================ */ 0018 0019 #include "peoplesidebarwidget.h" 0020 0021 // Qt includes 0022 0023 #include <QLabel> 0024 #include <QScrollArea> 0025 #include <QApplication> 0026 #include <QStyle> 0027 #include <QPushButton> 0028 #include <QIcon> 0029 #include <QHBoxLayout> 0030 #include <QVBoxLayout> 0031 0032 // KDE includes 0033 0034 #include <kconfiggroup.h> 0035 #include <klocalizedstring.h> 0036 0037 // Local includes 0038 0039 #include "digikam_debug.h" 0040 #include "searchtextbardb.h" 0041 #include "tagfolderview.h" 0042 #include "timelinewidget.h" 0043 #include "facescanwidget.h" 0044 #include "facesdetector.h" 0045 #include "dnotificationwidget.h" 0046 #include "applicationsettings.h" 0047 0048 namespace Digikam 0049 { 0050 0051 class Q_DECL_HIDDEN PeopleSideBarWidget::Private 0052 { 0053 public: 0054 0055 explicit Private() 0056 : rescanButton (nullptr), 0057 searchModificationHelper(nullptr), 0058 settingsWdg (nullptr), 0059 tagFolderView (nullptr), 0060 tagSearchBar (nullptr) 0061 { 0062 } 0063 0064 QPushButton* rescanButton; 0065 SearchModificationHelper* searchModificationHelper; 0066 FaceScanWidget* settingsWdg; 0067 TagFolderView* tagFolderView; 0068 SearchTextBarDb* tagSearchBar; 0069 }; 0070 0071 PeopleSideBarWidget::PeopleSideBarWidget(QWidget* const parent, 0072 TagModel* const model, 0073 SearchModificationHelper* const searchModificationHelper) 0074 : SidebarWidget(parent), 0075 d (new Private) 0076 { 0077 setObjectName(QLatin1String("People Sidebar")); 0078 setProperty("Shortcut", QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_F9)); 0079 d->searchModificationHelper = searchModificationHelper; 0080 0081 const int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0082 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)); 0083 0084 QWidget* const mainView = new QWidget(this); 0085 QScrollArea* const scrollArea = new QScrollArea(this); 0086 QVBoxLayout* const mainLayout = new QVBoxLayout(this); 0087 0088 mainLayout->addWidget(scrollArea); 0089 mainLayout->setContentsMargins(0, 0, spacing, 0); 0090 scrollArea->setWidget(mainView); 0091 scrollArea->setWidgetResizable(true); 0092 0093 model->setColumnHeader(this->getCaption()); 0094 0095 QVBoxLayout* const vlay = new QVBoxLayout; 0096 d->tagFolderView = new TagFolderView(this, model); 0097 d->tagFolderView->setConfigGroup(getConfigGroup()); 0098 d->tagFolderView->setAlbumManagerCurrentAlbum(true); 0099 d->tagFolderView->setShowDeleteFaceTagsAction(true); 0100 0101 d->tagFolderView->filteredModel()->listOnlyTagsWithProperty(TagPropertyName::person()); 0102 d->tagFolderView->filteredModel()->setFilterBehavior(AlbumFilterModel::StrictFiltering); 0103 0104 d->tagSearchBar = new SearchTextBarDb(this, QLatin1String("ItemIconViewPeopleSearchBar")); 0105 d->tagSearchBar->setHighlightOnResult(true); 0106 d->tagSearchBar->setModel(d->tagFolderView->filteredModel(), 0107 AbstractAlbumModel::AlbumIdRole, AbstractAlbumModel::AlbumTitleRole); 0108 d->tagSearchBar->setFilterModel(d->tagFolderView->albumFilterModel()); 0109 0110 d->settingsWdg = new FaceScanWidget(this); 0111 0112 d->rescanButton = new QPushButton; 0113 d->rescanButton->setText(i18n("Scan collection for faces")); 0114 0115 vlay->addWidget(d->tagFolderView, 10); 0116 vlay->addWidget(d->tagSearchBar); 0117 vlay->addWidget(d->settingsWdg); 0118 vlay->addWidget(d->rescanButton); 0119 vlay->setContentsMargins(spacing, spacing, spacing, spacing); 0120 0121 mainView->setLayout(vlay); 0122 0123 connect(d->tagFolderView, SIGNAL(signalFindDuplicates(QList<TAlbum*>)), 0124 this, SIGNAL(signalFindDuplicates(QList<TAlbum*>))); 0125 0126 connect(d->rescanButton, SIGNAL(pressed()), 0127 this, SLOT(slotScanForFaces()) ); 0128 } 0129 0130 PeopleSideBarWidget::~PeopleSideBarWidget() 0131 { 0132 delete d; 0133 } 0134 0135 void PeopleSideBarWidget::slotInit() 0136 { 0137 loadState(); 0138 } 0139 0140 void PeopleSideBarWidget::setActive(bool active) 0141 { 0142 Q_EMIT requestFaceMode(active); 0143 0144 if (active) 0145 { 0146 d->tagFolderView->setCurrentAlbums(QList<Album*>() << d->tagFolderView->currentAlbum()); 0147 0148 if (!ApplicationSettings::instance()->getHelpBoxNotificationSeen()) 0149 { 0150 QString msg = i18n("Welcome to Face Management in digiKam. " 0151 "If this is your first time using this feature, please consider " 0152 "using the Help Box in the Bottom Left Side Panel."); 0153 Q_EMIT signalNotificationError(msg, DNotificationWidget::Information); 0154 ApplicationSettings::instance()->setHelpBoxNotificationSeen(true); 0155 } 0156 } 0157 } 0158 0159 void PeopleSideBarWidget::doLoadState() 0160 { 0161 d->tagFolderView->loadState(); 0162 d->settingsWdg->loadState(); 0163 } 0164 0165 void PeopleSideBarWidget::doSaveState() 0166 { 0167 d->tagFolderView->saveState(); 0168 d->settingsWdg->saveState(); 0169 } 0170 0171 void PeopleSideBarWidget::applySettings() 0172 { 0173 ApplicationSettings* const settings = ApplicationSettings::instance(); 0174 d->tagFolderView->setExpandNewCurrentItem(settings->getExpandNewCurrentItem()); 0175 } 0176 0177 void PeopleSideBarWidget::changeAlbumFromHistory(const QList<Album*>& album) 0178 { 0179 d->tagFolderView->setCurrentAlbums(album); 0180 } 0181 0182 void PeopleSideBarWidget::slotScanForFaces() 0183 { 0184 FaceScanSettings faceScanSettings = d->settingsWdg->settings(); 0185 0186 if (!d->settingsWdg->settingsConflicted()) 0187 { 0188 FacesDetector* const tool = new FacesDetector(faceScanSettings); 0189 tool->start(); 0190 0191 d->settingsWdg->setEnabled(false); 0192 d->rescanButton->setEnabled(false); 0193 0194 connect(tool, SIGNAL(signalComplete()), 0195 this, SLOT(slotScanComplete())); 0196 0197 connect(tool, SIGNAL(signalCanceled()), 0198 this, SLOT(slotScanComplete())); 0199 } 0200 else 0201 { 0202 Q_EMIT signalNotificationError(i18n("Face recognition is aborted, because " 0203 "there are no identities to recognize. " 0204 "Please add new identities."), 0205 DNotificationWidget::Information); 0206 } 0207 } 0208 0209 void PeopleSideBarWidget::slotScanComplete() 0210 { 0211 d->settingsWdg->setEnabled(true); 0212 d->rescanButton->setEnabled(true); 0213 } 0214 0215 const QIcon PeopleSideBarWidget::getIcon() 0216 { 0217 return QIcon::fromTheme(QLatin1String("edit-image-face-show")); 0218 } 0219 0220 const QString PeopleSideBarWidget::getCaption() 0221 { 0222 return i18nc("Browse images sorted by depicted people", "People"); 0223 } 0224 0225 } // namespace Digikam 0226 0227 #include "moc_peoplesidebarwidget.cpp"