diff --git a/clocation.cpp b/clocation.cpp new file mode 100644 index 0000000..cb74e2e --- /dev/null +++ b/clocation.cpp @@ -0,0 +1,274 @@ +/*! + \file clocation.cpp + +*/ + + +#include "common.h" + +#include "clocation.h" + +#include +#include + +#include + + +cLocation::cLocation(qint32 iID, QObject *parent) : + QObject(parent), + m_iID(iID), + m_szName("") +{ +} + +bool cLocation::toDB() +{ + QSqlQuery query; + + if(m_iID != -1) + { + query.prepare("SELECT id FROM location WHERE id=:id;"); + query.bindValue(":id", m_iID); + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + if(!query.next()) + query.prepare("INSERT INTO location (name) VALUES (:name);"); + else + query.prepare("UPDATE location SET name=:name WHERE id=:id;"); + } + else + query.prepare("INSERT INTO location (name) VALUES (:name);"); + + + query.bindValue(":id", m_iID); + query.bindValue(":name", m_szName); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + if(m_iID == -1) + { + query.prepare("SELECT id FROM location WHERE _rowid_=(SELECT MAX(_rowid_) FROM location);"); + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + query.next(); + m_iID = query.value("id").toInt(); + } + + return(true); +} + +void cLocation::setID(const qint32& id) +{ + m_iID = id; +} + +qint32 cLocation::id() +{ + return(m_iID); +} + +void cLocation::setName(const QString &name) +{ + m_szName = name; +} + +QString cLocation::name() +{ + return(m_szName); +} + +bool cLocation::operator==(const cLocation& other) const +{ + if(this->m_szName != other.m_szName) + return(false); + + return(true); +} + +bool cLocation::operator==(const cLocation*& other) const +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +bool cLocation::operator==(const cLocation* other) const +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +bool cLocation::operator==(cLocation* other) +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +cLocationList::cLocationList(QObject *parent) : + QObject(parent) +{ +} + +bool cLocationList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) +{ + QSqlQuery query; + + query.prepare("SELECT COUNT(1) cnt FROM location;"); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + query.next(); + + qint32 max = static_cast(query.value("cnt").toLongLong()); + + if(lpProgressBar) + lpProgressBar->setMaximum(max); + else if(lpSplashScreen) + lpSplashScreen->setMax(max); + + query.prepare("SELECT id, " + " name " + "FROM location " + "ORDER BY UPPER(name);"); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + qint32 count = 0; + qint32 step = max/200; + + if(!step) + step = 1; + + while(query.next()) + { + cLocation* lpLocation = add(query.value("id").toInt(), true); + lpLocation->setName(query.value("name").toString()); + + count++; + if(!(count % step)) + { + if(lpProgressBar) + lpProgressBar->setValue(count); + else if(lpSplashScreen) + lpSplashScreen->setProgress(count); + qApp->processEvents(); + } + } + + return(true); +} + +cLocation* cLocationList::add(qint32 iID, bool bNoCheck) +{ + if(iID != -1 && !bNoCheck) + { + if(find(iID)) + return(nullptr); + } + + cLocation* lpNew = new cLocation(iID); + append(lpNew); + return(lpNew); +} + +bool cLocationList::add(cLocation* lpLocation, bool bNoCheck) +{ + if(bNoCheck) + { + append(lpLocation); + return(true); + } + + if(contains(lpLocation)) + return(false); + + append(lpLocation); + return(true); +} + +cLocation* cLocationList::find(qint32 iID) +{ + for(cLocationList::iterator i = begin(); i != end(); i++) + { + if((*i)->id() == iID) + return(*i); + } + return(nullptr); +} + +cLocation* cLocationList::find(cLocation* lpLocation) +{ + for(cLocationList::iterator i = begin(); i != end(); i++) + { + if(*lpLocation == (**i)) + return(*i); + } + return(nullptr); +} + +bool cLocationList::remove(cLocation* lpLocation) +{ + if(!find(lpLocation)) + return(true); + + QSqlQuery query; + + query.prepare("SELECT COUNT(1) cnt FROM picture_location WHERE locationID=:id;"); + query.bindValue(":id", lpLocation->id()); + + if(!query.exec()) + return(false); + + if(!query.next()) + return(false); + + if(query.value("cnt").toInt() != 0) + return(false); + + query.prepare("DELETE FROM location WHERE id=:id;"); + query.bindValue(":id", lpLocation->id()); + + if(!query.exec()) + return(false); + + this->removeOne(lpLocation); + delete lpLocation; + + return(true); +} + +QStringList cLocationList::locationList() +{ + QStringList szLocationList; + + for(cLocationList::iterator i = begin(); i != end();i++) + szLocationList.append((*i)->name()); + + szLocationList.removeDuplicates(); + szLocationList.sort(Qt::CaseInsensitive); + return(szLocationList); +} diff --git a/clocation.h b/clocation.h new file mode 100644 index 0000000..869014a --- /dev/null +++ b/clocation.h @@ -0,0 +1,205 @@ +/*! + \file clocation.h + +*/ + +#ifndef CLOCATION_H +#define CLOCATION_H + + +#include "csplashscreen.h" + +#include +#include + +#include + +#include + + +/*! + \brief + + \class cLocation clocation.h "clocation.h" +*/ +class cLocation : public QObject +{ + Q_OBJECT +public: + /*! + \brief + + \fn cLocation + \param parent + */ + explicit cLocation(qint32 iID = -1, QObject *parent = nullptr); + + /*! + \brief + + \fn toDB + \return bool + */ + bool toDB(); + + /*! + \brief + + \fn setID + \param id + */ + void setID(const qint32& id); + /*! + \brief + + \fn id + \return qint32 + */ + qint32 id(); + + /*! + \brief + + \fn setName + \param name + */ + void setName(const QString& name); + /*! + \brief + + \fn name + \return QString + */ + QString name(); + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(const cLocation& other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(const cLocation*& other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(const cLocation* other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(cLocation* other); + +signals: + +public slots: + +private: + qint32 m_iID; /*!< TODO: describe */ + QString m_szName; /*!< TODO: describe */ +}; + +Q_DECLARE_METATYPE(cLocation*) + +/*! + \brief + + \class ccLocation clocation.h "clocation.h" +*/ +class cLocationList : public QObject, public QList +{ + Q_OBJECT +public: + /*! + \brief + + \fn cLocationList + \param parent + */ + explicit cLocationList(QObject *parent = nullptr); + + /*! + \brief + + \fn load + \param lpSplashScreen + \param lpProgressBar + \return bool + */ + bool load(cSplashScreen* lpSplashScreen, QProgressBar* lpProgressBar = nullptr); + + /*! + \brief + + \fn add + \param iID + \param bNoCheck + \return cLocation + */ + cLocation* add(qint32 iID = -1, bool bNoCheck = false); + /*! + \brief + + \fn add + \param cLocation + \param bNoCheck + \return bool + */ + bool add(cLocation* lpLocation, bool bNoCheck = false); + + /*! + \brief + + \fn find + \param iID + \return cTag + */ + cLocation* find(qint32 iID); + /*! + \brief + + \fn find + \param iID + \return cTag + */ + cLocation* find(cLocation* lpLocation); + /*! + \brief + + \fn remove + \param lpLocation + \return bool + */ + bool remove(cLocation* lpLocation); + + /*! + \brief + + \fn locationList + \return QStringList + */ + QStringList locationList(); +signals: + +public slots: +}; + +#endif // CLOCATION_H diff --git a/cmainwindow.cpp b/cmainwindow.cpp index cbfcd2f..03eddad 100644 --- a/cmainwindow.cpp +++ b/cmainwindow.cpp @@ -153,11 +153,11 @@ void cMainWindow::loadData(bool bProgressBar) m_personList.load(m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); ui->m_lpToolBoxPerson->setPersonList(&m_personList); - m_flagList.clear(); - m_flagList.load(m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); + m_tagList.clear(); + m_tagList.load(m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); m_pictureList.clear(); - m_pictureList.load(m_personList, m_flagList, m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); + m_pictureList.load(m_personList, m_tagList, m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); displayData(); diff --git a/cmainwindow.h b/cmainwindow.h index 2cdc443..c38ad91 100644 --- a/cmainwindow.h +++ b/cmainwindow.h @@ -10,7 +10,7 @@ #include "cpicturelibrary.h" #include "csplashscreen.h" #include "cpicture.h" -#include "cflag.h" +#include "ctag.h" #include "cperson.h" #include "cfoldersortfilterproxymodel.h" @@ -76,7 +76,7 @@ private: cPictureLibrary m_pictureLibrary; /*!< TODO: describe */ cPictureList m_pictureList; /*!< TODO: describe */ cPersonList m_personList; /*!< TODO: describe */ - cFlagList m_flagList; /*!< TODO: describe */ + cTagList m_tagList; /*!< TODO: describe */ QMenu* m_lpFileMenu; /*!< TODO: describe */ diff --git a/cmainwindow.ui b/cmainwindow.ui index 3ddbc3e..73f5cda 100644 --- a/cmainwindow.ui +++ b/cmainwindow.ui @@ -107,7 +107,7 @@ - 1 + 3 @@ -115,7 +115,7 @@ 0 0 69 - 510 + 483 @@ -128,24 +128,37 @@ 0 0 69 - 510 + 483 Person - + 0 0 69 - 510 + 483 - Flags + Location + + + + + + 0 + 0 + 69 + 483 + + + + Tags @@ -196,6 +209,18 @@
ctoolboxperson.h
1 + + cToolBoxLocation + QWidget +
ctoolboxlocation.h
+ 1 +
+ + ctoolBoxTag + QWidget +
ctoolboxtag.h
+ 1 +
diff --git a/cperson.h b/cperson.h index 53fb5be..03de22e 100644 --- a/cperson.h +++ b/cperson.h @@ -122,7 +122,7 @@ Q_DECLARE_METATYPE(cPerson*) /*! \brief - \class cFlagList cflag.h "cflag.h" + \class cPersonList cperson.h "cperson.h" */ class cPersonList : public QObject, public QList { diff --git a/cpicture.cpp b/cpicture.cpp index 75fab64..cbb68cc 100644 --- a/cpicture.cpp +++ b/cpicture.cpp @@ -173,16 +173,16 @@ bool cPicture::toDB() query.exec(); } - query.prepare("DELETE FROM picture_flag WHERE pictureID=:pictureID;"); + query.prepare("DELETE FROM picture_tag WHERE pictureID=:pictureID;"); query.bindValue(":pictureID", m_iID); query.exec(); - query.prepare("INSERT INTO picture_flag (pictureID, flagID) VALUES (:pictureID, :flagID);"); + query.prepare("INSERT INTO picture_tag (pictureID, tagID) VALUES (:pictureID, :tagID);"); query.bindValue(":pictureID", m_iID); - for(cFlagList::iterator i = m_flagList.begin();i != m_flagList.end();i++) + for(cTagList::iterator i = m_tagList.begin();i != m_tagList.end();i++) { - query.bindValue(":flagID", (*i)->id()); + query.bindValue(":tagID", (*i)->id()); query.exec(); } @@ -512,27 +512,50 @@ cPersonList& cPicture::personList() return(m_personList); } -void cPicture::addFlag(cFlag* lpFlag) +void cPicture::addLocation(cLocation* lpLocation) { - if(m_flagList.contains(lpFlag)) + if(m_locationList.contains(lpLocation)) return; - m_flagList.add(lpFlag); + m_locationList.add(lpLocation); } -void cPicture::removeFlag(cFlag* lpFlag) +void cPicture::removeLocation(cLocation* lpLocation) { - if(m_flagList.contains(lpFlag)) - m_flagList.removeAll(lpFlag); + if(m_tagList.contains(lpTag)) + m_tagList.removeAll(lpTag); } -void cPicture::clearFlagList() +void cPicture::clearLocationList() { - m_flagList.clear(); + m_locationList.clear(); } -cFlagList& cPicture::flagList() +cLocationList& cPicture::locationList() { - return(m_flagList); + return(m_locationList); +} + +void cPicture::addTag(cTag* lpTag) +{ + if(m_tagList.contains(lpTag)) + return; + m_tagList.add(lpTag); +} + +void cPicture::removeTag(cTag* lpTag) +{ + if(m_tagList.contains(lpTag)) + m_tagList.removeAll(lpTag); +} + +void cPicture::clearTagList() +{ + m_tagList.clear(); +} + +cTagList& cPicture::tagList() +{ + return(m_tagList); } bool cPicture::operator==(const cPicture& other) const @@ -764,7 +787,7 @@ cPictureList::cPictureList(QObject *parent) : { } -bool cPictureList::load(cPersonList& personList, cFlagList& flagList, cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) +bool cPictureList::load(cPersonList& personList, cLocationList& locationList, cTagList& tagList, cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) { cEXIFFlashList flashList; QSqlQuery query; @@ -924,7 +947,7 @@ bool cPictureList::load(cPersonList& personList, cFlagList& flagList, cSplashScr } } - query.prepare("SELECT COUNT(1) cnt FROM picture_flag;"); + query.prepare("SELECT COUNT(1) cnt FROM picture_location;"); if(!query.exec()) { @@ -941,8 +964,8 @@ bool cPictureList::load(cPersonList& personList, cFlagList& flagList, cSplashScr lpSplashScreen->setMax(max); query.prepare("SELECT pictureID, " - " flagID " - "FROM picture_flag;"); + " locationID " + "FROM picture_location;"); if(!query.exec()) { @@ -959,10 +982,61 @@ bool cPictureList::load(cPersonList& personList, cFlagList& flagList, cSplashScr while(query.next()) { cPicture* lpPicture = find(query.value("pictureID").toInt()); - cFlag* lpFlag = flagList.find(query.value("flagID").toInt()); + cLocation* lpLocation = locationList.find(query.value("locationID").toInt()); - if(lpPicture && lpFlag) - lpPicture->addFlag(lpFlag); + if(lpPicture && lpLocation) + lpPicture->addLocation(lpLocation); + + count++; + if(!(count % step)) + { + if(lpProgressBar) + lpProgressBar->setValue(count); + else if(lpSplashScreen) + lpSplashScreen->setProgress(count); + qApp->processEvents(); + } + } + + query.prepare("SELECT COUNT(1) cnt FROM picture_tag;"); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + query.next(); + + max = static_cast(query.value("cnt").toLongLong()); + + if(lpProgressBar) + lpProgressBar->setMaximum(max); + else if(lpSplashScreen) + lpSplashScreen->setMax(max); + + query.prepare("SELECT pictureID, " + " tagID " + "FROM picture_tag;"); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + count = 0; + step = max/200; + + if(!step) + step = 1; + + while(query.next()) + { + cPicture* lpPicture = find(query.value("pictureID").toInt()); + cTag* lpTag = tagList.find(query.value("tagID").toInt()); + + if(lpPicture && lpTag) + lpPicture->addTag(lpTag); count++; if(!(count % step)) diff --git a/cpicture.h b/cpicture.h index 8d20a53..84e84de 100644 --- a/cpicture.h +++ b/cpicture.h @@ -10,7 +10,8 @@ #include "csplashscreen.h" #include "cperson.h" -#include "cflag.h" +#include "clocation.h" +#include "ctag.h" #include #include @@ -537,30 +538,58 @@ public: /*! \brief - \fn addFlag - \param lpFlag + \fn addLocation + \param lpLocation */ - void addFlag(cFlag* lpFlag); + void addLocation(cLocation* lpLocation); /*! \brief - \fn removeFlag - \param lpFlag + \fn removeLocation + \param lpLocation */ - void removeFlag(cFlag* lpFlag); + void removeLocation(cLocation* lpLocation); /*! \brief - \fn clearFlagList + \fn clearLocationList */ - void clearFlagList(); + void clearLocationList(); /*! \brief - \fn flagList - \return cFlagList + \fn tagList + \return cLocationList */ - cFlagList& flagList(); + cLocationList& locationList(); + + /*! + \brief + + \fn addTag + \param lpTag + */ + void addTag(cTag* lpTag); + /*! + \brief + + \fn removeTag + \param lpTag + */ + void removeTag(cTag* lpTag); + /*! + \brief + + \fn clearTagList + */ + void clearTagList(); + /*! + \brief + + \fn tagList + \return cTagList + */ + cTagList& tagList(); /*! \brief @@ -635,7 +664,8 @@ private: bool m_hdr; /*!< TODO: describe */ cPersonList m_personList; /*!< TODO: describe */ - cFlagList m_flagList; /*!< TODO: describe */ + cLocationList m_locationList; /*!< TODO: describe */ + cTagList m_tagList; /*!< TODO: describe */ }; Q_DECLARE_METATYPE(cPicture*) @@ -665,7 +695,7 @@ public: \param lpProgressBar \return bool */ - bool load(cPersonList& personList, cFlagList& flagList, cSplashScreen* lpSplashScreen, QProgressBar* lpProgressBar = nullptr); + bool load(cPersonList& personList, cLocationList& locationList, cTagList& tagList, cSplashScreen* lpSplashScreen, QProgressBar* lpProgressBar = nullptr); /*! \brief diff --git a/cpicturelibrary.cpp b/cpicturelibrary.cpp index 46ce5a4..555189f 100644 --- a/cpicturelibrary.cpp +++ b/cpicturelibrary.cpp @@ -138,21 +138,27 @@ bool cPictureLibrary::createDatabase() "); ")) return(false); - if(!createTable("CREATE TABLE flags ( " + if(!createTable("CREATE TABLE location ( " " id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, " " name TEXT " "); ")) return(false); - if(!createTable("CREATE TABLE picture_flags ( " - " pictureID INTEGER REFERENCES picture (id), " - " flagsID INTEGER REFERENCES flags (id) " + if(!createTable("CREATE TABLE tag ( " + " id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, " + " name TEXT " "); ")) return(false); - if(!createTable("CREATE UNIQUE INDEX picture_flag_idx ON picture_flags ( " + if(!createTable("CREATE TABLE picture_tag ( " + " pictureID INTEGER REFERENCES picture (id), " + " tagID INTEGER REFERENCES tag (id) " + "); ")) + return(false); + + if(!createTable("CREATE UNIQUE INDEX picture_tag_idx ON picture_tag ( " " pictureID, " - " flagsID " + " tagID " "); ")) return(false); @@ -168,6 +174,18 @@ bool cPictureLibrary::createDatabase() "); ")) return(false); + if(!createTable("CREATE TABLE picture_location ( " + " pictureID INTEGER REFERENCES picture (id), " + " locationID INTEGER REFERENCES location (id) " + "); ")) + return(false); + + if(!createTable("CREATE UNIQUE INDEX picture_location_idx ON picture_location ( " + " pictureID, " + " personID " + "); ")) + return(false); + query.prepare("INSERT INTO config (version) VALUES (:version);"); query.bindValue(":version", 1); if(!query.exec()) diff --git a/ctag.cpp b/ctag.cpp index 14bfae0..949b6bf 100644 --- a/ctag.cpp +++ b/ctag.cpp @@ -1,11 +1,12 @@ /*! - \file cFlag.cpp + \file cTag.cpp */ + #include "common.h" -#include "cflag.h" +#include "ctag.h" #include #include @@ -13,20 +14,20 @@ #include -cFlag::cFlag(qint32 iID, QObject *parent) : +cTag::cTag(qint32 iID, QObject *parent) : QObject(parent), m_iID(iID), m_szName("") { } -bool cFlag::toDB() +bool cTag::toDB() { QSqlQuery query; if(m_iID != -1) { - query.prepare("SELECT id FROM flag WHERE id=:id;"); + query.prepare("SELECT id FROM tag WHERE id=:id;"); query.bindValue(":id", m_iID); if(!query.exec()) { @@ -35,12 +36,12 @@ bool cFlag::toDB() } if(!query.next()) - query.prepare("INSERT INTO flag (name) VALUES (:name);"); + query.prepare("INSERT INTO tag (name) VALUES (:name);"); else - query.prepare("UPDATE flag SET name=:name WHERE id=:id;"); + query.prepare("UPDATE tag SET name=:name WHERE id=:id;"); } else - query.prepare("INSERT INTO flag (name) VALUES (:name);"); + query.prepare("INSERT INTO tag (name) VALUES (:name);"); query.bindValue(":id", m_iID); @@ -54,7 +55,7 @@ bool cFlag::toDB() if(m_iID == -1) { - query.prepare("SELECT id FROM flag WHERE _rowid_=(SELECT MAX(_rowid_) FROM flag);"); + query.prepare("SELECT id FROM tag WHERE _rowid_=(SELECT MAX(_rowid_) FROM tag);"); if(!query.exec()) { myDebug << query.lastError().text(); @@ -68,27 +69,27 @@ bool cFlag::toDB() return(true); } -void cFlag::setID(const qint32& id) +void cTag::setID(const qint32& id) { m_iID = id; } -qint32 cFlag::id() +qint32 cTag::id() { return(m_iID); } -void cFlag::setName(const QString &name) +void cTag::setName(const QString &name) { m_szName = name; } -QString cFlag::name() +QString cTag::name() { return(m_szName); } -bool cFlag::operator==(const cFlag& other) const +bool cTag::operator==(const cTag& other) const { if(this->m_szName != other.m_szName) return(false); @@ -96,7 +97,7 @@ bool cFlag::operator==(const cFlag& other) const return(true); } -bool cFlag::operator==(const cFlag*& other) const +bool cTag::operator==(const cTag*& other) const { if(this->m_szName != other->m_szName) return(false); @@ -104,7 +105,7 @@ bool cFlag::operator==(const cFlag*& other) const return(true); } -bool cFlag::operator==(const cFlag* other) const +bool cTag::operator==(const cTag* other) const { if(this->m_szName != other->m_szName) return(false); @@ -112,7 +113,7 @@ bool cFlag::operator==(const cFlag* other) const return(true); } -bool cFlag::operator==(cFlag* other) +bool cTag::operator==(cTag* other) { if(this->m_szName != other->m_szName) return(false); @@ -120,16 +121,16 @@ bool cFlag::operator==(cFlag* other) return(true); } -cFlagList::cFlagList(QObject *parent) : +cTagList::cTagList(QObject *parent) : QObject(parent) { } -bool cFlagList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) +bool cTagList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) { QSqlQuery query; - query.prepare("SELECT COUNT(1) cnt FROM flag;"); + query.prepare("SELECT COUNT(1) cnt FROM tag;"); if(!query.exec()) { @@ -147,7 +148,7 @@ bool cFlagList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) query.prepare("SELECT id, " " name " - "FROM flag " + "FROM tag " "ORDER BY UPPER(name);"); if(!query.exec()) @@ -164,8 +165,8 @@ bool cFlagList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) while(query.next()) { - cFlag* lpFlag = add(query.value("id").toInt(), true); - lpFlag->setName(query.value("name").toString()); + cTag* lpTag = add(query.value("id").toInt(), true); + lpTag->setName(query.value("name").toString()); count++; if(!(count % step)) @@ -181,7 +182,7 @@ bool cFlagList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) return(true); } -cFlag* cFlagList::add(qint32 iID, bool bNoCheck) +cTag* cTagList::add(qint32 iID, bool bNoCheck) { if(iID != -1 && !bNoCheck) { @@ -189,29 +190,29 @@ cFlag* cFlagList::add(qint32 iID, bool bNoCheck) return(nullptr); } - cFlag* lpNew = new cFlag(iID); + cTag* lpNew = new cTag(iID); append(lpNew); return(lpNew); } -bool cFlagList::add(cFlag* lpFlag, bool bNoCheck) +bool cTagList::add(cTag* lpTag, bool bNoCheck) { if(bNoCheck) { - append(lpFlag); + append(lpTag); return(true); } - if(contains(lpFlag)) + if(contains(lpTag)) return(false); - append(lpFlag); + append(lpTag); return(true); } -cFlag* cFlagList::find(qint32 iID) +cTag* cTagList::find(qint32 iID) { - for(cFlagList::iterator i = begin(); i != end(); i++) + for(cTagList::iterator i = begin(); i != end(); i++) { if((*i)->id() == iID) return(*i); @@ -219,24 +220,24 @@ cFlag* cFlagList::find(qint32 iID) return(nullptr); } -cFlag* cFlagList::find(cFlag* lpFlag) +cTag* cTagList::find(cTag* lpTag) { - for(cFlagList::iterator i = begin(); i != end(); i++) + for(cTagList::iterator i = begin(); i != end(); i++) { - if(*lpFlag == (**i)) + if(*lpTag == (**i)) return(*i); } return(nullptr); } -QStringList cFlagList::flagList() +QStringList cTagList::tagList() { - QStringList szFlagList; + QStringList szTagList; - for(cFlagList::iterator i = begin(); i != end();i++) - szFlagList.append((*i)->name()); + for(cTagList::iterator i = begin(); i != end();i++) + szTagList.append((*i)->name()); - szFlagList.removeDuplicates(); - szFlagList.sort(Qt::CaseInsensitive); - return(szFlagList); + szTagList.removeDuplicates(); + szTagList.sort(Qt::CaseInsensitive); + return(szTagList); } diff --git a/ctag.h b/ctag.h index 6bdb78a..a11908a 100644 --- a/ctag.h +++ b/ctag.h @@ -1,10 +1,10 @@ /*! - \file cFlag.h + \file ctag.h */ -#ifndef cFlag_H -#define cFlag_H +#ifndef CTAG_H +#define CTAG_H #include "csplashscreen.h" @@ -20,19 +20,19 @@ /*! \brief - \class cFlag cflag.h "cflag.h" + \class cTag ctag.h "ctag.h" */ -class cFlag : public QObject +class cTag : public QObject { Q_OBJECT public: /*! \brief - \fn cFlag + \fn cTag \param parent */ - explicit cFlag(qint32 iID = -1, QObject *parent = nullptr); + explicit cTag(qint32 iID = -1, QObject *parent = nullptr); /*! \brief @@ -79,7 +79,7 @@ public: \param other \return bool */ - bool operator==(const cFlag& other) const; + bool operator==(const cTag& other) const; /*! \brief @@ -88,7 +88,7 @@ public: \param other \return bool */ - bool operator==(const cFlag*& other) const; + bool operator==(const cTag*& other) const; /*! \brief @@ -97,7 +97,7 @@ public: \param other \return bool */ - bool operator==(const cFlag* other) const; + bool operator==(const cTag* other) const; /*! \brief @@ -106,7 +106,7 @@ public: \param other \return bool */ - bool operator==(cFlag* other); + bool operator==(cTag* other); signals: @@ -117,24 +117,24 @@ private: QString m_szName; /*!< TODO: describe */ }; -Q_DECLARE_METATYPE(cFlag*) +Q_DECLARE_METATYPE(cTag*) /*! \brief - \class cFlagList cflag.h "cflag.h" + \class cTagList ctag.h "ctag.h" */ -class cFlagList : public QObject, public QList +class cTagList : public QObject, public QList { Q_OBJECT public: /*! \brief - \fn cFlagList + \fn cTagList \param parent */ - explicit cFlagList(QObject *parent = nullptr); + explicit cTagList(QObject *parent = nullptr); /*! \brief @@ -152,46 +152,46 @@ public: \fn add \param iID \param bNoCheck - \return cFlag + \return cTag */ - cFlag* add(qint32 iID = -1, bool bNoCheck = false); + cTag* add(qint32 iID = -1, bool bNoCheck = false); /*! \brief \fn add - \param cFlag + \param cTag \param bNoCheck \return bool */ - bool add(cFlag* lpFlag, bool bNoCheck = false); + bool add(cTag* lpTag, bool bNoCheck = false); /*! \brief \fn find \param iID - \return cFlag + \return cTag */ - cFlag* find(qint32 iID); + cTag* find(qint32 iID); /*! \brief \fn find \param iID - \return cFlag + \return cTag */ - cFlag* find(cFlag* lpFlag); + cTag* find(cTag* lpTag); /*! \brief - \fn flagList + \fn tagList \return QStringList */ - QStringList flagList(); + QStringList tagList(); signals: public slots: }; -#endif // cFlag_H +#endif // CTAG_H diff --git a/ctoolboxlocation.cpp b/ctoolboxlocation.cpp index 71655e9..bb06e67 100644 --- a/ctoolboxlocation.cpp +++ b/ctoolboxlocation.cpp @@ -1,14 +1,297 @@ #include "ctoolboxlocation.h" #include "ui_ctoolboxlocation.h" +#include +#include + +#include + +#include + + cToolBoxLocation::cToolBoxLocation(QWidget *parent) : QWidget(parent), - ui(new Ui::cToolBoxLocation) + ui(new Ui::cToolBoxLocation), + m_bLoading(true), + m_bEditing(false) { - ui->setupUi(this); + initUI(); + createActions(); } cToolBoxLocation::~cToolBoxLocation() { delete ui; } + +void cToolBoxLocation::initUI() +{ + ui->setupUi(this); + + m_lpLocationListModel = new QStandardItemModel; + ui->m_lpLocationList->setModel(m_lpLocationListModel); + + ui->m_lpEdit->setEnabled(false); + ui->m_lpDelete->setEnabled(false); +} + +void cToolBoxLocation::createActions() +{ + m_lpLocationAddAction = new QAction(tr("add location"), this); + m_lpLocationAddAction->setStatusTip(tr("add a new location")); + connect(m_lpLocationAddAction, &QAction::triggered, this, &cToolBoxLocation::onLocationAdd); + connect(ui->m_lpAdd, &QPushButton::clicked, this, &cToolBoxLocation::onLocationAdd); + + m_lpLocationEditAction = new QAction(tr("edit location"), this); + m_lpLocationEditAction->setStatusTip(tr("edit this location")); + connect(m_lpLocationEditAction, &QAction::triggered, this, &cToolBoxLocation::onLocationEdit); + connect(ui->m_lpEdit, &QPushButton::clicked, this, &cToolBoxLocation::onLocationEdit); + + m_lpLocationDeleteAction = new QAction(tr("delete location"), this); + m_lpLocationDeleteAction->setStatusTip(tr("delete this location")); + connect(m_lpLocationDeleteAction, &QAction::triggered, this, &cToolBoxLocation::onLocationDelete); + connect(ui->m_lpDelete, &QPushButton::clicked, this, &cToolBoxLocation::onLocationDelete); + + connect(ui->m_lpLocationList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cToolBoxLocation::onLocationSelected); + + connect(m_lpLocationListModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), SLOT(personChanged(QModelIndex, QModelIndex, QVector))); + connect(ui->m_lpLocationList, &QTreeView::customContextMenuRequested, this, &cToolBoxLocation::onLocationViewContextMenu); + connect(m_lpLocationListModel, &QStandardItemModel::itemChanged, this, &cToolBoxLocation::onLocationChanged); +} + +void cToolBoxLocation::setLocationList(cLocationList* lpLocationList) +{ + m_bLoading = true; + + m_lpLocationList = lpLocationList; + + for(cLocationList::iterator i = lpLocationList->begin();i != lpLocationList->end();i++) + { + QStandardItem* lpItem = new QStandardItem((*i)->name()); + lpItem->setData(QVariant::fromValue(*i), Qt::UserRole+1); + lpItem->setCheckable(true); + m_lpLocationListModel->appendRow(lpItem); + } + + m_bLoading = false; +} + +void cToolBoxLocation::setPicture(cPictureList& pictureList) +{ + m_bLoading = true; + + m_pictureList.clear(); + + for(int i = 0;i < m_lpLocationListModel->rowCount();i++) + { + QStandardItem* lpItem = m_lpLocationListModel->item(i, 0); + lpItem->setCheckState(Qt::Unchecked); + } + + if(!pictureList.count()) + { + m_bLoading = false; + return; + } + + QHash list; + qint32 count = pictureList.count(); + + for(cPictureList::iterator i = pictureList.begin();i != pictureList.end();i++) + { + m_pictureList.add(*i, true); + cPersonList& personList = (*i)->personList(); + + for(cPersonList::iterator j = personList.begin();j != personList.end();j++) + { + if(list.contains((*j)->id())) + list[(*j)->id()] ++; + else + list.insert((*j)->id(), 1); + } + } + + for(int i = 0;i < m_lpLocationListModel->rowCount();i++) + { + QStandardItem* lpItem = m_lpLocationListModel->item(i, 0); + cPerson* lpPerson = lpItem->data().value(); + + if(list.contains(lpPerson->id())) + { + if(list[lpPerson->id()] == count) + lpItem->setCheckState(Qt::Checked); + else + lpItem->setCheckState(Qt::PartiallyChecked); + } + } + m_bLoading = false; +} + +void cToolBoxLocation::onLocationSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/) +{ + if(ui->m_lpLocationList->selectionModel()->selectedIndexes().count() == 1) + { + ui->m_lpEdit->setEnabled(true); + ui->m_lpDelete->setEnabled(true); + } + else if(ui->m_lpLocationList->selectionModel()->selectedIndexes().count() > 1) + { + ui->m_lpEdit->setEnabled(false); + ui->m_lpDelete->setEnabled(true); + } +} + +void cToolBoxLocation::locationChanged(const QModelIndex& /*topLeft*/, const QModelIndex& /*bottomright*/, const QVector& /*roles*/) +{ + if(!m_pictureList.count()) + return; + + if(m_bLoading) + return; + + for(int x = 0;x < m_lpLocationListModel->rowCount();x++) + { + QStandardItem* lpItem = m_lpLocationListModel->item(x, 0); + + if(lpItem->checkState() != Qt::PartiallyChecked) + { + cPerson* lpPerson = lpItem->data(Qt::UserRole+1).value(); + if(lpPerson) + { + for(cPictureList::iterator i = m_pictureList.begin();i != m_pictureList.end();i++) + { + if(lpItem->checkState() == Qt::Checked) + (*i)->addPerson(lpPerson); + else if(lpItem->checkState() == Qt::Unchecked) + (*i)->removePerson(lpPerson); + } + } + } + } + + for(cPictureList::iterator i = m_pictureList.begin();i != m_pictureList.end();i++) + (*i)->toDB(); +} + +void cToolBoxLocation::onLocationAdd() +{ + QInputDialog input(this); + + input.setLabelText(tr("name:")); + input.setWindowTitle(tr("New Location")); + if(input.exec() == QDialog::Rejected) + return; + + if(input.textValue().isEmpty()) + return; + + cLocation* lpLocation = new cLocation; + lpLocation->setName(input.textValue()); + if(!lpLocation->toDB()) + { + delete lpLocation; + return; + } + + m_lpLocationList->add(lpLocation); + + m_bLoading = true; + + QStandardItem* lpItem = new QStandardItem(lpLocation->name()); + lpItem->setData(QVariant::fromValue(lpLocation), Qt::UserRole+1); + lpItem->setCheckable(true); + m_lpLocationListModel->appendRow(lpItem); + m_lpLocationListModel->sort(0); + + m_bLoading = false; +} + +void cToolBoxLocation::onLocationEdit() +{ + if(ui->m_lpLocationList->selectionModel()->selectedIndexes().count() != 1) + return; + + QStandardItem* lpItem = m_lpLocationListModel->itemFromIndex(ui->m_lpLocationList->selectionModel()->selectedIndexes()[0]); + if(!lpItem) + return; + + cLocation* lpLocation = lpItem->data(Qt::UserRole+1).value(); + if(!lpLocation) + return; + + QInputDialog input(this); + + input.setLabelText(tr("name:")); + input.setWindowTitle(tr("Edit Location")); + input.setTextValue(lpLocation->name()); + + if(input.exec() == QDialog::Rejected) + return; + + if(input.textValue().isEmpty()) + return; + + lpItem->setText(input.textValue()); +} + +void cToolBoxLocation::onLocationDelete() +{ + for(int x = ui->m_lpLocationList->selectionModel()->selectedIndexes().count()-1;x >= 0; x--) + { + QModelIndex index = ui->m_lpLocationList->selectionModel()->selectedIndexes()[x]; + QStandardItem* lpItem = m_lpLocationListModel->itemFromIndex(index); + if(lpItem) + { + cLocation* lpLocation = lpItem->data(Qt::UserRole+1).value(); + if(lpLocation) + { + if(QMessageBox::question(this, tr("Delete Location"), QString(tr("Are you sure you want to delete %1?")).arg(lpLocation->name())) == QMessageBox::Yes) + { + if(!m_lpLocationList->remove(lpLocation)) + QMessageBox::critical(this, tr("Delete Location"), QString(tr("%1 is in use and can't be deleted!")).arg(lpLocation->name())); + else + m_lpLocationListModel->removeRow(index.row()); + } + } + } + } + +} + +void cToolBoxLocation::onLocationViewContextMenu(const QPoint& pos) +{ + QMenu menu(this); + + menu.addAction(m_lpLocationAddAction); + + if(ui->m_lpLocationList->selectionModel()->selectedIndexes().count() == 1) + menu.addAction(m_lpLocationEditAction); + if(ui->m_lpLocationList->selectionModel()->selectedIndexes().count() >= 1) + menu.addAction(m_lpLocationDeleteAction); + + menu.exec(ui->m_lpLocationList->mapToGlobal(pos)); +} + +void cToolBoxLocation::onLocationChanged(QStandardItem* lpItem) +{ + if(m_bEditing) + return; + + cPerson* lpPerson = lpItem->data(Qt::UserRole+1).value(); + if(!lpPerson) + return; + + if(lpItem->text() == lpPerson->name()) + return; + + QString szOldName = lpPerson->name(); + lpPerson->setName(lpItem->text()); + if(!lpPerson->toDB()) + { + QMessageBox::critical(this, tr("ERROR"), QString(tr("%1 already exists.").arg(lpItem->text()))); + m_bEditing = true; + lpItem->setText(szOldName); + lpPerson->setName(szOldName); + m_bEditing = false; + } +} diff --git a/ctoolboxlocation.h b/ctoolboxlocation.h new file mode 100644 index 0000000..b7aa51c --- /dev/null +++ b/ctoolboxlocation.h @@ -0,0 +1,142 @@ +/*! + \file ctoolboxlocation.h + +*/ + +#ifndef CTOOLBOXLOCATION_H +#define CTOOLBOXLOCATION_H + + +#include "clocation.h" +#include "cpicture.h" + +#include +#include +#include + + +namespace Ui { +class cToolBoxLocation; +} + +/*! + \brief + + \class cToolBoxLocation ctoolboxlocation.h "ctoolboxlocation.h" +*/ +class cToolBoxLocation : public QWidget +{ + Q_OBJECT + +public: + /*! + \brief + + \fn cToolBoxLocation + \param parent + */ + explicit cToolBoxLocation(QWidget *parent = nullptr); + /*! + \brief + + \fn ~cToolBoxLocation + */ + ~cToolBoxLocation(); + + /*! + \brief + + \param lpLocationList + \fn setLocationList + */ + void setLocationList(cLocationList* lpLocationList); + + /*! + \brief + + \fn setPicture + \param pictureList + */ + void setPicture(cPictureList& pictureList); + +private: + Ui::cToolBoxLocation* ui; /*!< TODO: describe */ + QStandardItemModel* m_lpLocationListModel; /*!< TODO: describe */ + cLocationList* m_lpLocationList; /*!< TODO: describe */ + cPictureList m_pictureList; /*!< TODO: describe */ + bool m_bLoading; /*!< TODO: describe */ + + QAction* m_lpLocationAddAction; /*!< TODO: describe */ + QAction* m_lpLocationEditAction; /*!< TODO: describe */ + QAction* m_lpLocationDeleteAction; /*!< TODO: describe */ + + bool m_bEditing; /*!< TODO: describe */ + + /*! + \brief + + \fn initUI + */ + void initUI(); + /*! + \brief + + \fn createActions + */ + void createActions(); + +private slots: + /*! + \brief + + \fn onLocationSelected + \param selection + \param previous + */ + void onLocationSelected(const QItemSelection& selection, const QItemSelection& previous); + /*! + \brief + + \fn locationChanged + \param topLeft + \param bottomright + \param roles + */ + void locationChanged(const QModelIndex& topLeft, const QModelIndex& bottomright, const QVector& roles); + /*! + \brief + + \fn onLocationAdd + */ + void onLocationAdd(); + /*! + \brief + + \fn onLocationEdit + */ + void onLocationEdit(); + /*! + \brief + + \fn onLocationDelete + */ + void onLocationDelete(); + + /*! + \brief + + \fn onLocationViewContextMenu + \param pos + */ + void onLocationViewContextMenu(const QPoint& pos); + + /*! + \brief + + \fn onLocationChanged + \param lpItem + */ + void onLocationChanged(QStandardItem* lpItem); +}; + +#endif // CTOOLBOXLOCATION_H diff --git a/ctoolboxlocation.ui b/ctoolboxlocation.ui new file mode 100644 index 0000000..3ad1167 --- /dev/null +++ b/ctoolboxlocation.ui @@ -0,0 +1,85 @@ + + + cToolBoxLocation + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed + + + true + + + QAbstractItemView::ExtendedSelection + + + false + + + false + + + + + + + + + add + + + + + + + edit + + + + + + + delete + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + diff --git a/pictureLibrary.pro b/pictureLibrary.pro index 5d4ad41..927c15b 100644 --- a/pictureLibrary.pro +++ b/pictureLibrary.pro @@ -69,11 +69,14 @@ SOURCES += \ ccopier.cpp \ cdatepicker.cpp \ ccombopicker.cpp \ - cflag.cpp \ cperson.cpp \ ctoolboxperson.cpp \ clabel.cpp \ - cimageviewer.cpp + cimageviewer.cpp \ + ctag.cpp \ + clocation.cpp \ + ctoolboxlocation.cpp \ + ctoolboxtag.cpp HEADERS += \ cmainwindow.h \ @@ -91,11 +94,14 @@ HEADERS += \ ccopier.h \ cdatepicker.h \ ccombopicker.h \ - cflag.h \ cperson.h \ ctoolboxperson.h \ clabel.h \ - cimageviewer.h + cimageviewer.h \ + ctag.h \ + clocation.h \ + ctoolboxlocation.h \ + ctoolboxtag.h FORMS += \ cmainwindow.ui \ @@ -105,7 +111,9 @@ FORMS += \ cdatepicker.ui \ ccombopicker.ui \ ctoolboxperson.ui \ - cimageviewer.ui + cimageviewer.ui \ + ctoolboxlocation.ui \ + ctoolboxtag.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin