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"