diff --git a/ccombopicker.cpp b/ccombopicker.cpp new file mode 100644 index 0000000..7c91879 --- /dev/null +++ b/ccombopicker.cpp @@ -0,0 +1,59 @@ +#include "ccombopicker.h" +#include "ui_ccombopicker.h" + + +cComboPicker::cComboPicker(QWidget *parent) : + QDialog(parent), + ui(new Ui::cComboPicker) +{ + ui->setupUi(this); + ui->m_lpText->setVisible(false); + ui->m_lpPicture->setVisible(false); +} + +cComboPicker::~cComboPicker() +{ + delete ui; +} + +void cComboPicker::setText(const QString& szText) +{ + if(szText.isEmpty()) + ui->m_lpText->setVisible(false); + else + { + ui->m_lpText->setVisible(true); + ui->m_lpText->setText(szText); + } +} + +void cComboPicker::setImage(const QImage& image) +{ + if(image.isNull()) + ui->m_lpPicture->setVisible(false); + else + { + ui->m_lpPicture->setVisible(true); + ui->m_lpPicture->setPixmap(QPixmap::fromImage(image)); + } +} + +void cComboPicker::setList(const QStringList& list) +{ + ui->m_lpComboBox->addItems(list); +} + +void cComboPicker::setEditable(bool editable) +{ + ui->m_lpComboBox->setEditable(editable); +} + +void cComboPicker::setSelection(const QString& selection) +{ + ui->m_lpComboBox->setCurrentText(selection); +} + +QString cComboPicker::selection() +{ + return(ui->m_lpComboBox->currentText()); +} diff --git a/ccombopicker.h b/ccombopicker.h new file mode 100644 index 0000000..548d9b3 --- /dev/null +++ b/ccombopicker.h @@ -0,0 +1,86 @@ +/*! + \file ccombopicker.h + +*/ + +#ifndef CCOMBOPICKER_H +#define CCOMBOPICKER_H + +#include + +namespace Ui { +class cComboPicker; +} + +/*! + \brief + + \class cComboPicker ccombopicker.h "ccombopicker.h" +*/ +class cComboPicker : public QDialog +{ + Q_OBJECT + +public: + /*! + \brief + + \fn cComboPicker + \param parent + */ + explicit cComboPicker(QWidget *parent = nullptr); + /*! + \brief + + \fn ~cComboPicker + */ + ~cComboPicker(); + + /*! + \brief + + \fn setText + \param szText + */ + void setText(const QString& szText); + /*! + \brief + + \fn setImage + \param image + */ + void setImage(const QImage& image); + /*! + \brief + + \fn setList + \param list + */ + void setList(const QStringList& list); + /*! + \brief + + \fn setEditable + \param editable + */ + void setEditable(bool editable); + /*! + \brief + + \fn setSelection + \param image + */ + void setSelection(const QString& selection); + /*! + \brief + + \fn selection + \return QString + */ + QString selection(); + +private: + Ui::cComboPicker *ui; /*!< TODO: describe */ +}; + +#endif // CCOMBOPICKER_H diff --git a/ccombopicker.ui b/ccombopicker.ui new file mode 100644 index 0000000..0df91ba --- /dev/null +++ b/ccombopicker.ui @@ -0,0 +1,89 @@ + + + cComboPicker + + + + 0 + 0 + 176 + 90 + + + + Dialog + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + cComboPicker + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + cComboPicker + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/cdatepicker.h b/cdatepicker.h index 20ef547..c2051b4 100644 --- a/cdatepicker.h +++ b/cdatepicker.h @@ -66,7 +66,7 @@ public: \fn date \return QDate */ - QDate date(); + QDate date(); private: Ui::cDatePicker *ui; /*!< TODO: describe */ diff --git a/cflag.cpp b/cflag.cpp new file mode 100644 index 0000000..90cbc0e --- /dev/null +++ b/cflag.cpp @@ -0,0 +1,242 @@ +/*! + \file cFlag.cpp + +*/ + +#include "common.h" + +#include "cflag.h" + +#include +#include + +#include + + +cFlag::cFlag(qint32 iID, QObject *parent) : + QObject(parent), + m_iID(iID), + m_szName("") +{ +} + +bool cFlag::toDB() +{ + QSqlQuery query; + + if(m_iID != -1) + { + query.prepare("SELECT id FROM flags WHERE id=:id;"); + query.bindValue(":id", m_iID); + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + if(!query.next()) + query.prepare("INSERT INTO flags (name) VALUES (:name);"); + else + query.prepare("UPDATE flags SET name=:name WHERE id=:id;"); + } + else + query.prepare("INSERT INTO flags (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 flags WHERE _rowid_=(SELECT MAX(_rowid_) FROM flags);"); + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + query.next(); + m_iID = query.value("id").toInt(); + } + + return(true); +} + +void cFlag::setID(const qint32& id) +{ + m_iID = id; +} + +qint32 cFlag::id() +{ + return(m_iID); +} + +void cFlag::setName(const QString &name) +{ + m_szName = name; +} + +QString cFlag::name() +{ + return(m_szName); +} + +bool cFlag::operator==(const cFlag& other) const +{ + if(this->m_szName != other.m_szName) + return(false); + + return(true); +} + +bool cFlag::operator==(const cFlag*& other) const +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +bool cFlag::operator==(const cFlag* other) const +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +bool cFlag::operator==(cFlag* other) +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +cFlagList::cFlagList(QObject *parent) : + QObject(parent) +{ +} + +bool cFlagList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) +{ + QSqlQuery query; + + query.prepare("SELECT COUNT(1) cnt FROM flags;"); + + 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 flags " + "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()) + { + cFlag* lpFlags = add(query.value("id").toInt(), true); + lpFlags->setName(query.value("name").toString()); + + count++; + if(!(count % step)) + { + if(lpProgressBar) + lpProgressBar->setValue(count); + else if(lpSplashScreen) + lpSplashScreen->setProgress(count); + qApp->processEvents(); + } + } + + return(true); +} + +cFlag* cFlagList::add(qint32 iID, bool bNoCheck) +{ + if(iID != -1 && !bNoCheck) + { + if(find(iID)) + return(nullptr); + } + + cFlag* lpNew = new cFlag(iID); + append(lpNew); + return(lpNew); +} + +bool cFlagList::add(cFlag* lpFlags, bool bNoCheck) +{ + if(bNoCheck) + { + append(lpFlags); + return(true); + } + + if(contains(lpFlags)) + return(false); + + append(lpFlags); + return(true); +} + +cFlag* cFlagList::find(qint32 iID) +{ + for(cFlagList::iterator i = begin(); i != end(); i++) + { + if((*i)->id() == iID) + return(*i); + } + return(nullptr); +} + +cFlag* cFlagList::find(cFlag* lpFlags) +{ + for(cFlagList::iterator i = begin(); i != end(); i++) + { + if(*lpFlags == (**i)) + return(*i); + } + return(nullptr); +} + +QStringList cFlagList::flagList() +{ + QStringList szFlagsList; + + for(cFlagList::iterator i = begin(); i != end();i++) + szFlagsList.append((*i)->name()); + + szFlagsList.removeDuplicates(); + szFlagsList.sort(Qt::CaseInsensitive); + return(szFlagsList); +} diff --git a/cflag.h b/cflag.h new file mode 100644 index 0000000..8f8c29f --- /dev/null +++ b/cflag.h @@ -0,0 +1,197 @@ +/*! + \file cFlag.h + +*/ + +#ifndef cFlag_H +#define cFlag_H + + +#include "csplashscreen.h" + +#include +#include + +#include + +#include + + +/*! + \brief + + \class cFlag cflag.h "cflag.h" +*/ +class cFlag : public QObject +{ + Q_OBJECT +public: + /*! + \brief + + \fn cFlag + \param parent + */ + explicit cFlag(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 cFlag& other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(const cFlag*& other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(const cFlag* other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(cFlag* other); + +signals: + +public slots: + +private: + qint32 m_iID; /*!< TODO: describe */ + QString m_szName; /*!< TODO: describe */ +}; + +Q_DECLARE_METATYPE(cFlag*) + +/*! + \brief + + \class cFlagList cflag.h "cflag.h" +*/ +class cFlagList : public QObject, public QList +{ + Q_OBJECT +public: + /*! + \brief + + \fn cFlagList + \param parent + */ + explicit cFlagList(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 cFlag + */ + cFlag* add(qint32 iID = -1, bool bNoCheck = false); + /*! + \brief + + \fn add + \param cFlag + \param bNoCheck + \return bool + */ + bool add(cFlag* lpFlags, bool bNoCheck = false); + + /*! + \brief + + \fn find + \param iID + \return cFlag + */ + cFlag* find(qint32 iID); + /*! + \brief + + \fn find + \param iID + \return cFlag + */ + cFlag* find(cFlag* lpFlags); + + /*! + \brief + + \fn flagList + \return QStringList + */ + QStringList flagList(); +signals: + +public slots: +}; + +#endif // cFlag_H diff --git a/cimportdialog.cpp b/cimportdialog.cpp index 537123b..f58dcbc 100644 --- a/cimportdialog.cpp +++ b/cimportdialog.cpp @@ -127,7 +127,6 @@ void cImportDialog::onPathSelect() void cImportDialog::onThumbnailSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/) { - cToolBoxInfo* lpToolBoxInfo = ui->m_lpInfo; qint32 iCount = ui->m_lpThumbnailView->selectionModel()->selectedRows().count(); ui->m_lpCount->setText(QString("count: %1, selected: %2").arg(m_lpThumbnailViewModel->rowCount()).arg(iCount)); @@ -136,11 +135,7 @@ void cImportDialog::onThumbnailSelected(const QItemSelection& /*selection*/, con else ui->m_lpImport->setEnabled(false); - if(ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count() != 1) - { - lpToolBoxInfo->setPicture(nullptr); - return; - } + cPictureList pictureList; for(int x = 0;x < ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count();x++) { @@ -148,9 +143,9 @@ void cImportDialog::onThumbnailSelected(const QItemSelection& /*selection*/, con if(!index.isValid()) return; - cPicture* lpPicture = m_lpThumbnailSortFilterProxyModel->data(index, Qt::UserRole+1).value(); - lpToolBoxInfo->setPicture(lpPicture); + pictureList.append(m_lpThumbnailSortFilterProxyModel->data(index, Qt::UserRole+1).value()); } + ui->m_lpInfo->setPicture(pictureList); } void cImportDialog::onFolderSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/) diff --git a/cimportdialog.ui b/cimportdialog.ui index c7a6806..a6b55e7 100644 --- a/cimportdialog.ui +++ b/cimportdialog.ui @@ -105,6 +105,9 @@ + + false + detect HDR @@ -112,6 +115,9 @@ + + false + detect JPG/RAW diff --git a/cmainwindow.cpp b/cmainwindow.cpp index eedc720..ea4a048 100644 --- a/cmainwindow.cpp +++ b/cmainwindow.cpp @@ -10,6 +10,7 @@ #include "cdatepicker.h" #include "cdatetimepicker.h" +#include "ccombopicker.h" #include "ui_cmainwindow.h" @@ -142,8 +143,15 @@ void cMainWindow::loadData(bool bProgressBar) { m_bLoading = true; + m_personList.clear(); + 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_pictureList.clear(); - m_pictureList.load(m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); + m_pictureList.load(m_personList, m_flagList, m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); displayData(); @@ -338,27 +346,7 @@ void cMainWindow::createFileActions() void cMainWindow::onThumbnailSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/) { - if(!ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count()) - { - ui->m_lpToolBoxInfo->setPicture(nullptr); - return; - } - - if(ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count() != 1) - { - QList pictureList; - - for(int x = 0;x < ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count();x++) - { - QModelIndex index = ui->m_lpThumbnailView->selectionModel()->selectedIndexes()[x]; - if(!index.isValid()) - return; - - pictureList.append(m_lpThumbnailSortFilterProxyModel->data(index, Qt::UserRole+1).value()); - } - ui->m_lpToolBoxInfo->setPicture(pictureList); - return; - } + cPictureList pictureList; for(int x = 0;x < ui->m_lpThumbnailView->selectionModel()->selectedIndexes().count();x++) { @@ -366,9 +354,10 @@ void cMainWindow::onThumbnailSelected(const QItemSelection& /*selection*/, const if(!index.isValid()) return; - cPicture* lpPicture = m_lpThumbnailSortFilterProxyModel->data(index, Qt::UserRole+1).value(); - ui->m_lpToolBoxInfo->setPicture(lpPicture); + pictureList.append(m_lpThumbnailSortFilterProxyModel->data(index, Qt::UserRole+1).value()); } + ui->m_lpToolBoxInfo->setPicture(pictureList); + ui->m_lpToolBoxPerson->setPicture(pictureList); } void cMainWindow::onFolderSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/) @@ -591,13 +580,15 @@ void cMainWindow::onChangeTitle() pictureList.append(lpPicture); } - QInputDialog dialog(this); - dialog.setLabelText(tr("Enter new title:")); - dialog.setTextValue(szCurTitle); - if(dialog.exec() == QDialog::Rejected) + cComboPicker comboPicker(this); + comboPicker.setList(m_pictureList.titleList()); + comboPicker.setEditable(true); + comboPicker.setWindowTitle("Enter new title"); + comboPicker.setSelection(szCurTitle); + if(comboPicker.exec() == QDialog::Rejected) return; - QString szNewTitle = dialog.textValue(); + QString szNewTitle = comboPicker.selection(); for(int x = 0;x < pictureList.count();x++) { diff --git a/cmainwindow.h b/cmainwindow.h index 431ac92..2919290 100644 --- a/cmainwindow.h +++ b/cmainwindow.h @@ -10,6 +10,8 @@ #include "cpicturelibrary.h" #include "csplashscreen.h" #include "cpicture.h" +#include "cflag.h" +#include "cperson.h" #include "cfoldersortfilterproxymodel.h" #include "cthumbnailsortfilterproxymodel.h" @@ -73,6 +75,8 @@ private: cSplashScreen* m_lpSplashScreen; /*!< TODO: describe */ cPictureLibrary m_pictureLibrary; /*!< TODO: describe */ cPictureList m_pictureList; /*!< TODO: describe */ + cPersonList m_personList; /*!< TODO: describe */ + cFlagList m_flagList; /*!< TODO: describe */ QMenu* m_lpFileMenu; /*!< TODO: describe */ diff --git a/cmainwindow.ui b/cmainwindow.ui index 961994e..b39e088 100644 --- a/cmainwindow.ui +++ b/cmainwindow.ui @@ -115,20 +115,33 @@ 0 0 69 - 537 + 510 Information + + + + 0 + 0 + 69 + 510 + + + + People + + 0 0 69 - 537 + 510 @@ -177,6 +190,12 @@
ctoolboxinfo.h
1 + + cToolBoxPerson + QWidget +
ctoolboxperson.h
+ 1 +
diff --git a/cperson.cpp b/cperson.cpp new file mode 100644 index 0000000..114264c --- /dev/null +++ b/cperson.cpp @@ -0,0 +1,242 @@ +/*! + \file cPerson.cpp + +*/ + +#include "common.h" + +#include "cperson.h" + +#include +#include + +#include + + +cPerson::cPerson(qint32 iID, QObject *parent) : + QObject(parent), + m_iID(iID), + m_szName("") +{ +} + +bool cPerson::toDB() +{ + QSqlQuery query; + + if(m_iID != -1) + { + query.prepare("SELECT id FROM person WHERE id=:id;"); + query.bindValue(":id", m_iID); + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + if(!query.next()) + query.prepare("INSERT INTO person (name) VALUES (:name);"); + else + query.prepare("UPDATE person SET name=:name WHERE id=:id;"); + } + else + query.prepare("INSERT INTO person (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 person WHERE _rowid_=(SELECT MAX(_rowid_) FROM person);"); + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + query.next(); + m_iID = query.value("id").toInt(); + } + + return(true); +} + +void cPerson::setID(const qint32& id) +{ + m_iID = id; +} + +qint32 cPerson::id() +{ + return(m_iID); +} + +void cPerson::setName(const QString &name) +{ + m_szName = name; +} + +QString cPerson::name() +{ + return(m_szName); +} + +bool cPerson::operator==(const cPerson& other) const +{ + if(this->m_szName != other.m_szName) + return(false); + + return(true); +} + +bool cPerson::operator==(const cPerson*& other) const +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +bool cPerson::operator==(const cPerson* other) const +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +bool cPerson::operator==(cPerson* other) +{ + if(this->m_szName != other->m_szName) + return(false); + + return(true); +} + +cPersonList::cPersonList(QObject *parent) : + QObject(parent) +{ +} + +bool cPersonList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) +{ + QSqlQuery query; + + query.prepare("SELECT COUNT(1) cnt FROM person;"); + + 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 person " + "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()) + { + cPerson* lpFlags = add(query.value("id").toInt(), true); + lpFlags->setName(query.value("name").toString()); + + count++; + if(!(count % step)) + { + if(lpProgressBar) + lpProgressBar->setValue(count); + else if(lpSplashScreen) + lpSplashScreen->setProgress(count); + qApp->processEvents(); + } + } + + return(true); +} + +cPerson* cPersonList::add(qint32 iID, bool bNoCheck) +{ + if(iID != -1 && !bNoCheck) + { + if(find(iID)) + return(nullptr); + } + + cPerson* lpNew = new cPerson(iID); + append(lpNew); + return(lpNew); +} + +bool cPersonList::add(cPerson* lpFlags, bool bNoCheck) +{ + if(bNoCheck) + { + append(lpFlags); + return(true); + } + + if(contains(lpFlags)) + return(false); + + append(lpFlags); + return(true); +} + +cPerson* cPersonList::find(qint32 iID) +{ + for(cPersonList::iterator i = begin(); i != end(); i++) + { + if((*i)->id() == iID) + return(*i); + } + return(nullptr); +} + +cPerson* cPersonList::find(cPerson* lpFlags) +{ + for(cPersonList::iterator i = begin(); i != end(); i++) + { + if(*lpFlags == (**i)) + return(*i); + } + return(nullptr); +} + +QStringList cPersonList::personList() +{ + QStringList szPersonList; + + for(cPersonList::iterator i = begin(); i != end();i++) + szPersonList.append((*i)->name()); + + szPersonList.removeDuplicates(); + szPersonList.sort(Qt::CaseInsensitive); + return(szPersonList); +} diff --git a/cperson.h b/cperson.h new file mode 100644 index 0000000..6963d29 --- /dev/null +++ b/cperson.h @@ -0,0 +1,197 @@ +/*! + \file cperson.h + +*/ + +#ifndef CPERSON_H +#define CPERSON_H + + +#include "csplashscreen.h" + +#include +#include + +#include + +#include + + +/*! + \brief + + \class cPerson cperson.h "cperson.h" +*/ +class cPerson : public QObject +{ + Q_OBJECT +public: + /*! + \brief + + \fn cPerson + \param parent + */ + explicit cPerson(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 cPerson& other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(const cPerson*& other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(const cPerson* other) const; + + /*! + \brief + + \fn operator== + \param other + \return bool + */ + bool operator==(cPerson* other); + +signals: + +public slots: + +private: + qint32 m_iID; /*!< TODO: describe */ + QString m_szName; /*!< TODO: describe */ +}; + +Q_DECLARE_METATYPE(cPerson*) + +/*! + \brief + + \class cFlagList cflag.h "cflag.h" +*/ +class cPersonList : public QObject, public QList +{ + Q_OBJECT +public: + /*! + \brief + + \fn cPersonList + \param parent + */ + explicit cPersonList(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 cPerson + */ + cPerson* add(qint32 iID = -1, bool bNoCheck = false); + /*! + \brief + + \fn add + \param cPerson + \param bNoCheck + \return bool + */ + bool add(cPerson* lpPersons, bool bNoCheck = false); + + /*! + \brief + + \fn find + \param iID + \return cPerson + */ + cPerson* find(qint32 iID); + /*! + \brief + + \fn find + \param iID + \return cPerson + */ + cPerson* find(cPerson* lpPersons); + + /*! + \brief + + \fn PersonList + \return QStringList + */ + QStringList personList(); +signals: + +public slots: +}; + +#endif // CPERSON_H diff --git a/cpicture.cpp b/cpicture.cpp index 652c4cc..75fab64 100644 --- a/cpicture.cpp +++ b/cpicture.cpp @@ -160,6 +160,32 @@ bool cPicture::toDB() m_iID = query.value("id").toInt(); } + query.prepare("DELETE FROM picture_person WHERE pictureID=:pictureID;"); + query.bindValue(":pictureID", m_iID); + query.exec(); + + query.prepare("INSERT INTO picture_person (pictureID, personID) VALUES (:pictureID, :personID);"); + query.bindValue(":pictureID", m_iID); + + for(cPersonList::iterator i = m_personList.begin();i != m_personList.end();i++) + { + query.bindValue(":personID", (*i)->id()); + query.exec(); + } + + query.prepare("DELETE FROM picture_flag WHERE pictureID=:pictureID;"); + query.bindValue(":pictureID", m_iID); + query.exec(); + + query.prepare("INSERT INTO picture_flag (pictureID, flagID) VALUES (:pictureID, :flagID);"); + query.bindValue(":pictureID", m_iID); + + for(cFlagList::iterator i = m_flagList.begin();i != m_flagList.end();i++) + { + query.bindValue(":flagID", (*i)->id()); + query.exec(); + } + return(true); } @@ -463,6 +489,52 @@ QImage cPicture::thumbnail() return(m_thumbnail); } +void cPicture::addPerson(cPerson* lpPerson) +{ + if(m_personList.contains(lpPerson)) + return; + m_personList.add(lpPerson); +} + +void cPicture::removePerson(cPerson* lpPerson) +{ + if(m_personList.contains(lpPerson)) + m_personList.removeAll(lpPerson); +} + +void cPicture::clearPersonList() +{ + m_personList.clear(); +} + +cPersonList& cPicture::personList() +{ + return(m_personList); +} + +void cPicture::addFlag(cFlag* lpFlag) +{ + if(m_flagList.contains(lpFlag)) + return; + m_flagList.add(lpFlag); +} + +void cPicture::removeFlag(cFlag* lpFlag) +{ + if(m_flagList.contains(lpFlag)) + m_flagList.removeAll(lpFlag); +} + +void cPicture::clearFlagList() +{ + m_flagList.clear(); +} + +cFlagList& cPicture::flagList() +{ + return(m_flagList); +} + bool cPicture::operator==(const cPicture& other) const { if(this->m_szFileName != other.m_szFileName) @@ -692,7 +764,7 @@ cPictureList::cPictureList(QObject *parent) : { } -bool cPictureList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) +bool cPictureList::load(cPersonList& personList, cFlagList& flagList, cSplashScreen *lpSplashScreen, QProgressBar *lpProgressBar) { cEXIFFlashList flashList; QSqlQuery query; @@ -801,6 +873,108 @@ bool cPictureList::load(cSplashScreen *lpSplashScreen, QProgressBar *lpProgressB } } + query.prepare("SELECT COUNT(1) cnt FROM picture_person;"); + + 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, " + " personID " + "FROM picture_person;"); + + 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()); + cPerson* lpPerson = personList.find(query.value("personID").toInt()); + + if(lpPicture && lpPerson) + lpPicture->addPerson(lpPerson); + + 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_flag;"); + + 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, " + " flagID " + "FROM picture_flag;"); + + 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()); + cFlag* lpFlag = flagList.find(query.value("flagID").toInt()); + + if(lpPicture && lpFlag) + lpPicture->addFlag(lpFlag); + + count++; + if(!(count % step)) + { + if(lpProgressBar) + lpProgressBar->setValue(count); + else if(lpSplashScreen) + lpSplashScreen->setProgress(count); + qApp->processEvents(); + } + } + return(true); } @@ -834,30 +1008,42 @@ bool cPictureList::add(cPicture* lpPicture, bool bNoCheck) cPicture* cPictureList::find(qint32 iID) { - for(int i = 0;i < count();i++) + for(cPictureList::iterator i = begin(); i != end(); i++) { - if(at(i)->id() == iID) - return(at(i)); + if((*i)->id() == iID) + return(*i); } return(nullptr); } cPicture* cPictureList::find(cPicture* lpPicture) { - for(int i = 0;i < count();i++) + for(cPictureList::iterator i = begin(); i != end(); i++) { - if(*lpPicture == *at(i)) - return(at(i)); + if(*lpPicture == (**i)) + return(*i); } return(nullptr); } bool cPictureList::hasPath(const QString& szPath) { - for(int i = 0;i < count();i++) + for(cPictureList::iterator i = begin(); i != end(); i++) { - if(at(i)->filePath() == szPath) + if((*i)->filePath() == szPath) return(true); } return(false); } + +QStringList cPictureList::titleList() +{ + QStringList szTitleList; + + for(cPictureList::iterator i = begin(); i != end();i++) + szTitleList.append((*i)->title()); + + szTitleList.removeDuplicates(); + szTitleList.sort(Qt::CaseInsensitive); + return(szTitleList); +} diff --git a/cpicture.h b/cpicture.h index 17956f4..8d20a53 100644 --- a/cpicture.h +++ b/cpicture.h @@ -9,6 +9,9 @@ #include "csplashscreen.h" +#include "cperson.h" +#include "cflag.h" + #include #include #include @@ -503,6 +506,62 @@ public: */ QImage thumbnail(); + /*! + \brief + + \fn addPerson + \param lpPerson + */ + void addPerson(cPerson* lpPerson); + /*! + \brief + + \fn removePerson + \param lpPerson + */ + void removePerson(cPerson* lpPerson); + /*! + \brief + + \fn clearPersonList + */ + void clearPersonList(); + /*! + \brief + + \fn personList + \return cPersonList + */ + cPersonList& personList(); + + /*! + \brief + + \fn addFlag + \param lpFlag + */ + void addFlag(cFlag* lpFlag); + /*! + \brief + + \fn removeFlag + \param lpFlag + */ + void removeFlag(cFlag* lpFlag); + /*! + \brief + + \fn clearFlagList + */ + void clearFlagList(); + /*! + \brief + + \fn flagList + \return cFlagList + */ + cFlagList& flagList(); + /*! \brief @@ -574,6 +633,9 @@ private: QString m_gps; /*!< TODO: describe */ qint64 m_duration; /*!< TODO: describe */ bool m_hdr; /*!< TODO: describe */ + + cPersonList m_personList; /*!< TODO: describe */ + cFlagList m_flagList; /*!< TODO: describe */ }; Q_DECLARE_METATYPE(cPicture*) @@ -603,7 +665,7 @@ public: \param lpProgressBar \return bool */ - bool load(cSplashScreen* lpSplashScreen, QProgressBar* lpProgressBar = nullptr); + bool load(cPersonList& personList, cFlagList& flagList, cSplashScreen* lpSplashScreen, QProgressBar* lpProgressBar = nullptr); /*! \brief @@ -650,6 +712,13 @@ public: */ bool hasPath(const QString& szPath); + /*! + \brief + + \fn titleList + \return QStringList + */ + QStringList titleList(); signals: public slots: diff --git a/cpicturelibrary.cpp b/cpicturelibrary.cpp index bbfc72e..46ce5a4 100644 --- a/cpicturelibrary.cpp +++ b/cpicturelibrary.cpp @@ -132,6 +132,42 @@ bool cPictureLibrary::createDatabase() "); ")) return(false); + if(!createTable("CREATE TABLE person ( " + " id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, " + " name TEXT " + "); ")) + return(false); + + if(!createTable("CREATE TABLE flags ( " + " 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) " + "); ")) + return(false); + + if(!createTable("CREATE UNIQUE INDEX picture_flag_idx ON picture_flags ( " + " pictureID, " + " flagsID " + "); ")) + return(false); + + if(!createTable("CREATE TABLE picture_person ( " + " pictureID INTEGER REFERENCES picture (id), " + " personID INTEGER REFERENCES people (id) " + "); ")) + return(false); + + if(!createTable("CREATE UNIQUE INDEX picture_person_idx ON picture_person ( " + " pictureID, " + " personID " + "); ")) + return(false); + query.prepare("INSERT INTO config (version) VALUES (:version);"); query.bindValue(":version", 1); if(!query.exec()) diff --git a/ctoolboxinfo.cpp b/ctoolboxinfo.cpp index e1e7d97..1d488bd 100644 --- a/ctoolboxinfo.cpp +++ b/ctoolboxinfo.cpp @@ -21,9 +21,9 @@ cToolBoxInfo::~cToolBoxInfo() delete ui; } -void cToolBoxInfo::setPicture(cPicture* lpPicture) +void cToolBoxInfo::setPicture(cPictureList& pictureList) { - if(!lpPicture) + if(!pictureList.count()) { ui->m_lpTitlePicture->setText("---"); ui->m_lpFileNamePicture->setText("---"); @@ -53,43 +53,6 @@ void cToolBoxInfo::setPicture(cPicture* lpPicture) return; } - if(lpPicture->mimeType().startsWith("image")) - { - ui->m_lpCategory->setCurrentIndex(0); - - ui->m_lpTitlePicture->setText(lpPicture->title()); - ui->m_lpFileNamePicture->setText(lpPicture->fileName()); - ui->m_lpPathPicture->setText(lpPicture->filePath()); - ui->m_lpDatePicture->setText(lpPicture->dateTime().toString()); - ui->m_lpSizePicture->setText(QString("%1x%2").arg(lpPicture->imageWidth()).arg(lpPicture->imageHeight())); - ui->m_lpHDRPicture->setText(lpPicture->hdr() ? tr("yes") : tr("no")); - ui->m_lpCameraPicture->setText(QString("%1 %2").arg(lpPicture->cameraMake()).arg(lpPicture->cameraModel())); - ui->m_lpLensModelPicture->setText(lpPicture->lensModel()); - ui->m_lpFNumberPicture->setText("f 1:" + lpPicture->fNumber()); - ui->m_lpExposureTimePicture->setText(lpPicture->exposureTime()); - ui->m_lpExposureBiasPicture->setText(QString::number(lpPicture->exposureBias())); - ui->m_lpISOPicture->setText(QString::number(lpPicture->iso())); - ui->m_lpFocalLengthPicture->setText(QString("%1 mm").arg(lpPicture->focalLength())); - ui->m_lpFlashPicture->setText(lpPicture->flash()); - ui->m_lpGPSPicture->setText(lpPicture->gps()); - } - else - { - ui->m_lpCategory->setCurrentIndex(1); - - ui->m_lpTitleVideo->setText(lpPicture->title()); - ui->m_lpFileNameVideo->setText(lpPicture->fileName()); - ui->m_lpPathVideo->setText(lpPicture->filePath()); - ui->m_lpDateVideo->setText(lpPicture->dateTime().toString()); - ui->m_lpSizeVideo->setText(QString("%1x%2").arg(lpPicture->imageWidth()).arg(lpPicture->imageHeight())); - ui->m_lpHDRVideo->setText(lpPicture->hdr() ? tr("yes") : tr("no")); - ui->m_lpCameraVideo->setText(QString("%1 %2").arg(lpPicture->cameraMake()).arg(lpPicture->cameraModel())); - ui->m_lpDurationVideo->setText(ms2String(lpPicture->duration())); - } -} - -void cToolBoxInfo::setPicture(QList pictureList) -{ cPicture* lpPicture = pictureList[0]; QString mimeType = lpPicture->mimeType().left(lpPicture->mimeType().indexOf("/")); QString title = lpPicture->title(); diff --git a/ctoolboxinfo.h b/ctoolboxinfo.h index 7f070ef..1b9736f 100644 --- a/ctoolboxinfo.h +++ b/ctoolboxinfo.h @@ -40,20 +40,13 @@ public: */ ~cToolBoxInfo(); - /*! - \brief - - \fn setPicture - \param lpPicture - */ - void setPicture(cPicture* lpPicture); /*! \brief \fn setPicture \param pictureList */ - void setPicture(QList pictureList); + void setPicture(cPictureList& pictureList); private: Ui::cToolBoxInfo* ui; /*!< TODO: describe */ }; diff --git a/ctoolboxperson.cpp b/ctoolboxperson.cpp new file mode 100644 index 0000000..00fbe7a --- /dev/null +++ b/ctoolboxperson.cpp @@ -0,0 +1,121 @@ +#include "ctoolboxperson.h" +#include "ui_ctoolboxperson.h" + + +cToolBoxPerson::cToolBoxPerson(QWidget *parent) : + QWidget(parent), + ui(new Ui::cToolBoxPerson), + m_bLoading(true) +{ + ui->setupUi(this); + + m_lpPersonListModel = new QStandardItemModel; + ui->m_lpPersonList->setModel(m_lpPersonListModel); + + connect(m_lpPersonListModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), SLOT(personChanged(QModelIndex, QModelIndex, QVector))); +} + +cToolBoxPerson::~cToolBoxPerson() +{ + delete ui; +} + +void cToolBoxPerson::setPersonList(cPersonList* lpPersonList) +{ + m_bLoading = true; + + m_lpPersonList = lpPersonList; + + for(cPersonList::iterator i = lpPersonList->begin();i != lpPersonList->end();i++) + { + QStandardItem* lpItem = new QStandardItem((*i)->name()); + lpItem->setData(QVariant::fromValue(*i), Qt::UserRole+1); + lpItem->setCheckable(true); + m_lpPersonListModel->appendRow(lpItem); + } + + m_bLoading = false; +} + +void cToolBoxPerson::setPicture(cPictureList& pictureList) +{ + m_bLoading = true; + + m_pictureList.clear(); + + for(int i = 0;i < m_lpPersonListModel->rowCount();i++) + { + QStandardItem* lpItem = m_lpPersonListModel->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_lpPersonListModel->rowCount();i++) + { + QStandardItem* lpItem = m_lpPersonListModel->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 cToolBoxPerson::personChanged(const QModelIndex& /*topLeft*/, const QModelIndex& /*bottomright*/, const QVector& /*roles*/) +{ + if(!m_pictureList.count()) + return; + + if(m_bLoading) + return; + + for(int x = 0;x < m_lpPersonListModel->rowCount();x++) + { + QStandardItem* lpItem = m_lpPersonListModel->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(); +} diff --git a/ctoolboxperson.h b/ctoolboxperson.h new file mode 100644 index 0000000..372c20e --- /dev/null +++ b/ctoolboxperson.h @@ -0,0 +1,79 @@ +/*! + \file ctoolboxperson.h + +*/ + +#ifndef CTOOLBOXPERSON_H +#define CTOOLBOXPERSON_H + + +#include "cperson.h" +#include "cpicture.h" + +#include +#include + + +namespace Ui { +class cToolBoxPerson; +} + +/*! + \brief + + \class cToolBoxPerson ctoolboxperson.h "ctoolboxperson.h" +*/ +class cToolBoxPerson : public QWidget +{ + Q_OBJECT + +public: + /*! + \brief + + \fn cToolBoxPerson + \param parent + */ + explicit cToolBoxPerson(QWidget *parent = nullptr); + /*! + \brief + + \fn ~cToolBoxPerson + */ + ~cToolBoxPerson(); + + /*! + \brief + + \param lpPersonList + \fn setPersonList + */ + void setPersonList(cPersonList* lpPersonList); + + /*! + \brief + + \fn setPicture + \param pictureList + */ + void setPicture(cPictureList& pictureList); +private: + Ui::cToolBoxPerson* ui; /*!< TODO: describe */ + QStandardItemModel* m_lpPersonListModel; /*!< TODO: describe */ + cPersonList* m_lpPersonList; /*!< TODO: describe */ + cPictureList m_pictureList; /*!< TODO: describe */ + bool m_bLoading; /*!< TODO: describe */ + +private slots: + /*! + \brief + + \fn personChanged + \param topLeft + \param bottomright + \param roles + */ + void personChanged(const QModelIndex& topLeft, const QModelIndex& bottomright, const QVector& roles); +}; + +#endif // CTOOLBOXPERSON_H diff --git a/ctoolboxperson.ui b/ctoolboxperson.ui new file mode 100644 index 0000000..5293872 --- /dev/null +++ b/ctoolboxperson.ui @@ -0,0 +1,37 @@ + + + cToolBoxPerson + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + QAbstractItemView::NoEditTriggers + + + true + + + false + + + false + + + + + + + + diff --git a/pictureLibrary.pro b/pictureLibrary.pro index 89e6c8a..814abc2 100644 --- a/pictureLibrary.pro +++ b/pictureLibrary.pro @@ -67,7 +67,11 @@ SOURCES += \ cthumbnailsortfilterproxymodel.cpp \ cfoldersortfilterproxymodel.cpp \ ccopier.cpp \ - cdatepicker.cpp + cdatepicker.cpp \ + ccombopicker.cpp \ + cflag.cpp \ + cperson.cpp \ + ctoolboxperson.cpp HEADERS += \ cmainwindow.h \ @@ -83,14 +87,20 @@ HEADERS += \ cthumbnailsortfilterproxymodel.h \ cfoldersortfilterproxymodel.h \ ccopier.h \ - cdatepicker.h + cdatepicker.h \ + ccombopicker.h \ + cflag.h \ + cperson.h \ + ctoolboxperson.h FORMS += \ cmainwindow.ui \ ctoolboxinfo.ui \ cimportdialog.ui \ cdatetimepicker.ui \ - cdatepicker.ui + cdatepicker.ui \ + ccombopicker.ui \ + ctoolboxperson.ui # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin