From 99b8193982f8c3b4223a3441cc2e0aba0e258bcc Mon Sep 17 00:00:00 2001 From: Herwig Birke Date: Fri, 8 Mar 2019 15:23:51 +0100 Subject: [PATCH] Add/remove persons to pictures --- ccombopicker.cpp | 59 +++++++++++ ccombopicker.h | 86 ++++++++++++++++ ccombopicker.ui | 89 ++++++++++++++++ cdatepicker.h | 2 +- cflag.cpp | 242 ++++++++++++++++++++++++++++++++++++++++++++ cflag.h | 197 ++++++++++++++++++++++++++++++++++++ cimportdialog.cpp | 11 +- cimportdialog.ui | 6 ++ cmainwindow.cpp | 49 ++++----- cmainwindow.h | 4 + cmainwindow.ui | 23 ++++- cperson.cpp | 242 ++++++++++++++++++++++++++++++++++++++++++++ cperson.h | 197 ++++++++++++++++++++++++++++++++++++ cpicture.cpp | 204 +++++++++++++++++++++++++++++++++++-- cpicture.h | 71 ++++++++++++- cpicturelibrary.cpp | 36 +++++++ ctoolboxinfo.cpp | 41 +------- ctoolboxinfo.h | 9 +- ctoolboxperson.cpp | 121 ++++++++++++++++++++++ ctoolboxperson.h | 79 +++++++++++++++ ctoolboxperson.ui | 37 +++++++ pictureLibrary.pro | 16 ++- 22 files changed, 1721 insertions(+), 100 deletions(-) create mode 100644 ccombopicker.cpp create mode 100644 ccombopicker.h create mode 100644 ccombopicker.ui create mode 100644 cflag.cpp create mode 100644 cflag.h create mode 100644 cperson.cpp create mode 100644 cperson.h create mode 100644 ctoolboxperson.cpp create mode 100644 ctoolboxperson.h create mode 100644 ctoolboxperson.ui 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