00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00028
00029
00030 extern "C"
00031 {
00032 #include <sys/time.h>
00033 }
00034
00035
00036
00037 #include <cstdio>
00038 #include <cstdlib>
00039 #include <ctime>
00040
00041
00042
00043 #include <QFile>
00044 #include <QFileInfo>
00045 #include <QDir>
00046
00047
00048
00049 #include <kdebug.h>
00050 #include <klocale.h>
00051
00052
00053
00054 #include "databasebackend.h"
00055 #include "collectionmanager.h"
00056 #include "collectionlocation.h"
00057 #include "albumdb.h"
00058
00059 namespace Digikam
00060 {
00061
00062 class AlbumDBPriv
00063 {
00064
00065 public:
00066
00067 AlbumDBPriv()
00068 {
00069 db = 0;
00070 }
00071
00072 DatabaseBackend *db;
00073 QList<int> recentlyAssignedTags;
00074 };
00075
00076 AlbumDB::AlbumDB(DatabaseBackend *backend)
00077 {
00078 d = new AlbumDBPriv;
00079 d->db = backend;
00080 }
00081
00082 AlbumDB::~AlbumDB()
00083 {
00084 delete d;
00085 }
00086
00087 QList<AlbumRootInfo> AlbumDB::getAlbumRoots()
00088 {
00089 QList<AlbumRootInfo> list;
00090
00091 QList<QVariant> values;
00092 d->db->execSql( "SELECT id, label, status, type, identifier, specificPath FROM AlbumRoots;", &values );
00093
00094 for (QList<QVariant>::iterator it = values.begin(); it != values.end();)
00095 {
00096 AlbumRootInfo info;
00097 info.id = (*it).toInt();
00098 ++it;
00099 info.label = (*it).toString();
00100 ++it;
00101 info.status = (*it).toInt();
00102 ++it;
00103 info.type = (AlbumRoot::Type)(*it).toInt();
00104 ++it;
00105 info.identifier = (*it).toString();
00106 ++it;
00107 info.specificPath = (*it).toString();
00108 ++it;
00109
00110 list << info;
00111 }
00112
00113 return list;
00114 }
00115
00116 int AlbumDB::addAlbumRoot(AlbumRoot::Type type, const QString &identifier, const QString &specificPath, const QString &label)
00117 {
00118 QVariant id;
00119 d->db->execSql( QString("REPLACE INTO AlbumRoots (type, label, status, identifier, specificPath) "
00120 "VALUES(?, ?, 0, ?, ?);"),
00121 (int)type, label, identifier, specificPath, 0, &id);
00122
00123 d->db->recordChangeset(AlbumRootChangeset(id.toInt(), AlbumRootChangeset::Added));
00124 return id.toInt();
00125 }
00126
00127 void AlbumDB::deleteAlbumRoot(int rootId)
00128 {
00129 d->db->execSql( QString("DELETE FROM AlbumRoots WHERE id=?;"),
00130 rootId );
00131 d->db->recordChangeset(AlbumRootChangeset(rootId, AlbumRootChangeset::Deleted));
00132 }
00133
00134 void AlbumDB::setAlbumRootLabel(int rootId, const QString &newLabel)
00135 {
00136 d->db->execSql( QString("UPDATE AlbumRoots SET label=? WHERE id=?;"),
00137 newLabel, rootId);
00138 d->db->recordChangeset(AlbumRootChangeset(rootId, AlbumRootChangeset::PropertiesChanged));
00139 }
00140
00141 void AlbumDB::changeAlbumRootType(int rootId, AlbumRoot::Type newType)
00142 {
00143 d->db->execSql( QString("UPDATE AlbumRoots SET type=? WHERE id=?;"),
00144 (int)newType, rootId);
00145 d->db->recordChangeset(AlbumRootChangeset(rootId, AlbumRootChangeset::PropertiesChanged));
00146 }
00147
00148
00149
00150 AlbumInfo::List AlbumDB::scanAlbums()
00151 {
00152 AlbumInfo::List aList;
00153
00154 QList<QVariant> values;
00155 d->db->execSql( "SELECT A.albumRoot, A.id, A.relativePath, A.date, A.caption, A.collection, B.albumRoot, B.relativePath, I.name \n "
00156 "FROM Albums AS A \n "
00157 " LEFT OUTER JOIN Images AS I ON A.icon=I.id \n"
00158 " LEFT OUTER JOIN Albums AS B ON B.id=I.album \n"
00159 " WHERE A.albumRoot != 0;",
00160 &values);
00161
00162 QString iconAlbumUrl, iconName;
00163
00164 for (QList<QVariant>::iterator it = values.begin(); it != values.end();)
00165 {
00166 AlbumInfo info;
00167
00168 info.albumRootId = (*it).toInt();
00169 ++it;
00170 info.id = (*it).toInt();
00171 ++it;
00172 info.relativePath = (*it).toString();
00173 ++it;
00174 info.date = QDate::fromString((*it).toString(), Qt::ISODate);
00175 ++it;
00176 info.caption = (*it).toString();
00177 ++it;
00178 info.collection = (*it).toString();
00179 ++it;
00180 info.iconAlbumRootId = (*it).toInt();
00181 ++it;
00182 iconAlbumUrl = (*it).toString();
00183 ++it;
00184 iconName = (*it).toString();
00185 ++it;
00186
00187 if (!iconName.isEmpty())
00188 info.iconRelativePath = iconAlbumUrl + '/' + iconName;
00189
00190 aList.append(info);
00191 }
00192
00193 return aList;
00194 }
00195
00196 TagInfo::List AlbumDB::scanTags()
00197 {
00198 TagInfo::List tList;
00199
00200 QList<QVariant> values;
00201 d->db->execSql( "SELECT T.id, T.pid, T.name, A.relativePath, I.name, T.iconkde, A.albumRoot \n "
00202 "FROM Tags AS T \n"
00203 " LEFT OUTER JOIN Images AS I ON I.id=T.icon \n "
00204 " LEFT OUTER JOIN Albums AS A ON A.id=I.album; ", &values );
00205
00206 QString iconName, iconKDE, albumURL;
00207 int iconAlbumRootId;
00208
00209 for (QList<QVariant>::iterator it = values.begin(); it != values.end();)
00210 {
00211 TagInfo info;
00212
00213 info.id = (*it).toInt();
00214 ++it;
00215 info.pid = (*it).toInt();
00216 ++it;
00217 info.name = (*it).toString();
00218 ++it;
00219 albumURL = (*it).toString();
00220 ++it;
00221 iconName = (*it).toString();
00222 ++it;
00223 iconKDE = (*it).toString();
00224 ++it;
00225 iconAlbumRootId = (*it).toInt();
00226 ++it;
00227
00228 if (albumURL.isEmpty())
00229 {
00230 info.icon = iconKDE;
00231 }
00232 else
00233 {
00234 info.iconAlbumRootId = iconAlbumRootId;
00235 info.iconRelativePath = albumURL + '/' + iconName;
00236 }
00237
00238 tList.append(info);
00239 }
00240
00241 return tList;
00242 }
00243
00244 SearchInfo::List AlbumDB::scanSearches()
00245 {
00246 SearchInfo::List searchList;
00247
00248 QList<QVariant> values;
00249 d->db->execSql( "SELECT id, type, name, query FROM Searches;", &values);
00250
00251 for (QList<QVariant>::iterator it = values.begin(); it != values.end();)
00252 {
00253 SearchInfo info;
00254
00255 info.id = (*it).toInt();
00256 ++it;
00257 info.type = (DatabaseSearch::Type)(*it).toInt();
00258 ++it;
00259 info.name = (*it).toString();
00260 ++it;
00261 info.query = (*it).toString();
00262 ++it;
00263
00264 searchList.append(info);
00265 }
00266
00267 return searchList;
00268 }
00269
00270 QList<AlbumShortInfo> AlbumDB::getAlbumShortInfos()
00271 {
00272 QList<QVariant> values;
00273 d->db->execSql( QString("SELECT Albums.id, Albums.relativePath, Albums.albumRoot from Albums; "),
00274 &values);
00275
00276 QList<AlbumShortInfo> albumList;
00277
00278 for (QList<QVariant>::iterator it = values.begin(); it != values.end();)
00279 {
00280 AlbumShortInfo info;
00281
00282 info.id = (*it).toLongLong();
00283 ++it;
00284 info.relativePath = (*it).toString();
00285 ++it;
00286 info.albumRootId = (*it).toInt();
00287 ++it;
00288
00289 albumList << info;
00290 }
00291
00292 return albumList;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 int AlbumDB::addAlbum(int albumRootId, const QString& relativePath,
00349 const QString& caption,
00350 const QDate& date, const QString& collection)
00351 {
00352 QVariant id;
00353 QList<QVariant> boundValues;
00354 boundValues << albumRootId << relativePath << date.toString(Qt::ISODate) << caption << collection;
00355
00356 d->db->execSql( QString("REPLACE INTO Albums (albumRoot, relativePath, date, caption, collection) "
00357 "VALUES(?, ?, ?, ?, ?);"),
00358 boundValues, 0, &id);
00359
00360 d->db->recordChangeset(AlbumChangeset(id.toInt(), AlbumChangeset::Added));
00361 return id.toInt();
00362 }
00363
00364 void AlbumDB::setAlbumCaption(int albumID, const QString& caption)
00365 {
00366 d->db->execSql( QString("UPDATE Albums SET caption=? WHERE id=?;"),
00367 caption, albumID );
00368 d->db->recordChangeset(AlbumChangeset(albumID, AlbumChangeset::PropertiesChanged));
00369 }
00370
00371 void AlbumDB::setAlbumCollection(int albumID, const QString& collection)
00372 {
00373 d->db->execSql( QString("UPDATE Albums SET collection=? WHERE id=?;"),
00374 collection, albumID );
00375 d->db->recordChangeset(AlbumChangeset(albumID, AlbumChangeset::PropertiesChanged));
00376 }
00377
00378 void AlbumDB::setAlbumDate(int albumID, const QDate& date)
00379 {
00380 d->db->execSql( QString("UPDATE Albums SET date=? WHERE id=?;"),
00381 date.toString(Qt::ISODate),
00382 albumID );
00383 d->db->recordChangeset(AlbumChangeset(albumID, AlbumChangeset::PropertiesChanged));
00384 }
00385
00386 void AlbumDB::setAlbumIcon(int albumID, qlonglong iconID)
00387 {
00388 d->db->execSql( QString("UPDATE Albums SET icon=? WHERE id=?;"),
00389 iconID,
00390 albumID );
00391 d->db->recordChangeset(AlbumChangeset(albumID, AlbumChangeset::PropertiesChanged));
00392 }
00393
00394 bool AlbumDB::getAlbumIcon(int albumID, int *albumRootId, QString *iconRelativePath)
00395 {
00396 QList<QVariant> values;
00397 d->db->execSql( QString("SELECT B.relativePath, I.name, B.albumRoot \n "
00398 "FROM Albums AS A \n "
00399 " LEFT OUTER JOIN Images AS I ON I.id=A.icon \n "
00400 " LEFT OUTER JOIN Albums AS B ON B.id=I.album \n "
00401 "WHERE A.id=?;"),
00402 albumID, &values );
00403 if (values.isEmpty())
00404 return false;
00405
00406 QList<QVariant>::iterator it = values.begin();
00407 QString album = (*it).toString();
00408 ++it;
00409 QString iconName = (*it).toString();
00410 ++it;
00411 *albumRootId = (*it).toInt();
00412
00413 *iconRelativePath = album + '/' + iconName;
00414
00415 return !iconName.isEmpty();
00416 }
00417
00418 void AlbumDB::deleteAlbum(int albumID)
00419 {
00420 d->db->execSql( QString("DELETE FROM Albums WHERE id=?;"),
00421 albumID );
00422 d->db->recordChangeset(AlbumChangeset(albumID, AlbumChangeset::Deleted));
00423 }
00424
00425 void AlbumDB::makeStaleAlbum(int albumID)
00426 {
00427
00428
00429 QList<QVariant> values;
00430
00431
00432 d->db->execSql( QString("SELECT Albums.albumRoot, Albums.relativePath from Albums WHERE id=?;"),
00433 albumID, &values);
00434
00435 if (values.isEmpty())
00436 return;
00437
00438
00439 QString newRelativePath = values[0].toString() + '-' + values[1].toString();
00440
00441
00442 d->db->execSql( QString("DELETE FROM Albums WHERE albumRoot=0 AND relativePath=?;"),
00443 newRelativePath );
00444
00445
00446 d->db->execSql( QString("UPDATE Albums SET albumRoot=0, relativePath=? WHERE id=?;"),
00447 newRelativePath, albumID );
00448
00449
00450 d->db->recordChangeset(AlbumChangeset(albumID, AlbumChangeset::Deleted));
00451 }
00452
00453 void AlbumDB::deleteStaleAlbums()
00454 {
00455 d->db->execSql( QString("DELETE FROM Albums WHERE albumRoot=0;") );
00456
00457 }
00458
00459 int AlbumDB::addTag(int parentTagID, const QString& name, const QString& iconKDE,
00460 qlonglong iconID)
00461 {
00462 QVariant id;
00463 if (!d->db->execSql( QString("INSERT INTO Tags (pid, name) "
00464 "VALUES( ?, ?);"),
00465 parentTagID,
00466 name,
00467 0, &id) )
00468 {
00469 return -1;
00470 }
00471
00472 if (!iconKDE.isEmpty())
00473 {
00474 d->db->execSql( QString("UPDATE Tags SET iconkde=? WHERE id=?;"),
00475 iconKDE,
00476 id.toInt() );
00477 }
00478 else
00479 {
00480 d->db->execSql( QString("UPDATE Tags SET icon=? WHERE id=?;"),
00481 iconID,
00482 id.toInt());
00483 }
00484
00485 d->db->recordChangeset(TagChangeset(id.toInt(), TagChangeset::Added));
00486 return id.toInt();
00487 }
00488
00489 void AlbumDB::deleteTag(int tagID)
00490 {
00491 d->db->execSql( QString("DELETE FROM Tags WHERE id=?;"),
00492 tagID );
00493 d->db->recordChangeset(TagChangeset(tagID, TagChangeset::Deleted));
00494 }
00495
00496 void AlbumDB::setTagIcon(int tagID, const QString& iconKDE, qlonglong iconID)
00497 {
00498 if (!iconKDE.isEmpty())
00499 {
00500 d->db->execSql( QString("UPDATE Tags SET iconkde=?, icon=0 WHERE id=?;"),
00501 iconKDE, tagID );
00502 }
00503 else
00504 {
00505 d->db->execSql( QString("UPDATE Tags SET icon=? WHERE id=?;"),
00506 iconID, tagID );
00507 }
00508 d->db->recordChangeset(TagChangeset(tagID, TagChangeset::IconChanged));
00509 }
00510
00511 bool AlbumDB::getTagIcon(int tagID, int *iconAlbumRootId, QString *iconAlbumRelativePath, QString *icon)
00512 {
00513 QList<QVariant> values;
00514 d->db->execSql( QString("SELECT A.relativePath, I.name, T.iconkde, A.albumRoot \n "
00515 "FROM Tags AS T \n "
00516 " LEFT OUTER JOIN Images AS I ON I.id=T.icon \n "
00517 " LEFT OUTER JOIN Albums AS A ON A.id=I.album \n "
00518 "WHERE T.id=?;"),
00519 tagID, &values );
00520
00521 if (values.isEmpty())
00522 return false;
00523
00524 QString iconName, iconKDE, albumURL;
00525
00526 QList<QVariant>::iterator it = values.begin();
00527
00528 albumURL = (*it).toString();
00529 ++it;
00530 iconName = (*it).toString();
00531 ++it;
00532 iconKDE = (*it).toString();
00533 ++it;
00534
00535 *iconAlbumRootId = (*it).toInt();
00536 ++it;
00537
00538 if (albumURL.isEmpty())
00539 {
00540 *iconAlbumRelativePath = QString();
00541 *icon = iconKDE;
00542 return !iconKDE.isEmpty();
00543 }
00544 else
00545 {
00546 *iconAlbumRelativePath = albumURL + '/' + iconName;
00547 *icon = QString();
00548 return true;
00549 }
00550 }
00551
00552 void AlbumDB::setTagParentID(int tagID, int newParentTagID)
00553 {
00554 d->db->execSql( QString("UPDATE Tags SET pid=? WHERE id=?;"),
00555 newParentTagID, tagID );
00556 d->db->recordChangeset(TagChangeset(tagID, TagChangeset::Reparented));
00557 }
00558
00559 int AlbumDB::addSearch(DatabaseSearch::Type type, const QString& name, const QString &query)
00560 {
00561 QVariant id;
00562 if (!d->db->execSql(QString("INSERT INTO Searches (type, name, query) VALUES(?, ?, ?);"),
00563 type, name, query, 0, &id) )
00564 {
00565 return -1;
00566 }
00567
00568 d->db->recordChangeset(SearchChangeset(id.toInt(), SearchChangeset::Added));
00569 return id.toInt();
00570 }
00571
00572 void AlbumDB::updateSearch(int searchID, DatabaseSearch::Type type,
00573 const QString& name, const QString &query)
00574 {
00575 d->db->execSql(QString("UPDATE Searches SET type=?, name=?, query=? WHERE id=?"),
00576 type, name, query, searchID);
00577 d->db->recordChangeset(SearchChangeset(searchID, SearchChangeset::Changed));
00578 }
00579
00580 void AlbumDB::deleteSearch(int searchID)
00581 {
00582 d->db->execSql( QString("DELETE FROM Searches WHERE id=?"),
00583 searchID );
00584 d->db->recordChangeset(SearchChangeset(searchID, SearchChangeset::Deleted));
00585 }
00586
00587 void AlbumDB::deleteSearches(DatabaseSearch::Type type)
00588 {
00589 d->db->execSql( QString("DELETE FROM Searches WHERE type=?"),
00590 type );
00591 d->db->recordChangeset(SearchChangeset(0, SearchChangeset::Deleted));
00592 }
00593
00594 QString AlbumDB::getSearchQuery(int searchId)
00595 {
00596 QList<QVariant> values;
00597 d->db->execSql( QString("SELECT query FROM Searches WHERE id=?;"),
00598 searchId, &values );
00599
00600 if (values.isEmpty())
00601 return QString();
00602 else
00603 return values.first().toString();
00604 }
00605
00606 SearchInfo AlbumDB::getSearchInfo(int searchId)
00607 {
00608 SearchInfo info;
00609
00610 QList<QVariant> values;
00611 d->db->execSql( "SELECT id, type, name, query FROM Searches WHERE id=?;",
00612 searchId, &values);
00613
00614 if (values.size() == 4)
00615 {
00616 QList<QVariant>::iterator it = values.begin();
00617 info.id = (*it).toInt();
00618 ++it;
00619 info.type = (DatabaseSearch::Type)(*it).toInt();
00620 ++it;
00621 info.name = (*it).toString();
00622 ++it;
00623 info.query = (*it).toString();
00624 ++it;
00625 }
00626
00627 return info;
00628 }
00629
00630 void AlbumDB::setSetting(const QString& keyword,
00631 const QString& value )
00632 {
00633 d->db->execSql( QString("REPLACE into Settings VALUES (?,?);"),
00634 keyword, value );
00635 }
00636
00637 QString AlbumDB::getSetting(const QString& keyword)
00638 {
00639 QList<QVariant> values;
00640 d->db->execSql( QString("SELECT value FROM Settings "
00641 "WHERE keyword=?;"),
00642 keyword, &values );
00643
00644 if (values.isEmpty())
00645 return QString();
00646 else
00647 return values.first().toString();
00648 }
00649
00650
00651 static QStringList joinMainAndUserFilterString(const QString &filter, const QString &userFilter)
00652 {
00653 QSet<QString> filterSet;
00654 QStringList userFilterList;
00655
00656 filterSet = filter.split(';', QString::SkipEmptyParts).toSet();
00657 userFilterList = userFilter.split(';', QString::SkipEmptyParts);
00658 foreach (const QString &userFormat, userFilterList)
00659 {
00660 if (userFormat.startsWith('-'))
00661 filterSet.remove(userFormat.mid(1));
00662 else
00663 filterSet << userFormat;
00664 }
00665 return filterSet.toList();
00666 }
00667
00668 void AlbumDB::getFilterSettings(QStringList *imageFilter, QStringList *videoFilter, QStringList *audioFilter)
00669 {
00670 QString imageFormats, videoFormats, audioFormats, userImageFormats, userVideoFormats, userAudioFormats;
00671
00672 if (imageFilter)
00673 {
00674 imageFormats = getSetting("databaseImageFormats");
00675 userImageFormats = getSetting("databaseUserImageFormats");
00676 *imageFilter = joinMainAndUserFilterString(imageFormats, userImageFormats);
00677 }
00678
00679 if (videoFilter)
00680 {
00681 videoFormats = getSetting("databaseVideoFormats");
00682 userVideoFormats = getSetting("databaseUserVideoFormats");
00683 *videoFilter = joinMainAndUserFilterString(videoFormats, userVideoFormats);
00684 }
00685
00686 if (audioFilter)
00687 {
00688 audioFormats = getSetting("databaseAudioFormats");
00689 userAudioFormats = getSetting("databaseUserAudioFormats");
00690 *audioFilter = joinMainAndUserFilterString(audioFormats, userAudioFormats);
00691 }
00692 }
00693
00694 void AlbumDB::getUserFilterSettings(QString *imageFilterString, QString *videoFilterString, QString *audioFilterString)
00695 {
00696 if (imageFilterString)
00697 *imageFilterString = getSetting("databaseUserImageFormats");
00698 if (videoFilterString)
00699 *videoFilterString = getSetting("databaseUserVideoFormats");
00700 if (audioFilterString)
00701 *audioFilterString = getSetting("databaseUserAudioFormats");
00702 }
00703
00704 void AlbumDB::setFilterSettings(const QStringList &imageFilter, const QStringList &videoFilter, const QStringList &audioFilter)
00705 {
00706 setSetting("databaseImageFormats", imageFilter.join(";"));
00707 setSetting("databaseVideoFormats", videoFilter.join(";"));
00708 setSetting("databaseAudioFormats", audioFilter.join(";"));
00709 }
00710
00711
00712 static QStringList cleanUserFilterString(const QString &filterString)
00713 {
00714
00715 QStringList filterList;
00716
00717 QString wildcard("*.");
00718 QString minusWildcard("-*.");
00719 QChar dot('.');
00720 QString minusDot("-.");
00721 QChar sep( ';' );
00722 int i = filterString.indexOf( sep );
00723 if ( i == -1 && filterString.indexOf( ' ') != -1 )
00724 sep = QChar( ' ' );
00725
00726 QStringList sepList = filterString.split(sep, QString::SkipEmptyParts);
00727 foreach (const QString &f, sepList)
00728 {
00729 if (f.startsWith(wildcard))
00730 filterList << f.mid(2).trimmed().toLower();
00731 else if (f.startsWith(minusWildcard))
00732 filterList << '-' + f.mid(3).trimmed().toLower();
00733 else if (f.startsWith(dot))
00734 filterList << f.mid(1).trimmed().toLower();
00735 else if (f.startsWith(minusDot))
00736 filterList << '-' + f.mid(2).trimmed().toLower();
00737 else
00738 filterList << f.trimmed().toLower();
00739 }
00740 return filterList;
00741 }
00742
00743 void AlbumDB::setUserFilterSettings(const QString &imageFilterString, const QString &videoFilterString, const QString &audioFilterString)
00744 {
00745 setUserFilterSettings(cleanUserFilterString(imageFilterString),
00746 cleanUserFilterString(videoFilterString),
00747 cleanUserFilterString(audioFilterString));
00748 }
00749
00750 void AlbumDB::setUserFilterSettings(const QStringList &imageFilter, const QStringList &videoFilter, const QStringList &audioFilter)
00751 {
00752 setSetting("databaseUserImageFormats", imageFilter.join(";"));
00753 setSetting("databaseUserVideoFormats", videoFilter.join(";"));
00754 setSetting("databaseUserAudioFormats", audioFilter.join(";"));
00755 }
00756
00757 void AlbumDB::addToUserImageFilterSettings(const QString &filterString)
00758 {
00759 QStringList addList = cleanUserFilterString(filterString);
00760
00761 QStringList currentList = getSetting("databaseUserImageFormats").split(';', QString::SkipEmptyParts);
00762
00763
00764 foreach(const QString &addedFilter, addList)
00765 {
00766 if (!currentList.contains(addedFilter))
00767 currentList << addedFilter;
00768 }
00769
00770 setSetting("databaseUserImageFormats", currentList.join(";"));
00771 }
00772
00773 QUuid AlbumDB::databaseUuid()
00774 {
00775 QString uuidString = getSetting("databaseUUID");
00776 QUuid uuid = QUuid(uuidString);
00777 if (uuidString.isNull() || uuid.isNull())
00778 {
00779 uuid = QUuid::createUuid();
00780 setSetting("databaseUUID", uuid.toString());
00781 }
00782 return uuid;
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 qlonglong AlbumDB::getImageId(int albumID, const QString& name)
00850 {
00851 QList<QVariant> values;
00852
00853 d->db->execSql( QString("SELECT id FROM Images "
00854 "WHERE album=? AND name=?;"),
00855 albumID,
00856 name,
00857 &values );
00858
00859 if (values.isEmpty())
00860 return -1;
00861 else
00862 return values.first().toLongLong();
00863 }
00864
00865 QStringList AlbumDB::getItemTagNames(qlonglong imageID)
00866 {
00867 QList<QVariant> values;
00868
00869 d->db->execSql( QString("SELECT name FROM Tags \n "
00870 "WHERE id IN (SELECT tagid FROM ImageTags \n "
00871 " WHERE imageid=?) \n "
00872 "ORDER BY name;"),
00873 imageID,
00874 &values );
00875
00876 QStringList names;
00877 for (QList<QVariant>::iterator it = values.begin(); it != values.end(); ++it)
00878 names << it->toString();
00879 return names;
00880 }
00881
00882 QList<int> AlbumDB::getItemTagIDs(qlonglong imageID)
00883 {
00884 QList<QVariant> values;
00885
00886 d->db->execSql( QString("SELECT tagid FROM ImageTags \n "
00887 "WHERE imageID=?;"),
00888 imageID,
00889 &values );
00890
00891 QList<int> ids;
00892
00893 if (values.isEmpty())
00894 return ids;
00895
00896 for (QList<QVariant>::iterator it=values.begin(); it != values.end(); ++it)
00897 ids << it->toInt();
00898 return ids;
00899 }
00900
00901 ItemShortInfo AlbumDB::getItemShortInfo(qlonglong imageID)
00902 {
00903 QList<QVariant> values;
00904
00905 d->db->execSql( QString("SELECT Images.name, Albums.albumRoot, Albums.relativePath, Albums.id "
00906 "FROM Images "
00907 " LEFT OUTER JOIN Albums ON Albums.id=Images.album "
00908 "WHERE Images.id=?;"),
00909 imageID,
00910 &values );
00911
00912 ItemShortInfo info;
00913
00914 if (!values.isEmpty())
00915 {
00916 info.id = imageID;
00917 info.itemName = values[0].toString();
00918 info.albumRootID = values[1].toInt();
00919 info.album = values[2].toString();
00920 info.albumID = values[3].toInt();
00921 }
00922
00923 return info;
00924 }
00925
00926 bool AlbumDB::hasTags(const QList<qlonglong>& imageIDList)
00927 {
00928 QList<int> ids;
00929
00930 if (imageIDList.isEmpty())
00931 return false;
00932
00933 QList<QVariant> values;
00934 QList<QVariant> boundValues;
00935
00936 QString sql = QString("SELECT count(tagid) FROM ImageTags "
00937 "WHERE imageid=? ");
00938 boundValues << imageIDList.first();
00939
00940 QList<qlonglong>::const_iterator it = imageIDList.begin();
00941 ++it;
00942 for (; it != imageIDList.end(); ++it)
00943 {
00944 sql += QString(" OR imageid=? ");
00945 boundValues << (*it);
00946 }
00947
00948 sql += QString(";");
00949 d->db->execSql( sql, boundValues, &values );
00950
00951 if (values.isEmpty() || values.first().toInt() == 0)
00952 return false;
00953 else
00954 return true;
00955 }
00956
00957 QList<int> AlbumDB::getItemCommonTagIDs(const QList<qlonglong>& imageIDList)
00958 {
00959 QList<int> ids;
00960
00961 if (imageIDList.isEmpty())
00962 return ids;
00963
00964 QList<QVariant> values;
00965 QList<QVariant> boundValues;
00966
00967 QString sql = QString("SELECT DISTINCT tagid FROM ImageTags "
00968 "WHERE imageid=? ");
00969 boundValues << imageIDList.first();
00970
00971 QList<qlonglong>::const_iterator it = imageIDList.begin();
00972 ++it;
00973 for (; it != imageIDList.end(); ++it)
00974 {
<