File indexing completed on 2025-01-19 03:53:20
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 - Search 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 AlbumList AlbumManager::allSAlbums() const 0023 { 0024 AlbumList list; 0025 0026 if (d->rootSAlbum) 0027 { 0028 list.append(d->rootSAlbum); 0029 } 0030 0031 AlbumIterator it(d->rootSAlbum); 0032 0033 while (it.current()) 0034 { 0035 list.append(*it); 0036 ++it; 0037 } 0038 0039 return list; 0040 } 0041 0042 void AlbumManager::scanSAlbums() 0043 { 0044 d->scanSAlbumsTimer->stop(); 0045 0046 // list SAlbums directly from the db 0047 // first insert all the current SAlbums into a map for quick lookup 0048 0049 QMap<int, SAlbum*> oldSearches; 0050 0051 AlbumIterator it(d->rootSAlbum); 0052 0053 while (it.current()) 0054 { 0055 SAlbum* const search = (SAlbum*)(*it); 0056 oldSearches[search->id()] = search; 0057 ++it; 0058 } 0059 0060 // scan db and get a list of all albums 0061 0062 QList<SearchInfo> currentSearches = CoreDbAccess().db()->scanSearches(); 0063 QList<SearchInfo> newSearches; 0064 0065 // go through all the Albums and see which ones are already present 0066 0067 Q_FOREACH (const SearchInfo& info, currentSearches) 0068 { 0069 if (oldSearches.contains(info.id)) 0070 { 0071 SAlbum* const album = oldSearches[info.id]; 0072 0073 if ((info.name != album->title()) || 0074 (info.type != album->searchType()) || 0075 (info.query != album->query())) 0076 { 0077 QString oldName = album->title(); 0078 0079 album->setSearch(info.type, info.query); 0080 album->setTitle(info.name); 0081 0082 if (oldName != album->title()) 0083 { 0084 Q_EMIT signalAlbumRenamed(album); 0085 } 0086 0087 Q_EMIT signalSearchUpdated(album); 0088 } 0089 0090 oldSearches.remove(info.id); 0091 } 0092 else 0093 { 0094 newSearches << info; 0095 } 0096 } 0097 0098 // remove old albums that have been deleted 0099 0100 Q_FOREACH (SAlbum* const album, oldSearches) 0101 { 0102 Q_EMIT signalAlbumAboutToBeDeleted(album); 0103 d->allAlbumsIdHash.remove(album->globalID()); 0104 0105 Q_EMIT signalAlbumDeleted(album); 0106 0107 quintptr deletedAlbum = reinterpret_cast<quintptr>(album); 0108 delete album; 0109 0110 Q_EMIT signalAlbumHasBeenDeleted(deletedAlbum); 0111 } 0112 0113 // add new albums 0114 0115 Q_FOREACH (const SearchInfo& info, newSearches) 0116 { 0117 SAlbum* const album = new SAlbum(info.name, info.id); 0118 album->setSearch(info.type, info.query); 0119 0120 Q_EMIT signalAlbumAboutToBeAdded(album, d->rootSAlbum, d->rootSAlbum->lastChild()); 0121 0122 album->setParent(d->rootSAlbum); 0123 d->allAlbumsIdHash[album->globalID()] = album; 0124 0125 Q_EMIT signalAlbumAdded(album); 0126 } 0127 } 0128 0129 SAlbum* AlbumManager::findSAlbum(int id) const 0130 { 0131 if (!d->rootSAlbum) 0132 { 0133 return nullptr; 0134 } 0135 0136 int gid = d->rootSAlbum->globalID() + id; 0137 0138 return (static_cast<SAlbum*>((d->allAlbumsIdHash.value(gid)))); 0139 } 0140 0141 SAlbum* AlbumManager::findSAlbum(const QString& name) const 0142 { 0143 for (Album* album = d->rootSAlbum->firstChild() ; 0144 album ; album = album->next()) 0145 { 0146 if (album->title() == name) 0147 { 0148 return (dynamic_cast<SAlbum*>(album)); 0149 } 0150 } 0151 0152 return nullptr; 0153 } 0154 0155 QList<SAlbum*> AlbumManager::findSAlbumsBySearchType(int searchType) const 0156 { 0157 QList<SAlbum*> albums; 0158 0159 for (Album* album = d->rootSAlbum->firstChild() ; 0160 album ; album = album->next()) 0161 { 0162 SAlbum* const sAlbum = dynamic_cast<SAlbum*>(album); 0163 0164 if ((sAlbum) && (sAlbum->searchType() == searchType)) 0165 { 0166 albums.append(sAlbum); 0167 } 0168 } 0169 0170 return albums; 0171 } 0172 0173 SAlbum* AlbumManager::createSAlbum(const QString& name, 0174 DatabaseSearch::Type type, 0175 const QString& query) 0176 { 0177 // first iterate through all the search albums and see if there's an existing 0178 // SAlbum with same name. (Remember, SAlbums are arranged in a flat list) 0179 0180 SAlbum* album = findSAlbum(name); 0181 ChangingDB changing(d); 0182 0183 if (album) 0184 { 0185 updateSAlbum(album, query, name, type); 0186 return album; 0187 } 0188 0189 int id = CoreDbAccess().db()->addSearch(type, name, query); 0190 0191 if (id == -1) 0192 { 0193 return nullptr; 0194 } 0195 0196 album = new SAlbum(name, id); 0197 Q_EMIT signalAlbumAboutToBeAdded(album, d->rootSAlbum, d->rootSAlbum->lastChild()); 0198 album->setSearch(type, query); 0199 album->setParent(d->rootSAlbum); 0200 0201 d->allAlbumsIdHash.insert(album->globalID(), album); 0202 0203 Q_EMIT signalAlbumAdded(album); 0204 0205 return album; 0206 } 0207 0208 bool AlbumManager::updateSAlbum(SAlbum* album, 0209 const QString& changedQuery, 0210 const QString& changedName, 0211 DatabaseSearch::Type type) 0212 { 0213 if (!album) 0214 { 0215 return false; 0216 } 0217 0218 QString newName = changedName.isNull() ? album->title() : changedName; 0219 DatabaseSearch::Type newType = (type == DatabaseSearch::UndefinedType) ? album->searchType() : type; 0220 0221 ChangingDB changing(d); 0222 CoreDbAccess().db()->updateSearch(album->id(), newType, newName, changedQuery); 0223 0224 QString oldName = album->title(); 0225 0226 album->setSearch(newType, changedQuery); 0227 album->setTitle(newName); 0228 0229 if (oldName != album->title()) 0230 { 0231 Q_EMIT signalAlbumRenamed(album); 0232 } 0233 0234 if (!d->currentAlbums.isEmpty()) 0235 { 0236 if (d->currentAlbums.first() == album) 0237 { 0238 Q_EMIT signalAlbumCurrentChanged(d->currentAlbums); 0239 } 0240 } 0241 0242 return true; 0243 } 0244 0245 bool AlbumManager::deleteSAlbum(SAlbum* album) 0246 { 0247 if (!album) 0248 { 0249 return false; 0250 } 0251 0252 Q_EMIT signalAlbumAboutToBeDeleted(album); 0253 0254 ChangingDB changing(d); 0255 CoreDbAccess().db()->deleteSearch(album->id()); 0256 0257 d->allAlbumsIdHash.remove(album->globalID()); 0258 0259 Q_EMIT signalAlbumDeleted(album); 0260 0261 quintptr deletedAlbum = reinterpret_cast<quintptr>(album); 0262 delete album; 0263 0264 Q_EMIT signalAlbumHasBeenDeleted(deletedAlbum); 0265 0266 return true; 0267 } 0268 0269 void AlbumManager::slotSearchChange(const SearchChangeset& changeset) 0270 { 0271 if (d->changingDB || !d->rootSAlbum) 0272 { 0273 return; 0274 } 0275 0276 switch (changeset.operation()) 0277 { 0278 case SearchChangeset::Added: 0279 case SearchChangeset::Deleted: 0280 { 0281 if (!d->scanSAlbumsTimer->isActive()) 0282 { 0283 d->scanSAlbumsTimer->start(); 0284 } 0285 0286 break; 0287 } 0288 0289 case SearchChangeset::Changed: 0290 { 0291 if (!d->currentAlbums.isEmpty()) 0292 { 0293 Album* const currentAlbum = d->currentAlbums.first(); 0294 0295 if (currentAlbum && 0296 (currentAlbum->type() == Album::SEARCH) && 0297 (currentAlbum->id() == changeset.searchId())) 0298 { 0299 // the pointer is the same, but the contents changed 0300 0301 Q_EMIT signalAlbumCurrentChanged(d->currentAlbums); 0302 } 0303 } 0304 0305 break; 0306 } 0307 0308 case SearchChangeset::Unknown: 0309 { 0310 break; 0311 } 0312 } 0313 } 0314 0315 } // namespace Digikam