From cea01d06b72e22e7b8fdea8e4aec4e86da790724 Mon Sep 17 00:00:00 2001 From: emeric Date: Mon, 5 Feb 2018 13:39:45 +0100 Subject: [PATCH] Make filters really work --- approot/messages.xml | 5 ++ approot/templates.xml | 26 +++++++++ src/database/DbArtist.cpp | 6 +-- src/database/DbArtist.hpp | 4 +- src/database/Release.cpp | 6 +-- src/database/Release.hpp | 4 +- src/database/Track.cpp | 13 ++++- src/database/Track.hpp | 3 +- src/ui/ArtistView.cpp | 4 ++ src/ui/ArtistsView.cpp | 5 +- src/ui/Filters.cpp | 111 +++++++++++++++++++++++++++++++++++++- src/ui/Filters.hpp | 10 +++- src/ui/ReleasesView.cpp | 4 ++ src/ui/TracksView.cpp | 4 ++ 14 files changed, 187 insertions(+), 18 deletions(-) diff --git a/approot/messages.xml b/approot/messages.xml index 196a7296..44479447 100644 --- a/approot/messages.xml +++ b/approot/messages.xml @@ -10,4 +10,9 @@ Add filter Search... +Add +Cancel + +Type +Value diff --git a/approot/templates.xml b/approot/templates.xml index 1780e53d..5f93b41d 100644 --- a/approot/templates.xml +++ b/approot/templates.xml @@ -22,4 +22,30 @@ + +
+
+ +
+ ${type} +
+
+
+ +
+ ${value} +
+
+
+
+ ${add class="btn-primary"} ${cancel} +
+
+
+
+ diff --git a/src/database/DbArtist.cpp b/src/database/DbArtist.cpp index 7dc341f6..413e40c4 100644 --- a/src/database/DbArtist.cpp +++ b/src/database/DbArtist.cpp @@ -91,7 +91,7 @@ Artist::getAllOrphans(Wt::Dbo::Session& session) static Wt::Dbo::Query getQuery(Wt::Dbo::Session& session, - const std::vector& clusterIds, + const std::set& clusterIds, const std::vector& keywords) { WhereClause where; @@ -132,7 +132,7 @@ getQuery(Wt::Dbo::Session& session, std::vector Artist::getByFilter(Wt::Dbo::Session& session, - const std::vector& clusters, + const std::set& clusters, const std::vector keywords, int offset, int size, bool& moreResults) { @@ -152,7 +152,7 @@ Artist::getByFilter(Wt::Dbo::Session& session, } std::vector > -Artist::getReleases(const std::vector& clusterIds) const +Artist::getReleases(const std::set& clusterIds) const { assert(self()); assert(self()->id() != Wt::Dbo::dbo_traits::invalidId() ); diff --git a/src/database/DbArtist.hpp b/src/database/DbArtist.hpp index 7b45bcb6..47c7d24f 100644 --- a/src/database/DbArtist.hpp +++ b/src/database/DbArtist.hpp @@ -51,7 +51,7 @@ class Artist : public Wt::Dbo::Dbo static pointer getNone(Wt::Dbo::Session& session); // Special entry static std::vector getByName(Wt::Dbo::Session& session, const std::string& name); static std::vector getByFilter(Wt::Dbo::Session& session, - const std::vector& clusters, // at least one track that belongs to these clusters + const std::set& clusters, // at least one track that belongs to these clusters const std::vector keywords, // name must match all of these keywords int offset, int size, @@ -65,7 +65,7 @@ class Artist : public Wt::Dbo::Dbo std::string getMBID(void) const { return _MBID; } // Get the releases that have at least one track for this artist + belongs to optonal cluster filters - std::vector> getReleases(const std::vector& clusterIds = std::vector()) const; + std::vector> getReleases(const std::set& clusterIds = std::set()) const; void setMBID(std::string mbid) { _MBID = mbid; } diff --git a/src/database/Release.cpp b/src/database/Release.cpp index a7f15dea..2b338e34 100644 --- a/src/database/Release.cpp +++ b/src/database/Release.cpp @@ -90,7 +90,7 @@ Release::getAllOrphans(Wt::Dbo::Session& session) static Wt::Dbo::Query getQuery(Wt::Dbo::Session& session, - const std::vector& clusterIds, + const std::set& clusterIds, const std::vector keywords) { WhereClause where; @@ -130,7 +130,7 @@ getQuery(Wt::Dbo::Session& session, std::vector Release::getByFilter(Wt::Dbo::Session& session, - const std::vector& clusterIds, + const std::set& clusterIds, const std::vector keywords, int offset, int size, bool& moreResults) { @@ -195,7 +195,7 @@ Release::hasVariousArtists() const } std::vector> -Release::getTracks(const std::vector& clusterIds) const +Release::getTracks(const std::set& clusterIds) const { assert(self()); assert(self()->id() != Wt::Dbo::dbo_traits::invalidId() ); diff --git a/src/database/Release.hpp b/src/database/Release.hpp index 390d60a0..3feb0100 100644 --- a/src/database/Release.hpp +++ b/src/database/Release.hpp @@ -51,13 +51,13 @@ class Release : public Wt::Dbo::Dbo static std::vector getAll(Wt::Dbo::Session& session, int offset, int size); static std::vector getByFilter(Wt::Dbo::Session& session, - const std::vector& clusters, // at least one track that belongs to these clusters + const std::set& clusters, // at least one track that belongs to these clusters const std::vector keywords, // name must match all of these keywords int offset, int size, bool& moreExpected); - std::vector> getTracks(const std::vector& clusters = std::vector()) const; + std::vector> getTracks(const std::set& clusters = std::set()) const; // Create static pointer create(Wt::Dbo::Session& session, const std::string& name, const std::string& MBID = ""); diff --git a/src/database/Track.cpp b/src/database/Track.cpp index 65e3319e..50c16a4d 100644 --- a/src/database/Track.cpp +++ b/src/database/Track.cpp @@ -111,7 +111,7 @@ Track::getClusters(void) const static Wt::Dbo::Query< Track::pointer > getQuery(Wt::Dbo::Session& session, - const std::vector& clusterIds, + const std::set& clusterIds, const std::vector keywords) { WhereClause where; @@ -165,7 +165,7 @@ Track::getStats(Wt::Dbo::Session& session, SearchFilter filter) std::vector Track::getByFilter(Wt::Dbo::Session& session, - const std::vector& clusterIds, + const std::set& clusterIds, const std::vector keywords, int offset, int size, bool& moreResults) { @@ -282,6 +282,15 @@ Cluster::getQuery(Wt::Dbo::Session& session, SearchFilter filter) return query; } +std::vector +Cluster::getAllTypes(Wt::Dbo::Session& session) +{ + Wt::Dbo::collection res + = session.query("SELECT type from cluster").groupBy("type").orderBy("type"); + + return std::vector(res.begin(), res.end()); +} + std::vector Cluster::getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset, int size) { diff --git a/src/database/Track.hpp b/src/database/Track.hpp index d1af053c..0d81a36d 100644 --- a/src/database/Track.hpp +++ b/src/database/Track.hpp @@ -62,6 +62,7 @@ class Cluster static pointer getNone(Wt::Dbo::Session& session); static std::vector getByFilter(Wt::Dbo::Session& session, SearchFilter filter, int offset = -1, int size = -1); static Wt::Dbo::collection getAll(Wt::Dbo::Session& session); + static std::vector getAllTypes(Wt::Dbo::Session& session); static std::vector getByType(Wt::Dbo::Session& session, std::string type); // Create utility @@ -120,7 +121,7 @@ class Track static pointer getById(Wt::Dbo::Session& session, id_type id); static pointer getByMBID(Wt::Dbo::Session& session, const std::string& MBID); static std::vector getByFilter(Wt::Dbo::Session& session, - const std::vector& clusters, // tracks that belong to these clusters + const std::set& clusters, // tracks that belong to these clusters const std::vector keywords, // name must match all of these keywords int offset, int size, diff --git a/src/ui/ArtistView.cpp b/src/ui/ArtistView.cpp index 9c98dd93..0e17096b 100644 --- a/src/ui/ArtistView.cpp +++ b/src/ui/ArtistView.cpp @@ -43,6 +43,10 @@ Artist::Artist(Filters* filters, Wt::WContainerWidget* parent) })); refresh(); + + filters->updated().connect(std::bind([=] { + refresh(); + })); } void diff --git a/src/ui/ArtistsView.cpp b/src/ui/ArtistsView.cpp index e684db2d..be50e252 100644 --- a/src/ui/ArtistsView.cpp +++ b/src/ui/ArtistsView.cpp @@ -54,8 +54,11 @@ Artists::Artists(Filters* filters, Wt::WContainerWidget* parent) artists->bindWidget("artists", _artistsContainer); refresh(); -} + filters->updated().connect(std::bind([=] { + refresh(); + })); +} void Artists::refresh(std::vector searchKeywords) diff --git a/src/ui/Filters.cpp b/src/ui/Filters.cpp index 8dc3f131..872ba5ce 100644 --- a/src/ui/Filters.cpp +++ b/src/ui/Filters.cpp @@ -17,13 +17,116 @@ * along with LMS. If not, see . */ -#include +#include +#include #include +#include #include "Filters.hpp" +#include "LmsApplication.hpp" + namespace UserInterface { +void +Filters::showDialog() +{ + auto dialog = new Wt::WDialog("Go to cell"); + + auto container = new Wt::WTemplate(Wt::WString::tr("template-filter-add")); + container->addFunction("tr", &Wt::WTemplate::Functions::tr); + + dialog->contents()->addWidget(container); + + auto typeCombo = new Wt::WComboBox(); + container->bindWidget("type", typeCombo); + + auto valueCombo = new Wt::WComboBox(); + container->bindWidget("value", valueCombo); + + auto addBtn = new Wt::WPushButton(Wt::WString::tr("msg-add")); + container->bindWidget("add", addBtn); + addBtn->clicked().connect(dialog, &Wt::WDialog::accept); + + auto cancelBtn = new Wt::WPushButton(Wt::WString::tr("msg-cancel")); + container->bindWidget("cancel", cancelBtn); + cancelBtn->clicked().connect(dialog, &Wt::WDialog::reject); + + // Populate data + { + Wt::Dbo::Transaction transaction(DboSession()); + + auto types = Database::Cluster::getAllTypes(DboSession()); + + for (auto type : types) + typeCombo->addItem(Wt::WString::fromUTF8(type)); + + if (!types.empty()) + { + auto values = Database::Cluster::getByType(DboSession(), types.front()); + + for (auto value : values) + { + if (_filterIds.find(value.id()) == _filterIds.end()) + valueCombo->addItem(Wt::WString::fromUTF8(value->getName())); + } + } + + } + + typeCombo->changed().connect(std::bind([=] + { + auto type = typeCombo->valueText().toUTF8(); + + valueCombo->clear(); + + Wt::Dbo::Transaction transaction(DboSession()); + + auto values = Database::Cluster::getByType(DboSession(), type); + for (auto value : values) + { + if (_filterIds.find(value.id()) == _filterIds.end()) + valueCombo->addItem(Wt::WString::fromUTF8(value->getName())); + } + })); + + dialog->setModal(true); + dialog->setMovable(false); + dialog->setResizable(false); + dialog->setClosable(false); + + dialog->finished().connect(std::bind([=] + { + if (dialog->result() != Wt::WDialog::Accepted) + return; + + auto type = typeCombo->valueText().toUTF8(); + auto value = valueCombo->valueText().toUTF8(); + + Wt::Dbo::Transaction transaction(DboSession()); + + auto cluster = Database::Cluster::get(DboSession(), type, value); + if (!cluster) + return; + + auto clusterId = cluster.id(); + _filterIds.insert(clusterId); + _sigUpdated.emit(); + + auto filterBtn = new Wt::WPushButton(Wt::WString::fromUTF8(value)); + _filters->addWidget(filterBtn); + + filterBtn->clicked().connect(std::bind([=] + { + _filters->removeWidget(filterBtn); + _filterIds.erase(clusterId); + _sigUpdated.emit(); + })); + })); + + dialog->show(); +} + Filters::Filters(Wt::WContainerWidget *parent) : Wt::WContainerWidget(parent) { @@ -36,7 +139,11 @@ Filters::Filters(Wt::WContainerWidget *parent) _filters = new Wt::WContainerWidget(); container->bindWidget("filters", _filters); -// _filterIds = {108, 419}; + addFilterBtn->clicked().connect(std::bind([this] + { + showDialog(); + })); + } diff --git a/src/ui/Filters.hpp b/src/ui/Filters.hpp index 98d2e4c0..d0753915 100644 --- a/src/ui/Filters.hpp +++ b/src/ui/Filters.hpp @@ -20,6 +20,7 @@ #pragma once #include +#include #include "database/Types.hpp" @@ -32,12 +33,17 @@ class Filters : public Wt::WContainerWidget public: Filters(Wt::WContainerWidget *parent = 0); - std::vector getClusterIds() const { return _filterIds; } + std::set getClusterIds() const { return _filterIds; } + + Wt::Signal& updated() { return _sigUpdated; } private: + void showDialog(); + Wt::WContainerWidget *_filters; - std::vector _filterIds; + Wt::Signal _sigUpdated; + std::set _filterIds; }; } // namespace UserInterface diff --git a/src/ui/ReleasesView.cpp b/src/ui/ReleasesView.cpp index 414c1418..270abe89 100644 --- a/src/ui/ReleasesView.cpp +++ b/src/ui/ReleasesView.cpp @@ -56,6 +56,10 @@ Releases::Releases(Filters* filters, Wt::WContainerWidget* parent) releases->bindWidget("releases", _releasesContainer); refresh(); + + filters->updated().connect(std::bind([=] { + refresh(); + })); } diff --git a/src/ui/TracksView.cpp b/src/ui/TracksView.cpp index c904c6ae..7ae1b3ae 100644 --- a/src/ui/TracksView.cpp +++ b/src/ui/TracksView.cpp @@ -55,6 +55,10 @@ Tracks::Tracks(Filters* filters, Wt::WContainerWidget* parent) tracks->bindWidget("tracks", _tracksContainer); refresh(); + + filters->updated().connect(std::bind([=] { + refresh(); + })); }