From aa5dbe9324cf986bdf9221281fdc2dcf942867e4 Mon Sep 17 00:00:00 2001 From: birkeh Date: Mon, 11 Mar 2019 15:19:55 +0100 Subject: [PATCH] toolbox finalized --- cmainwindow.cpp | 13 +- cmainwindow.h | 2 + cmainwindow.ui | 4 +- cpicture.cpp | 17 ++- ctag.cpp | 31 +++++ ctag.h | 8 ++ ctoolboxlocation.cpp | 34 ++--- ctoolboxperson.cpp | 5 + ctoolboxtag.cpp | 292 ++++++++++++++++++++++++++++++++++++++++++- ctoolboxtag.h | 44 +++---- 10 files changed, 403 insertions(+), 47 deletions(-) diff --git a/cmainwindow.cpp b/cmainwindow.cpp index 03eddad..f8ea31e 100644 --- a/cmainwindow.cpp +++ b/cmainwindow.cpp @@ -153,11 +153,16 @@ void cMainWindow::loadData(bool bProgressBar) m_personList.load(m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); ui->m_lpToolBoxPerson->setPersonList(&m_personList); + m_locationList.clear(); + m_locationList.load(m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); + ui->m_lpToolBoxLocation->setLocationList(&m_locationList); + m_tagList.clear(); m_tagList.load(m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); + ui->m_lpToolBoxTags->setTagList(&m_tagList); m_pictureList.clear(); - m_pictureList.load(m_personList, m_tagList, m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); + m_pictureList.load(m_personList, m_locationList, m_tagList, m_lpSplashScreen, bProgressBar ? m_lpProgressBar : nullptr); displayData(); @@ -364,6 +369,8 @@ void cMainWindow::onThumbnailSelected(const QItemSelection& /*selection*/, const } ui->m_lpToolBoxInfo->setPicture(pictureList); ui->m_lpToolBoxPerson->setPicture(pictureList); + ui->m_lpToolBoxLocation->setPicture(pictureList); + ui->m_lpToolBoxTags->setPicture(pictureList); } void cMainWindow::onThumbnailDoubleClicked(const QModelIndex& index) @@ -377,10 +384,12 @@ void cMainWindow::onThumbnailDoubleClicked(const QModelIndex& index) if(!file.exists()) return; + QApplication::setOverrideCursor(Qt::WaitCursor); cImageViewer imageViewer(this); -// imageViewer.showMaximized(); cImage image(file.fileName()); + QApplication::restoreOverrideCursor(); + if(image.isNull()) return; diff --git a/cmainwindow.h b/cmainwindow.h index c38ad91..c211003 100644 --- a/cmainwindow.h +++ b/cmainwindow.h @@ -11,6 +11,7 @@ #include "csplashscreen.h" #include "cpicture.h" #include "ctag.h" +#include "clocation.h" #include "cperson.h" #include "cfoldersortfilterproxymodel.h" @@ -76,6 +77,7 @@ private: cPictureLibrary m_pictureLibrary; /*!< TODO: describe */ cPictureList m_pictureList; /*!< TODO: describe */ cPersonList m_personList; /*!< TODO: describe */ + cLocationList m_locationList; /*!< TODO: describe */ cTagList m_tagList; /*!< TODO: describe */ QMenu* m_lpFileMenu; /*!< TODO: describe */ diff --git a/cmainwindow.ui b/cmainwindow.ui index 73f5cda..906f60c 100644 --- a/cmainwindow.ui +++ b/cmainwindow.ui @@ -148,7 +148,7 @@ Location - + 0 @@ -216,7 +216,7 @@ 1 - ctoolBoxTag + cToolBoxTag QWidget
ctoolboxtag.h
1 diff --git a/cpicture.cpp b/cpicture.cpp index cbb68cc..6b005b6 100644 --- a/cpicture.cpp +++ b/cpicture.cpp @@ -173,6 +173,19 @@ bool cPicture::toDB() query.exec(); } + query.prepare("DELETE FROM picture_location WHERE pictureID=:pictureID;"); + query.bindValue(":pictureID", m_iID); + query.exec(); + + query.prepare("INSERT INTO picture_location (pictureID, locationID) VALUES (:pictureID, :locationID);"); + query.bindValue(":pictureID", m_iID); + + for(cLocationList::iterator i = m_locationList.begin();i != m_locationList.end();i++) + { + query.bindValue(":locationID", (*i)->id()); + query.exec(); + } + query.prepare("DELETE FROM picture_tag WHERE pictureID=:pictureID;"); query.bindValue(":pictureID", m_iID); query.exec(); @@ -521,8 +534,8 @@ void cPicture::addLocation(cLocation* lpLocation) void cPicture::removeLocation(cLocation* lpLocation) { - if(m_tagList.contains(lpTag)) - m_tagList.removeAll(lpTag); + if(m_locationList.contains(lpLocation)) + m_locationList.removeAll(lpLocation); } void cPicture::clearLocationList() diff --git a/ctag.cpp b/ctag.cpp index 949b6bf..12b0912 100644 --- a/ctag.cpp +++ b/ctag.cpp @@ -230,6 +230,37 @@ cTag* cTagList::find(cTag* lpTag) return(nullptr); } +bool cTagList::remove(cTag* lpTag) +{ + if(!find(lpTag)) + return(true); + + QSqlQuery query; + + query.prepare("SELECT COUNT(1) cnt FROM picture_tag WHERE tagID=:id;"); + query.bindValue(":id", lpTag->id()); + + if(!query.exec()) + return(false); + + if(!query.next()) + return(false); + + if(query.value("cnt").toInt() != 0) + return(false); + + query.prepare("DELETE FROM tag WHERE id=:id;"); + query.bindValue(":id", lpTag->id()); + + if(!query.exec()) + return(false); + + this->removeOne(lpTag); + delete lpTag; + + return(true); +} + QStringList cTagList::tagList() { QStringList szTagList; diff --git a/ctag.h b/ctag.h index a11908a..b4078e6 100644 --- a/ctag.h +++ b/ctag.h @@ -181,6 +181,14 @@ public: \return cTag */ cTag* find(cTag* lpTag); + /*! + \brief + + \fn remove + \param lpTag + \return bool + */ + bool remove(cTag* lpTag); /*! \brief diff --git a/ctoolboxlocation.cpp b/ctoolboxlocation.cpp index bb06e67..e6e439c 100644 --- a/ctoolboxlocation.cpp +++ b/ctoolboxlocation.cpp @@ -54,7 +54,7 @@ void cToolBoxLocation::createActions() connect(ui->m_lpLocationList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cToolBoxLocation::onLocationSelected); - connect(m_lpLocationListModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), SLOT(personChanged(QModelIndex, QModelIndex, QVector))); + connect(m_lpLocationListModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), SLOT(locationChanged(QModelIndex, QModelIndex, QVector))); connect(ui->m_lpLocationList, &QTreeView::customContextMenuRequested, this, &cToolBoxLocation::onLocationViewContextMenu); connect(m_lpLocationListModel, &QStandardItemModel::itemChanged, this, &cToolBoxLocation::onLocationChanged); } @@ -100,9 +100,9 @@ void cToolBoxLocation::setPicture(cPictureList& pictureList) for(cPictureList::iterator i = pictureList.begin();i != pictureList.end();i++) { m_pictureList.add(*i, true); - cPersonList& personList = (*i)->personList(); + cLocationList& locationList = (*i)->locationList(); - for(cPersonList::iterator j = personList.begin();j != personList.end();j++) + for(cLocationList::iterator j = locationList.begin();j != locationList.end();j++) { if(list.contains((*j)->id())) list[(*j)->id()] ++; @@ -114,11 +114,11 @@ void cToolBoxLocation::setPicture(cPictureList& pictureList) for(int i = 0;i < m_lpLocationListModel->rowCount();i++) { QStandardItem* lpItem = m_lpLocationListModel->item(i, 0); - cPerson* lpPerson = lpItem->data().value(); + cLocation* lpLocation = lpItem->data().value(); - if(list.contains(lpPerson->id())) + if(list.contains(lpLocation->id())) { - if(list[lpPerson->id()] == count) + if(list[lpLocation->id()] == count) lpItem->setCheckState(Qt::Checked); else lpItem->setCheckState(Qt::PartiallyChecked); @@ -155,15 +155,15 @@ void cToolBoxLocation::locationChanged(const QModelIndex& /*topLeft*/, const QMo if(lpItem->checkState() != Qt::PartiallyChecked) { - cPerson* lpPerson = lpItem->data(Qt::UserRole+1).value(); - if(lpPerson) + cLocation* lpLocation = lpItem->data(Qt::UserRole+1).value(); + if(lpLocation) { for(cPictureList::iterator i = m_pictureList.begin();i != m_pictureList.end();i++) { if(lpItem->checkState() == Qt::Checked) - (*i)->addPerson(lpPerson); + (*i)->addLocation(lpLocation); else if(lpItem->checkState() == Qt::Unchecked) - (*i)->removePerson(lpPerson); + (*i)->removeLocation(lpLocation); } } } @@ -277,21 +277,21 @@ void cToolBoxLocation::onLocationChanged(QStandardItem* lpItem) if(m_bEditing) return; - cPerson* lpPerson = lpItem->data(Qt::UserRole+1).value(); - if(!lpPerson) + cLocation* lpLocation = lpItem->data(Qt::UserRole+1).value(); + if(!lpLocation) return; - if(lpItem->text() == lpPerson->name()) + if(lpItem->text() == lpLocation->name()) return; - QString szOldName = lpPerson->name(); - lpPerson->setName(lpItem->text()); - if(!lpPerson->toDB()) + QString szOldName = lpLocation->name(); + lpLocation->setName(lpItem->text()); + if(!lpLocation->toDB()) { QMessageBox::critical(this, tr("ERROR"), QString(tr("%1 already exists.").arg(lpItem->text()))); m_bEditing = true; lpItem->setText(szOldName); - lpPerson->setName(szOldName); + lpLocation->setName(szOldName); m_bEditing = false; } } diff --git a/ctoolboxperson.cpp b/ctoolboxperson.cpp index cc225ee..add981a 100644 --- a/ctoolboxperson.cpp +++ b/ctoolboxperson.cpp @@ -1,3 +1,8 @@ +/*! + \file cToolBoxPerson.cpp + +*/ + #include "ctoolboxperson.h" #include "ui_ctoolboxperson.h" diff --git a/ctoolboxtag.cpp b/ctoolboxtag.cpp index 726e7c1..9b2a52f 100644 --- a/ctoolboxtag.cpp +++ b/ctoolboxtag.cpp @@ -1,14 +1,302 @@ +/*! + \file cToolBoxTag.cpp + +*/ + #include "ctoolboxtag.h" #include "ui_ctoolboxtag.h" +#include +#include + +#include + +#include + + cToolBoxTag::cToolBoxTag(QWidget *parent) : QWidget(parent), - ui(new Ui::cToolBoxTag) + ui(new Ui::cToolBoxTag), + m_bLoading(true), + m_bEditing(false) { - ui->setupUi(this); + initUI(); + createActions(); } cToolBoxTag::~cToolBoxTag() { delete ui; } + +void cToolBoxTag::initUI() +{ + ui->setupUi(this); + + m_lpTagListModel = new QStandardItemModel; + ui->m_lpTagList->setModel(m_lpTagListModel); + + ui->m_lpEdit->setEnabled(false); + ui->m_lpDelete->setEnabled(false); +} + +void cToolBoxTag::createActions() +{ + m_lpTagAddAction = new QAction(tr("add tag"), this); + m_lpTagAddAction->setStatusTip(tr("add a new tag")); + connect(m_lpTagAddAction, &QAction::triggered, this, &cToolBoxTag::onTagAdd); + connect(ui->m_lpAdd, &QPushButton::clicked, this, &cToolBoxTag::onTagAdd); + + m_lpTagEditAction = new QAction(tr("edit tag"), this); + m_lpTagEditAction->setStatusTip(tr("edit this tag")); + connect(m_lpTagEditAction, &QAction::triggered, this, &cToolBoxTag::onTagEdit); + connect(ui->m_lpEdit, &QPushButton::clicked, this, &cToolBoxTag::onTagEdit); + + m_lpTagDeleteAction = new QAction(tr("delete tag"), this); + m_lpTagDeleteAction->setStatusTip(tr("delete this tag")); + connect(m_lpTagDeleteAction, &QAction::triggered, this, &cToolBoxTag::onTagDelete); + connect(ui->m_lpDelete, &QPushButton::clicked, this, &cToolBoxTag::onTagDelete); + + connect(ui->m_lpTagList->selectionModel(), &QItemSelectionModel::selectionChanged, this, &cToolBoxTag::onTagSelected); + + connect(m_lpTagListModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), SLOT(tagChanged(QModelIndex, QModelIndex, QVector))); + connect(ui->m_lpTagList, &QTreeView::customContextMenuRequested, this, &cToolBoxTag::onTagViewContextMenu); + connect(m_lpTagListModel, &QStandardItemModel::itemChanged, this, &cToolBoxTag::onTagChanged); +} + +void cToolBoxTag::setTagList(cTagList* lpTagList) +{ + m_bLoading = true; + + m_lpTagList = lpTagList; + + for(cTagList::iterator i = lpTagList->begin();i != lpTagList->end();i++) + { + QStandardItem* lpItem = new QStandardItem((*i)->name()); + lpItem->setData(QVariant::fromValue(*i), Qt::UserRole+1); + lpItem->setCheckable(true); + m_lpTagListModel->appendRow(lpItem); + } + + m_bLoading = false; +} + +void cToolBoxTag::setPicture(cPictureList& pictureList) +{ + m_bLoading = true; + + m_pictureList.clear(); + + for(int i = 0;i < m_lpTagListModel->rowCount();i++) + { + QStandardItem* lpItem = m_lpTagListModel->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); + cTagList& tagList = (*i)->tagList(); + + for(cTagList::iterator j = tagList.begin();j != tagList.end();j++) + { + if(list.contains((*j)->id())) + list[(*j)->id()] ++; + else + list.insert((*j)->id(), 1); + } + } + + for(int i = 0;i < m_lpTagListModel->rowCount();i++) + { + QStandardItem* lpItem = m_lpTagListModel->item(i, 0); + cTag* lpTag = lpItem->data().value(); + + if(list.contains(lpTag->id())) + { + if(list[lpTag->id()] == count) + lpItem->setCheckState(Qt::Checked); + else + lpItem->setCheckState(Qt::PartiallyChecked); + } + } + m_bLoading = false; +} + +void cToolBoxTag::onTagSelected(const QItemSelection& /*selection*/, const QItemSelection& /*previous*/) +{ + if(ui->m_lpTagList->selectionModel()->selectedIndexes().count() == 1) + { + ui->m_lpEdit->setEnabled(true); + ui->m_lpDelete->setEnabled(true); + } + else if(ui->m_lpTagList->selectionModel()->selectedIndexes().count() > 1) + { + ui->m_lpEdit->setEnabled(false); + ui->m_lpDelete->setEnabled(true); + } +} + +void cToolBoxTag::tagChanged(const QModelIndex& /*topLeft*/, const QModelIndex& /*bottomright*/, const QVector& /*roles*/) +{ + if(!m_pictureList.count()) + return; + + if(m_bLoading) + return; + + for(int x = 0;x < m_lpTagListModel->rowCount();x++) + { + QStandardItem* lpItem = m_lpTagListModel->item(x, 0); + + if(lpItem->checkState() != Qt::PartiallyChecked) + { + cTag* lpTag = lpItem->data(Qt::UserRole+1).value(); + if(lpTag) + { + for(cPictureList::iterator i = m_pictureList.begin();i != m_pictureList.end();i++) + { + if(lpItem->checkState() == Qt::Checked) + (*i)->addTag(lpTag); + else if(lpItem->checkState() == Qt::Unchecked) + (*i)->removeTag(lpTag); + } + } + } + } + + for(cPictureList::iterator i = m_pictureList.begin();i != m_pictureList.end();i++) + (*i)->toDB(); +} + +void cToolBoxTag::onTagAdd() +{ + QInputDialog input(this); + + input.setLabelText(tr("name:")); + input.setWindowTitle(tr("New Tag")); + if(input.exec() == QDialog::Rejected) + return; + + if(input.textValue().isEmpty()) + return; + + cTag* lpTag = new cTag; + lpTag->setName(input.textValue()); + if(!lpTag->toDB()) + { + delete lpTag; + return; + } + + m_lpTagList->add(lpTag); + + m_bLoading = true; + + QStandardItem* lpItem = new QStandardItem(lpTag->name()); + lpItem->setData(QVariant::fromValue(lpTag), Qt::UserRole+1); + lpItem->setCheckable(true); + m_lpTagListModel->appendRow(lpItem); + m_lpTagListModel->sort(0); + + m_bLoading = false; +} + +void cToolBoxTag::onTagEdit() +{ + if(ui->m_lpTagList->selectionModel()->selectedIndexes().count() != 1) + return; + + QStandardItem* lpItem = m_lpTagListModel->itemFromIndex(ui->m_lpTagList->selectionModel()->selectedIndexes()[0]); + if(!lpItem) + return; + + cTag* lpTag = lpItem->data(Qt::UserRole+1).value(); + if(!lpTag) + return; + + QInputDialog input(this); + + input.setLabelText(tr("name:")); + input.setWindowTitle(tr("Edit Tag")); + input.setTextValue(lpTag->name()); + + if(input.exec() == QDialog::Rejected) + return; + + if(input.textValue().isEmpty()) + return; + + lpItem->setText(input.textValue()); +} + +void cToolBoxTag::onTagDelete() +{ + for(int x = ui->m_lpTagList->selectionModel()->selectedIndexes().count()-1;x >= 0; x--) + { + QModelIndex index = ui->m_lpTagList->selectionModel()->selectedIndexes()[x]; + QStandardItem* lpItem = m_lpTagListModel->itemFromIndex(index); + if(lpItem) + { + cTag* lpTag = lpItem->data(Qt::UserRole+1).value(); + if(lpTag) + { + if(QMessageBox::question(this, tr("Delete Tag"), QString(tr("Are you sure you want to delete %1?")).arg(lpTag->name())) == QMessageBox::Yes) + { + if(!m_lpTagList->remove(lpTag)) + QMessageBox::critical(this, tr("Delete Tag"), QString(tr("%1 is in use and can't be deleted!")).arg(lpTag->name())); + else + m_lpTagListModel->removeRow(index.row()); + } + } + } + } + +} + +void cToolBoxTag::onTagViewContextMenu(const QPoint& pos) +{ + QMenu menu(this); + + menu.addAction(m_lpTagAddAction); + + if(ui->m_lpTagList->selectionModel()->selectedIndexes().count() == 1) + menu.addAction(m_lpTagEditAction); + if(ui->m_lpTagList->selectionModel()->selectedIndexes().count() >= 1) + menu.addAction(m_lpTagDeleteAction); + + menu.exec(ui->m_lpTagList->mapToGlobal(pos)); +} + +void cToolBoxTag::onTagChanged(QStandardItem* lpItem) +{ + if(m_bEditing) + return; + + cTag* lpTag = lpItem->data(Qt::UserRole+1).value(); + if(!lpTag) + return; + + if(lpItem->text() == lpTag->name()) + return; + + QString szOldName = lpTag->name(); + lpTag->setName(lpItem->text()); + if(!lpTag->toDB()) + { + QMessageBox::critical(this, tr("ERROR"), QString(tr("%1 already exists.").arg(lpItem->text()))); + m_bEditing = true; + lpItem->setText(szOldName); + lpTag->setName(szOldName); + m_bEditing = false; + } +} diff --git a/ctoolboxtag.h b/ctoolboxtag.h index a77d93f..d5be515 100644 --- a/ctoolboxtag.h +++ b/ctoolboxtag.h @@ -46,10 +46,10 @@ public: /*! \brief - \param lpLocationList - \fn setLocationList + \param lpTagList + \fn setTagList */ - void setLocationList(cLocationList* lpLocationList); + void setTagList(cTagList* lpTagList); /*! \brief @@ -61,14 +61,14 @@ public: private: Ui::cToolBoxTag* ui; /*!< TODO: describe */ - QStandardItemModel* m_lpLocationListModel; /*!< TODO: describe */ - cPersonList* m_lpLocationList; /*!< TODO: describe */ + QStandardItemModel* m_lpTagListModel; /*!< TODO: describe */ + cTagList* m_lpTagList; /*!< 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 */ + QAction* m_lpTagAddAction; /*!< TODO: describe */ + QAction* m_lpTagEditAction; /*!< TODO: describe */ + QAction* m_lpTagDeleteAction; /*!< TODO: describe */ bool m_bEditing; /*!< TODO: describe */ @@ -89,54 +89,54 @@ private slots: /*! \brief - \fn onLocationSelected + \fn onTagSelected \param selection \param previous */ - void onLocationSelected(const QItemSelection& selection, const QItemSelection& previous); + void onTagSelected(const QItemSelection& selection, const QItemSelection& previous); /*! \brief - \fn locationChanged + \fn tagChanged \param topLeft \param bottomright \param roles */ - void locationChanged(const QModelIndex& topLeft, const QModelIndex& bottomright, const QVector& roles); + void tagChanged(const QModelIndex& topLeft, const QModelIndex& bottomright, const QVector& roles); /*! \brief - \fn onLocationAdd + \fn onTagAdd */ - void onLocationAdd(); + void onTagAdd(); /*! \brief - \fn onLocationEdit + \fn onTagEdit */ - void onLocationEdit(); + void onTagEdit(); /*! \brief - \fn onLocationDelete + \fn onTagDelete */ - void onLocationDelete(); + void onTagDelete(); /*! \brief - \fn onLocationViewContextMenu + \fn onTagViewContextMenu \param pos */ - void onLocationViewContextMenu(const QPoint& pos); + void onTagViewContextMenu(const QPoint& pos); /*! \brief - \fn onLocationChanged + \fn onTagChanged \param lpItem */ - void onLocationChanged(QStandardItem* lpItem); + void onTagChanged(QStandardItem* lpItem); }; #endif // CTOOLBOXTAG_H