1 /* ============================================================
2  *
3  * This file is a part of digiKam project
4  * https://www.digikam.org
5  *
6  * Date        : 2013-08-19
7  * Description : image quality sorter
8  *
9  * Copyright (C) 2013-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
10  *
11  * This program is free software; you can redistribute it
12  * and/or modify it under the terms of the GNU General
13  * Public License as published by the Free Software Foundation;
14  * either version 2, or (at your option)
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * ============================================================ */
23 
24 #include "imagequalitysorter.h"
25 
26 // Qt includes
27 
28 #include <QString>
29 #include <QIcon>
30 
31 // KDE includes
32 
33 #include <klocalizedstring.h>
34 
35 // Local includes
36 
37 #include "digikam_globals.h"
38 #include "dimg.h"
39 #include "coredb.h"
40 #include "albummanager.h"
41 #include "coredbaccess.h"
42 #include "tagscache.h"
43 #include "maintenancethread.h"
44 
45 namespace Digikam
46 {
47 
48 class Q_DECL_HIDDEN ImageQualitySorter::Private
49 {
50 public:
51 
Private()52     explicit Private()
53       : mode(ImageQualitySorter::NonAssignedItems),
54         thread(nullptr)
55     {
56     }
57 
58     QualityScanMode       mode;
59 
60     ImageQualityContainer quality;
61 
62     QStringList           allPicturesPath;
63 
64     AlbumList             albumList;
65 
66     MaintenanceThread*    thread;
67 };
68 
ImageQualitySorter(QualityScanMode mode,const AlbumList & list,const ImageQualityContainer & quality,ProgressItem * const parent)69 ImageQualitySorter::ImageQualitySorter(QualityScanMode mode,
70                                        const AlbumList& list,
71                                        const ImageQualityContainer& quality,
72                                        ProgressItem* const parent)
73     : MaintenanceTool(QLatin1String("ImageQualitySorter"), parent),
74       d(new Private)
75 {
76     setLabel(i18n("Image Quality Sorter"));
77     ProgressManager::addProgressItem(this);
78 
79     d->mode       = mode;
80     d->albumList  = list;
81     d->quality    = quality;
82     d->thread     = new MaintenanceThread(this);
83 
84     connect(d->thread, SIGNAL(signalCompleted()),
85             this, SLOT(slotDone()));
86 
87     connect(d->thread, SIGNAL(signalAdvance(QImage)),
88             this, SLOT(slotAdvance(QImage)));
89 }
90 
~ImageQualitySorter()91 ImageQualitySorter::~ImageQualitySorter()
92 {
93     delete d;
94 }
95 
setUseMultiCoreCPU(bool b)96 void ImageQualitySorter::setUseMultiCoreCPU(bool b)
97 {
98     d->thread->setUseMultiCore(b);
99 }
100 
slotCancel()101 void ImageQualitySorter::slotCancel()
102 {
103     d->thread->cancel();
104     MaintenanceTool::slotCancel();
105 }
106 
slotStart()107 void ImageQualitySorter::slotStart()
108 {
109     MaintenanceTool::slotStart();
110 
111     if (d->albumList.isEmpty())
112     {
113         d->albumList = AlbumManager::instance()->allPAlbums();
114     }
115 
116     // Get all item in DB which do not have any Pick Label assigned.
117     QStringList dirty = CoreDbAccess().db()->getItemsURLsWithTag(TagsCache::instance()->tagForPickLabel(NoPickLabel));
118 
119     // Get all digiKam albums collection pictures path, depending of d->rebuildAll flag.
120 
121     for (AlbumList::ConstIterator it = d->albumList.constBegin() ;
122          !canceled() && (it != d->albumList.constEnd()) ; ++it)
123     {
124         QStringList aPaths;
125 
126         if ((*it)->type() == Album::PHYSICAL)
127         {
128             aPaths = CoreDbAccess().db()->getItemURLsInAlbum((*it)->id());
129         }
130         else if ((*it)->type() == Album::TAG)
131         {
132             aPaths = CoreDbAccess().db()->getItemURLsInTag((*it)->id());
133         }
134 
135         if (d->mode == NonAssignedItems)
136         {
137             foreach (const QString& path, aPaths)
138             {
139                 if (dirty.contains(path))
140                 {
141                     d->allPicturesPath += path;
142                 }
143             }
144         }
145         else  // AllItems
146         {
147             d->allPicturesPath += aPaths;
148         }
149     }
150 
151     if (d->allPicturesPath.isEmpty())
152     {
153         slotDone();
154         return;
155     }
156 
157     setTotalItems(d->allPicturesPath.count());
158 
159     d->thread->sortByImageQuality(d->allPicturesPath, d->quality);
160     d->thread->start();
161 }
162 
slotAdvance(const QImage & img)163 void ImageQualitySorter::slotAdvance(const QImage& img)
164 {
165     setThumbnail(QIcon(QPixmap::fromImage(img)));
166     advance(1);
167 }
168 
169 } // namespace Digikam
170