diff --git a/cfilterpanel.cpp b/cfilterpanel.cpp index cbcc25b..27d3e9c 100644 --- a/cfilterpanel.cpp +++ b/cfilterpanel.cpp @@ -35,6 +35,17 @@ void cFilterPanel::initUI() void cFilterPanel::createActions() { + connect(ui->m_lpPersonFilter, &QGroupBox::toggled, this, &cFilterPanel::onPersonFilter); + connect(ui->m_lpLocationFilter, &QGroupBox::toggled, this, &cFilterPanel::onLocationFilter); + connect(ui->m_lpTagFilter, &QGroupBox::toggled, this, &cFilterPanel::onTagFilter); + + connect(ui->m_lpPersonAnd, &QRadioButton::toggled, this, &cFilterPanel::onPersonAnd); + connect(ui->m_lpLocationAnd, &QRadioButton::toggled, this, &cFilterPanel::onLocationAnd); + connect(ui->m_lpTagsAnd, &QRadioButton::toggled, this, &cFilterPanel::onTagAnd); + + connect(m_lpPersonListModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), SLOT(onPersonChanged(QModelIndex, QModelIndex, QVector))); + connect(m_lpLocationListModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), SLOT(onLocationChanged(QModelIndex, QModelIndex, QVector))); + connect(m_lpTagListModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), SLOT(onTagChanged(QModelIndex, QModelIndex, QVector))); } void cFilterPanel::clearPersonList() @@ -182,3 +193,120 @@ void cFilterPanel::updateTagList() m_bLoading = false; } + +void cFilterPanel::onPersonChanged() +{ + if(m_bLoading) + return; + + QList idList; + + for(int x = 0;x < m_lpPersonListModel->rowCount();x++) + { + QStandardItem* lpItem = m_lpPersonListModel->item(x, 0); + + if(lpItem->checkState() == Qt::Checked) + { + cPerson* lpPerson = lpItem->data(Qt::UserRole+1).value(); + if(lpPerson) + idList.append(lpPerson->id()); + } + } + emit personChanged(idList, ui->m_lpPersonAnd->isChecked()); +} + +void cFilterPanel::onPersonAnd(bool /*bToggle*/) +{ + onPersonChanged(); +} + +void cFilterPanel::onPersonFilter(bool bToggle) +{ + if(bToggle) + onPersonChanged(); + else + emit(personChanged(QList(), false)); +} + +void cFilterPanel::onPersonChanged(const QModelIndex& /*topLeft*/, const QModelIndex& /*bottomright*/, const QVector& /*roles*/) +{ + onPersonChanged(); +} + +void cFilterPanel::onLocationChanged() +{ + if(m_bLoading) + return; + + QList idList; + + for(int x = 0;x < m_lpLocationListModel->rowCount();x++) + { + QStandardItem* lpItem = m_lpLocationListModel->item(x, 0); + + if(lpItem->checkState() == Qt::Checked) + { + cLocation* lpLocation = lpItem->data(Qt::UserRole+1).value(); + if(lpLocation) + idList.append(lpLocation->id()); + } + } + emit locationChanged(idList, ui->m_lpLocationAnd->isChecked()); +} + +void cFilterPanel::onLocationFilter(bool bToggle) +{ + if(bToggle) + onLocationChanged(); + else + emit(locationChanged(QList(), false)); +} + +void cFilterPanel::onLocationAnd(bool /*bToggle*/) +{ + onLocationChanged(); +} + +void cFilterPanel::onLocationChanged(const QModelIndex& /*topLeft*/, const QModelIndex& /*bottomright*/, const QVector& /*roles*/) +{ + onLocationChanged(); +} + +void cFilterPanel::onTagChanged() +{ + if(m_bLoading) + return; + + QList idList; + + for(int x = 0;x < m_lpTagListModel->rowCount();x++) + { + QStandardItem* lpItem = m_lpTagListModel->item(x, 0); + + if(lpItem->checkState() == Qt::Checked) + { + cTag* lpTag = lpItem->data(Qt::UserRole+1).value(); + if(lpTag) + idList.append(lpTag->id()); + } + } + emit tagChanged(idList, ui->m_lpTagsAnd->isChecked()); +} + +void cFilterPanel::onTagFilter(bool bToggle) +{ + if(bToggle) + onTagChanged(); + else + emit(tagChanged(QList(), false)); +} + +void cFilterPanel::onTagAnd(bool /*bToggle*/) +{ + onTagChanged(); +} + +void cFilterPanel::onTagChanged(const QModelIndex& /*topLeft*/, const QModelIndex& /*bottomright*/, const QVector& /*roles*/) +{ + onTagChanged(); +} diff --git a/cfilterpanel.h b/cfilterpanel.h index 48cb8eb..7572d48 100644 --- a/cfilterpanel.h +++ b/cfilterpanel.h @@ -108,6 +108,117 @@ private: \fn createActions */ void createActions(); + + /*! + \brief + + \fn onPersonChanged + */ + void onPersonChanged(); + /*! + \brief + + \fn onLocationChanged + */ + void onLocationChanged(); + /*! + \brief + + \fn onTagChanged + */ + void onTagChanged(); +private slots: + /*! + \brief + + \fn onPersonFilter + \param bToggle + */ + void onPersonFilter(bool bToggle); + /*! + \brief + + \fn onPersonAnd + \param bToggle + */ + void onPersonAnd(bool bToggle); + /*! + \brief + + \fn onPersonChanged + \param topLeft + \param bottomright + \param roles + */ + void onPersonChanged(const QModelIndex& topLeft, const QModelIndex& bottomright, const QVector& roles); + /*! + \brief + + \fn onLocationFilter + \param bToggle + */ + void onLocationFilter(bool bToggle); + /*! + \brief + + \fn onLocationAnd + \param bToggle + */ + void onLocationAnd(bool bToggle); + /*! + \brief + + \fn onLocationChanged + \param topLeft + \param bottomright + \param roles + */ + void onLocationChanged(const QModelIndex& topLeft, const QModelIndex& bottomright, const QVector& roles); + /*! + \brief + + \fn onTagFilter + \param bToggle + */ + void onTagFilter(bool bToggle); + /*! + \brief + + \fn onTagAnd + \param bToggle + */ + void onTagAnd(bool bToggle); + /*! + \brief + + \fn onTagChanged + \param topLeft + \param bottomright + \param roles + */ + void onTagChanged(const QModelIndex& topLeft, const QModelIndex& bottomright, const QVector& roles); +signals: + /*! + \brief + + \fn personChanged + \param idList + */ + void personChanged(QList idList, bool bAnd); + /*! + \brief + + \fn locationChanged + \param idList + */ + void locationChanged(QList idList, bool bAnd); + /*! + \brief + + \fn tagChanged + \param idList + */ + void tagChanged(QList idList, bool bAnd); }; #endif // CFILTERPANEL_H diff --git a/cfilterpanel.ui b/cfilterpanel.ui index de367a8..d372a3e 100644 --- a/cfilterpanel.ui +++ b/cfilterpanel.ui @@ -25,7 +25,7 @@ true - + QAbstractItemView::NoEditTriggers @@ -41,6 +41,40 @@ + + + + + + and + + + true + + + + + + + or + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -53,7 +87,7 @@ true - + QAbstractItemView::NoEditTriggers @@ -69,6 +103,40 @@ + + + + + + and + + + true + + + + + + + or + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + @@ -81,7 +149,7 @@ true - + QAbstractItemView::NoEditTriggers @@ -97,6 +165,40 @@ + + + + + + and + + + true + + + + + + + or + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + diff --git a/clocation.cpp b/clocation.cpp index 3955b86..2c59560 100644 --- a/clocation.cpp +++ b/clocation.cpp @@ -282,3 +282,40 @@ QStringList cLocationList::locationList() szLocationList.sort(Qt::CaseInsensitive); return(szLocationList); } + +bool cLocationList::contains(cLocation* const& lpLocation) +{ + return(QList::contains(lpLocation)); +} + +bool cLocationList::contains(QList idList, bool bAnd) +{ + if(bAnd) + { + int found = 0; + + for(QList::iterator z = idList.begin();z != idList.end();z++) + { + for(cLocationList::iterator i = begin();i != end();i++) + { + if((*i)->id() == (*z)) + { + found++; + break; + } + } + } + if(found == idList.count()) + return(true); + return(false); + } + else + { + for(cLocationList::iterator i = begin();i != end();i++) + { + if(idList.contains((*i)->id())) + return(true); + } + return(false); + } +} diff --git a/clocation.h b/clocation.h index f34201c..725d28f 100644 --- a/clocation.h +++ b/clocation.h @@ -197,6 +197,22 @@ public: \return bool */ bool remove(cLocation* lpLocation); + /*! + \brief + + \fn contains + \param lpLocation + \return bool + */ + bool contains(cLocation* const &lpLocation); + /*! + \brief + + \fn contains + \param idList + \return bool + */ + bool contains(QList idList, bool bAnd); /*! \brief diff --git a/cmainwindow.cpp b/cmainwindow.cpp index f6eac8d..7dfe174 100644 --- a/cmainwindow.cpp +++ b/cmainwindow.cpp @@ -151,6 +151,10 @@ void cMainWindow::createActions() connect(ui->m_lpToolBoxLocation, &cToolBoxLocation::locationRemoved, this, &cMainWindow::onLocationRemoved); connect(ui->m_lpToolBoxLocation, &cToolBoxLocation::locationEdited, this, &cMainWindow::onLocationEdited); connect(ui->m_lpToolBoxLocation, &cToolBoxLocation::locationListChanged, this, &cMainWindow::onLocationListChanged); + + connect(m_lpFilterPanel, &cFilterPanel::personChanged, this, &cMainWindow::onFilterPersonChanged); + connect(m_lpFilterPanel, &cFilterPanel::locationChanged, this, &cMainWindow::onFilterLocationChanged); + connect(m_lpFilterPanel, &cFilterPanel::tagChanged, this, &cMainWindow::onFilterTagChanged); } void cMainWindow::createContextActions() @@ -890,3 +894,27 @@ void cMainWindow::onLocationListChanged() { m_lpFilterPanel->updateLocationList(); } + +void cMainWindow::onFilterPersonChanged(QList idList, bool bAnd) +{ + if(m_bLoading) + return; + + m_lpThumbnailSortFilterProxyModel->setPersonList(idList, bAnd); +} + +void cMainWindow::onFilterLocationChanged(QList idList, bool bAnd) +{ + if(m_bLoading) + return; + + m_lpThumbnailSortFilterProxyModel->setLocationList(idList, bAnd); +} + +void cMainWindow::onFilterTagChanged(QList idList, bool bAnd) +{ + if(m_bLoading) + return; + + m_lpThumbnailSortFilterProxyModel->setTagList(idList, bAnd); +} diff --git a/cmainwindow.h b/cmainwindow.h index e19c675..043c12b 100644 --- a/cmainwindow.h +++ b/cmainwindow.h @@ -351,6 +351,28 @@ private slots: \fn onLocationListChanged */ void onLocationListChanged(); + + /*! + \brief + + \fn onFilterPersonChanged + \param idList + */ + void onFilterPersonChanged(QList idList, bool bAnd); + /*! + \brief + + \fn onFilterLocationChanged + \param idList + */ + void onFilterLocationChanged(QList idList, bool bAnd); + /*! + \brief + + \fn onFilterTagChanged + \param idList + */ + void onFilterTagChanged(QList idList, bool bAnd); }; #endif // CMAINWINDOW_H diff --git a/cperson.cpp b/cperson.cpp index 7c0835b..41968a5 100644 --- a/cperson.cpp +++ b/cperson.cpp @@ -289,3 +289,40 @@ QStringList cPersonList::personList() szPersonList.sort(Qt::CaseInsensitive); return(szPersonList); } + +bool cPersonList::contains(cPerson* const& lpPerson) +{ + return(QList::contains(lpPerson)); +} + +bool cPersonList::contains(QList idList, bool bAnd) +{ + if(bAnd) + { + int found = 0; + + for(QList::iterator z = idList.begin();z != idList.end();z++) + { + for(cPersonList::iterator i = begin();i != end();i++) + { + if((*i)->id() == (*z)) + { + found++; + break; + } + } + } + if(found == idList.count()) + return(true); + return(false); + } + else + { + for(cPersonList::iterator i = begin();i != end();i++) + { + if(idList.contains((*i)->id())) + return(true); + } + return(false); + } +} diff --git a/cperson.h b/cperson.h index d7b8b34..4494e00 100644 --- a/cperson.h +++ b/cperson.h @@ -197,6 +197,22 @@ public: \return bool */ bool remove(cPerson* lpPerson); + /*! + \brief + + \fn contains + \param lpPerson + \return bool + */ + bool contains(cPerson * const &lpPerson); + /*! + \brief + + \fn contains + \param idList + \return bool + */ + bool contains(QList idList, bool bAnd); /*! \brief diff --git a/ctag.cpp b/ctag.cpp index f751f9a..90062ef 100644 --- a/ctag.cpp +++ b/ctag.cpp @@ -282,3 +282,40 @@ QStringList cTagList::tagList() szTagList.sort(Qt::CaseInsensitive); return(szTagList); } + +bool cTagList::contains(cTag* const& lpTag) +{ + return(QList::contains(lpTag)); +} + +bool cTagList::contains(QList idList, bool bAnd) +{ + if(bAnd) + { + int found = 0; + + for(QList::iterator z = idList.begin();z != idList.end();z++) + { + for(cTagList::iterator i = begin();i != end();i++) + { + if((*i)->id() == (*z)) + { + found++; + break; + } + } + } + if(found == idList.count()) + return(true); + return(false); + } + else + { + for(cTagList::iterator i = begin();i != end();i++) + { + if(idList.contains((*i)->id())) + return(true); + } + return(false); + } +} diff --git a/ctag.h b/ctag.h index a87ca02..5913c02 100644 --- a/ctag.h +++ b/ctag.h @@ -188,7 +188,7 @@ public: \param szName \return cTag */ - cTag* find(const QString& szName); + cTag* find(const QString& szName); /*! \brief @@ -197,6 +197,22 @@ public: \return bool */ bool remove(cTag* lpTag); + /*! + \brief + + \fn contains + \param lpTag + \return bool + */ + bool contains(cTag* const &lpTag); + /*! + \brief + + \fn contains + \param idList + \return bool + */ + bool contains(QList idList, bool bAnd); /*! \brief diff --git a/cthumbnailsortfilterproxymodel.cpp b/cthumbnailsortfilterproxymodel.cpp index 9681ab0..ee85519 100644 --- a/cthumbnailsortfilterproxymodel.cpp +++ b/cthumbnailsortfilterproxymodel.cpp @@ -25,10 +25,48 @@ QString cThumbnailSortFilterProxyModel::filterPath() return(m_szPath); } +QList cThumbnailSortFilterProxyModel::personList() +{ + return(m_personList); +} + +void cThumbnailSortFilterProxyModel::setPersonList(const QList& personList, bool bAnd) +{ + m_personList = personList; + m_bPersonAnd = bAnd; + + invalidateFilter(); +} + +QList cThumbnailSortFilterProxyModel::locationList() +{ + return(m_locationList); +} + +void cThumbnailSortFilterProxyModel::setLocationList(const QList& locationList, bool bAnd) +{ + m_locationList = locationList; + m_bLocationAnd = bAnd; + + invalidateFilter(); +} + +QList cThumbnailSortFilterProxyModel::tagList() +{ + return(m_tagList); +} + +void cThumbnailSortFilterProxyModel::setTagList(const QList& tagList, bool bAnd) +{ + m_tagList = tagList; + m_bTagAnd = bAnd; + + invalidateFilter(); +} + bool cThumbnailSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { - if(m_szPath.isEmpty()) - return(true); + bool bValid = false; QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent); cPicture* lpPicture = sourceModel()->data(index0, Qt::UserRole+1).value(); @@ -36,16 +74,42 @@ bool cThumbnailSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QMode if(!lpPicture) return(false); - QString szPath = lpPicture->filePath(); + if(m_szPath.isEmpty()) + bValid = true; + else + { + QString szPath = lpPicture->filePath(); - if(!szPath.startsWith(m_szPath)) + if(!szPath.startsWith(m_szPath)) + return(false); + + if(szPath.length() == m_szPath.length()) + bValid = true; + + if(szPath.mid(m_szPath.length(), 1) == "/") + bValid = true; + } + + if(!bValid) return(false); - if(szPath.length() == m_szPath.length()) - return(true); + if(!m_personList.isEmpty()) + { + if(!lpPicture->personList().contains(m_personList, m_bPersonAnd)) + return(false); + } - if(szPath.mid(m_szPath.length(), 1) == "/") - return(true); + if(!m_locationList.isEmpty()) + { + if(!lpPicture->locationList().contains(m_locationList, m_bLocationAnd)) + return(false); + } - return(false); + if(!m_tagList.isEmpty()) + { + if(!lpPicture->tagList().contains(m_tagList, m_bTagAnd)) + return(false); + } + + return(true); } diff --git a/cthumbnailsortfilterproxymodel.h b/cthumbnailsortfilterproxymodel.h index 58e7416..88cbb71 100644 --- a/cthumbnailsortfilterproxymodel.h +++ b/cthumbnailsortfilterproxymodel.h @@ -36,6 +36,48 @@ public: */ void setFilterPath(const QString& szPath); + /*! + \brief + + \fn personList + */ + QList personList(); + /*! + \brief + + \fn setPersonList + \param personList + */ + void setPersonList(const QList& personList, bool bAnd); + + /*! + \brief + + \fn locationList + */ + QList locationList(); + /*! + \brief + + \fn setLocationList + \param locationList + */ + void setLocationList(const QList& locationList, bool bAnd); + + /*! + \brief + + \fn tagList + */ + QList tagList(); + /*! + \brief + + \fn setTagList + \param tagList + */ + void setTagList(const QList& tagList, bool bAnd); + protected: /*! \brief @@ -49,6 +91,12 @@ protected: private: QString m_szPath; /*!< TODO: describe */ + QList m_personList; /*!< TODO: describe */ + QList m_locationList; /*!< TODO: describe */ + QList m_tagList; /*!< TODO: describe */ + bool m_bPersonAnd; /*!< TODO: describe */ + bool m_bLocationAnd; /*!< TODO: describe */ + bool m_bTagAnd; /*!< TODO: describe */ }; #endif // CTHUMBNAILFILTERPROXYMODEL_H