File indexing completed on 2025-01-19 03:53:19
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2004-06-15 0007 * Description : Albums manager interface - Date Album helpers. 0008 * 0009 * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2006-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0011 * SPDX-FileCopyrightText: 2015 by Mohamed_Anwer <m_dot_anwer at gmx dot com> 0012 * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * 0015 * ============================================================ */ 0016 0017 #include "albummanager_p.h" 0018 0019 namespace Digikam 0020 { 0021 0022 void AlbumManager::scanDAlbums() 0023 { 0024 d->scanDAlbumsTimer->stop(); 0025 0026 if (d->dateListJob) 0027 { 0028 disconnect(d->dateListJob, nullptr, this, nullptr); 0029 0030 d->dateListJob->cancel(); 0031 d->dateListJob = nullptr; 0032 } 0033 0034 DatesDBJobInfo jInfo; 0035 jInfo.setFoldersJob(); 0036 d->dateListJob = DBJobsManager::instance()->startDatesJobThread(jInfo); 0037 0038 connect(d->dateListJob, SIGNAL(finished()), 0039 this, SLOT(slotDatesJobResult())); 0040 0041 connect(d->dateListJob, SIGNAL(foldersData(QHash<QDateTime,int>)), 0042 this, SLOT(slotDatesJobData(QHash<QDateTime,int>))); 0043 } 0044 0045 AlbumList AlbumManager::allDAlbums() const 0046 { 0047 AlbumList list; 0048 0049 if (d->rootDAlbum) 0050 { 0051 list.append(d->rootDAlbum); 0052 } 0053 0054 AlbumIterator it(d->rootDAlbum); 0055 0056 while (it.current()) 0057 { 0058 list.append(*it); 0059 ++it; 0060 } 0061 0062 return list; 0063 } 0064 0065 DAlbum* AlbumManager::findDAlbum(int id) const 0066 { 0067 if (!d->rootDAlbum) 0068 { 0069 return nullptr; 0070 } 0071 0072 int gid = d->rootDAlbum->globalID() + id; 0073 0074 return static_cast<DAlbum*>((d->allAlbumsIdHash.value(gid))); 0075 } 0076 0077 QMap<YearMonth, int> AlbumManager::getDAlbumsCount() const 0078 { 0079 return d->dAlbumsCount; 0080 } 0081 0082 void AlbumManager::slotDatesJobResult() 0083 { 0084 if (!d->dateListJob) 0085 { 0086 return; 0087 } 0088 0089 if (d->dateListJob->hasErrors()) 0090 { 0091 qCWarning(DIGIKAM_GENERAL_LOG) << "Failed to list dates"; 0092 0093 // Pop-up a message about the error. 0094 0095 DNotificationWrapper(QString(), d->dateListJob->errorsList().first(), 0096 nullptr, i18n("digiKam")); 0097 } 0098 0099 d->dateListJob = nullptr; 0100 0101 Q_EMIT signalAllDAlbumsLoaded(); 0102 } 0103 0104 void AlbumManager::slotDatesJobData(const QHash<QDateTime, int>& datesStatHash) 0105 { 0106 if (datesStatHash.isEmpty() || !d->rootDAlbum) 0107 { 0108 return; 0109 } 0110 0111 // insert all the DAlbums into a qmap for quick access 0112 0113 QMap<QDate, DAlbum*> mAlbumMap; 0114 QMap<int, DAlbum*> yAlbumMap; 0115 0116 AlbumIterator it(d->rootDAlbum); 0117 0118 while (it.current()) 0119 { 0120 DAlbum* const a = (DAlbum*)(*it); 0121 0122 if (a->range() == DAlbum::Month) 0123 { 0124 mAlbumMap.insert(a->date(), a); 0125 } 0126 else 0127 { 0128 yAlbumMap.insert(a->date().year(), a); 0129 } 0130 0131 ++it; 0132 } 0133 0134 QMap<YearMonth, int> yearMonthMap; 0135 0136 for (QHash<QDateTime, int>::const_iterator it3 = datesStatHash.constBegin() ; 0137 it3 != datesStatHash.constEnd() ; ++it3) 0138 { 0139 YearMonth yearMonth = YearMonth(it3.key().date().year(), it3.key().date().month()); 0140 0141 QMap<YearMonth, int>::iterator it2 = yearMonthMap.find(yearMonth); 0142 0143 if (it2 == yearMonthMap.end()) 0144 { 0145 yearMonthMap.insert(yearMonth, *it3); 0146 } 0147 else 0148 { 0149 *it2 += *it3; 0150 } 0151 } 0152 0153 int year, month; 0154 0155 for (QMap<YearMonth, int>::const_iterator it4 = yearMonthMap.constBegin() ; 0156 it4 != yearMonthMap.constEnd() ; ++it4) 0157 { 0158 year = it4.key().first; 0159 month = it4.key().second; 0160 0161 QDate md(year, month, 1); 0162 0163 // Do we already have this Month album 0164 0165 if (mAlbumMap.contains(md)) 0166 { 0167 // already there. remove Month album from map 0168 0169 mAlbumMap.remove(md); 0170 0171 if (yAlbumMap.contains(year)) 0172 { 0173 // already there. remove from map 0174 0175 yAlbumMap.remove(year); 0176 } 0177 0178 continue; 0179 } 0180 0181 // Check if Year Album already exist. 0182 0183 DAlbum* yAlbum = nullptr; 0184 AlbumIterator it5(d->rootDAlbum); 0185 0186 while (it5.current()) 0187 { 0188 DAlbum* const a = (DAlbum*)(*it5); 0189 0190 if ((a->date() == QDate(year, 1, 1)) && (a->range() == DAlbum::Year)) 0191 { 0192 yAlbum = a; 0193 break; 0194 } 0195 0196 ++it5; 0197 } 0198 0199 // If no, create Year album. 0200 0201 if (!yAlbum) 0202 { 0203 yAlbum = new DAlbum(QDate(year, 1, 1), false, DAlbum::Year); 0204 Q_EMIT signalAlbumAboutToBeAdded(yAlbum, d->rootDAlbum, d->rootDAlbum->lastChild()); 0205 yAlbum->setParent(d->rootDAlbum); 0206 d->allAlbumsIdHash.insert(yAlbum->globalID(), yAlbum); 0207 Q_EMIT signalAlbumAdded(yAlbum); 0208 } 0209 0210 // Create Month album 0211 0212 DAlbum* const mAlbum = new DAlbum(md); 0213 0214 Q_EMIT signalAlbumAboutToBeAdded(mAlbum, yAlbum, yAlbum->lastChild()); 0215 0216 mAlbum->setParent(yAlbum); 0217 d->allAlbumsIdHash.insert(mAlbum->globalID(), mAlbum); 0218 0219 Q_EMIT signalAlbumAdded(mAlbum); 0220 } 0221 0222 // Now the items contained in the maps are the ones which 0223 // have been deleted. 0224 0225 for (QMap<QDate, DAlbum*>::const_iterator it6 = mAlbumMap.constBegin() ; 0226 it6 != mAlbumMap.constEnd() ; ++it6) 0227 { 0228 DAlbum* const album = it6.value(); 0229 Q_EMIT signalAlbumAboutToBeDeleted(album); 0230 d->allAlbumsIdHash.remove(album->globalID()); 0231 0232 Q_EMIT signalAlbumDeleted(album); 0233 0234 quintptr deletedAlbum = reinterpret_cast<quintptr>(album); 0235 delete album; 0236 0237 Q_EMIT signalAlbumHasBeenDeleted(deletedAlbum); 0238 } 0239 0240 for (QMap<int, DAlbum*>::const_iterator it7 = yAlbumMap.constBegin() ; 0241 it7 != yAlbumMap.constEnd() ; ++it7) 0242 { 0243 DAlbum* const album = it7.value(); 0244 Q_EMIT signalAlbumAboutToBeDeleted(album); 0245 d->allAlbumsIdHash.remove(album->globalID()); 0246 0247 Q_EMIT signalAlbumDeleted(album); 0248 0249 quintptr deletedAlbum = reinterpret_cast<quintptr>(album); 0250 delete album; 0251 0252 Q_EMIT signalAlbumHasBeenDeleted(deletedAlbum); 0253 } 0254 0255 d->dAlbumsCount = yearMonthMap; 0256 0257 Q_EMIT signalDAlbumsDirty(yearMonthMap); 0258 Q_EMIT signalDatesHashDirty(datesStatHash); 0259 } 0260 0261 void AlbumManager::scanDAlbumsScheduled() 0262 { 0263 // Avoid a cycle of killing a job which takes longer than the timer interval 0264 0265 if (d->dateListJob) 0266 { 0267 d->scanDAlbumsTimer->start(); 0268 return; 0269 } 0270 0271 scanDAlbums(); 0272 } 0273 0274 } // namespace Digikam