From: APTX Date: Mon, 9 Nov 2015 14:11:12 +0000 (+0100) Subject: Add Watched Directories Tab. X-Git-Url: https://gitweb.aptx.org/?a=commitdiff_plain;h=3792da99697be6271ea80aa4ce5fd379539cd67d;p=localmylist.git Add Watched Directories Tab. The tab allows editing of watched directories. A synthetic primary key was added to the watched_directory table to allow use with QtSQL classes. Watched directories can now be disabled. Triggers were added to automatically update watched directories when the table contents changes. Database::getWatchedDirectories can now return all or only currently enabled directories. The latter is the default. This change requires a schema update. --- diff --git a/localmylist-management/localmylist-management.pro b/localmylist-management/localmylist-management.pro index 112f119..d620ff4 100644 --- a/localmylist-management/localmylist-management.pro +++ b/localmylist-management/localmylist-management.pro @@ -31,6 +31,7 @@ SOURCES += main.cpp\ tabs/dynamicmodeltab.cpp \ tabs/pathmappingtab.cpp \ tabs/hosttab.cpp \ + tabs/watcheddirectoriestab.cpp \ fonts.cpp \ aniaddsyntaxhighlighter.cpp \ settingsdialog.cpp \ @@ -59,6 +60,7 @@ HEADERS += mainwindow.h \ tabs/dynamicmodeltab.h \ tabs/pathmappingtab.h \ tabs/hosttab.h \ + tabs/watcheddirectoriestab.h \ fonts.h \ aniaddsyntaxhighlighter.h \ settingsdialog.h \ @@ -79,7 +81,8 @@ FORMS += mainwindow.ui \ tabs/clientlogtab.ui \ tabs/dynamicmodeltab.ui \ tabs/pathmappingtab.ui \ - tabs/hosttab.ui + tabs/hosttab.ui \ + tabs/watcheddirectoriestab.ui RESOURCES += resources.qrc diff --git a/localmylist-management/registertabs.cpp b/localmylist-management/registertabs.cpp index 2e85cd9..2115be5 100644 --- a/localmylist-management/registertabs.cpp +++ b/localmylist-management/registertabs.cpp @@ -8,6 +8,7 @@ #include "tabs/clientlogtab.h" #include "tabs/dynamicmodeltab.h" #include "tabs/pathmappingtab.h" +#include "tabs/watcheddirectoriestab.h" #include "tabs/hosttab.h" void registerTabs() @@ -20,6 +21,7 @@ void registerTabs() TabWidget::registerTab(); TabWidget::registerTab(); TabWidget::registerTab(); + TabWidget::registerTab(); TabWidget::registerTab(); TabWidget::registerTab(); } diff --git a/localmylist-management/tabs/watcheddirectoriestab.cpp b/localmylist-management/tabs/watcheddirectoriestab.cpp new file mode 100644 index 0000000..72c2721 --- /dev/null +++ b/localmylist-management/tabs/watcheddirectoriestab.cpp @@ -0,0 +1,100 @@ +#include "watcheddirectoriestab.h" +#include "ui_watcheddirectoriestab.h" + +#include +#include +#include +#include "mylist.h" +#include "database.h" + +WatchedDirectoriesTab::WatchedDirectoriesTab(QWidget *parent) : + AbstractTabBase(parent), + ui(new Ui::WatchedDirectoriesTab) +{ + ui->setupUi(this); + setLabel(name()); +} + +WatchedDirectoriesTab::~WatchedDirectoriesTab() +{ + delete ui; +} + +QString WatchedDirectoriesTab::staticId() +{ + return "watched_directories"; +} + +QString WatchedDirectoriesTab::name() +{ + return tr("Watched Directories"); +} + +void WatchedDirectoriesTab::init() +{ + model = new QSqlRelationalTableModel(this, + LocalMyList::instance()->database()->connection()); + + model->setTable("watched_directory"); + model->setRelation(1, QSqlRelation("host", "host_id", "name")); + model->setEditStrategy(QSqlTableModel::OnManualSubmit); + + model->setHeaderData(0, Qt::Horizontal, tr("ID")); + model->setHeaderData(1, Qt::Horizontal, tr("Host")); + model->setHeaderData(2, Qt::Horizontal, tr("Directory")); + model->setHeaderData(2, Qt::Horizontal, tr("Enabled")); + + ui->watchedDirectoriesView->setModel(model); + ui->watchedDirectoriesView->hideColumn(0); + ui->watchedDirectoriesView->setItemDelegateForColumn(1, new QSqlRelationalDelegate); + ui->watchedDirectoriesView->setSelectionBehavior(QAbstractItemView::SelectRows); + reload(); +} + +AbstractTab::TabActions WatchedDirectoriesTab::availableActions() const +{ + return Reload | SelectAll | ClearSelection | SaveChanges | DiscardChanges + | AddEntry | RemoveSelected; +} + +void WatchedDirectoriesTab::reload() +{ + model->select(); + ui->watchedDirectoriesView->resizeColumnsToContents(); +} + +void WatchedDirectoriesTab::addEntry() +{ + model->insertRecord(-1, QSqlRecord()); +} + +void WatchedDirectoriesTab::saveChanges() +{ +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) + if(!model->isDirty()) + return; +#endif + + if (model->submitAll()) + return; + + QMessageBox::critical(this, tr("Error while saving changes"), + model->lastError().text()); +} + +void WatchedDirectoriesTab::discardChanges() +{ + model->revertAll(); +} + +void WatchedDirectoriesTab::removeSelected() +{ + using namespace LocalMyList; + + QModelIndexList selection = ui->watchedDirectoriesView->selectionModel()->selectedRows(); + + for (const QModelIndex &idx : selection) + { + model->removeRow(idx.row()); + } +} diff --git a/localmylist-management/tabs/watcheddirectoriestab.h b/localmylist-management/tabs/watcheddirectoriestab.h new file mode 100644 index 0000000..441e3c8 --- /dev/null +++ b/localmylist-management/tabs/watcheddirectoriestab.h @@ -0,0 +1,36 @@ +#ifndef WATCHEDDIRECTORIESTAB_H +#define WATCHEDDIRECTORIESTAB_H + +#include "abstracttab.h" +#include + +namespace Ui { +class WatchedDirectoriesTab; +} + +class WatchedDirectoriesTab : public AbstractTabBase +{ + Q_OBJECT + +public: + explicit WatchedDirectoriesTab(QWidget *parent = 0); + ~WatchedDirectoriesTab(); + + static QString staticId(); + static QString name(); + + void init() override; + + TabActions availableActions() const override; + void reload() override; + void addEntry() override; + void saveChanges() override; + void discardChanges() override; + void removeSelected() override; + +private: + Ui::WatchedDirectoriesTab *ui; + QSqlRelationalTableModel *model; +}; + +#endif // WATCHEDDIRECTORIESTAB_H diff --git a/localmylist-management/tabs/watcheddirectoriestab.ui b/localmylist-management/tabs/watcheddirectoriestab.ui new file mode 100644 index 0000000..40dbc93 --- /dev/null +++ b/localmylist-management/tabs/watcheddirectoriestab.ui @@ -0,0 +1,33 @@ + + + WatchedDirectoriesTab + + + + 0 + 0 + 400 + 300 + + + + Form + + + + 0 + + + 0 + + + 0 + + + + + + + + + diff --git a/localmylist/database.cpp b/localmylist/database.cpp index 5189345..a8ab87a 100644 --- a/localmylist/database.cpp +++ b/localmylist/database.cpp @@ -1472,11 +1472,19 @@ bool Database::clearPendingMyListUpdate(const PendingMyListUpdate &request) return exec(q); } -QStringList Database::getWatchedDirectories(int hostId) +QStringList Database::getWatchedDirectories(int hostId, bool onlyEnabled) { - QSqlQuery &q = prepare("SELECT directory FROM watched_directory WHERE host_id = :hostId"); + QSqlQuery &q = prepare(R"( + SELECT directory + FROM watched_directory + WHERE host_id = :hostId + AND ((:onlyEnabled1 = true AND enabled = true) + OR :onlyEnabled2 = false) + )"); q.bindValue(":hostId", hostId); + q.bindValue(":onlyEnabled1", onlyEnabled); + q.bindValue(":onlyEnabled2", onlyEnabled); if (!exec(q)) return QStringList(); @@ -2106,6 +2114,7 @@ void Database::subscribeToNotifications() d->db.driver()->subscribeToNotification("episode_delete"); d->db.driver()->subscribeToNotification("file_delete"); d->db.driver()->subscribeToNotification("file_location_delete"); + d->db.driver()->subscribeToNotification("watched_directory_changed"); } void Database::unsubscribeFromNotifications() @@ -2459,6 +2468,12 @@ void Database::handleNotification(const QString &name) if (locationId) emit fileLocationDelete(locationId, fid); } + else if (name == "watched_directory_changed") + { + int id = payload.toInt(); + if (id && id == LocalMyList::instance()->hostId()) + emit watchedDirectoriesChanged(); + } #endif } diff --git a/localmylist/database.h b/localmylist/database.h index 9ee38a9..5ee7dbd 100644 --- a/localmylist/database.h +++ b/localmylist/database.h @@ -132,7 +132,7 @@ public slots: QList getPendingMyListUpdateBatch(int limit = 10); bool clearPendingMyListUpdate(const LocalMyList::PendingMyListUpdate &request); - QStringList getWatchedDirectories(int hostId); + QStringList getWatchedDirectories(int hostId, bool onlyEnabled = true); QList getMappingsToHost(int hostId); @@ -208,6 +208,7 @@ signals: void newPendingMyListUpdate(); void renameDataChanged(); void configChanged(); + void watchedDirectoriesChanged(); void animeUpdate(int aid); void episodeUpdate(int eid, int aid); diff --git a/localmylist/directorywatcher.cpp b/localmylist/directorywatcher.cpp index ff07ac7..d7a03ca 100644 --- a/localmylist/directorywatcher.cpp +++ b/localmylist/directorywatcher.cpp @@ -96,6 +96,7 @@ void DirectoryWatcher::doDeInit() bool DirectoryWatcher::doStart() { + connect(db, SIGNAL(watchedDirectoriesChanged()), this, SLOT(setWatchedDirectories())); connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watchedDirectoryChanged(QString)), Qt::QueuedConnection); setWatchedDirectories(); @@ -105,6 +106,7 @@ bool DirectoryWatcher::doStart() void LocalMyList::DirectoryWatcher::doStop() { disconnect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(watchedDirectoryChanged(QString))); + disconnect(db, SIGNAL(watchedDirectoriesChanged()), this, SLOT(setWatchedDirectories())); } void DirectoryWatcher::doProcessRequests() diff --git a/localmylist/share/schema/schema.sql b/localmylist/share/schema/schema.sql index f44ce9f..d5a9134 100644 --- a/localmylist/share/schema/schema.sql +++ b/localmylist/share/schema/schema.sql @@ -229,9 +229,12 @@ CREATE TABLE host ( CREATE TABLE watched_directory ( + directory_id serial NOT NULL, host_id integer NOT NULL, directory text NOT NULL, - CONSTRAINT watched_directory_pk PRIMARY KEY (host_id, directory) + enabled boolean NOT NULL default true, + CONSTRAINT watched_directory_pk PRIMARY KEY (directory_id), + CONSTRAINT watched_directory_unique_directory UNIQUE (host_id, directory) ); CREATE TABLE path_map @@ -364,6 +367,10 @@ CREATE OR REPLACE RULE file_location_insert_notify_rule AS ON INSERT TO file_location DO SELECT pg_notify('file_location_insert', new.location_id::text); +CREATE OR REPLACE RULE watched_directory_insert_notify_rule AS + ON INSERT TO watched_directory DO SELECT + pg_notify('watched_directory_changed', new.host_id::text); + -- Update rules CREATE OR REPLACE RULE anime_update_notify_rule AS ON UPDATE TO anime DO SELECT pg_notify('rename_data_changed', ''), @@ -381,6 +388,15 @@ CREATE OR REPLACE RULE file_location_update_notify_rule AS ON UPDATE TO file_location DO SELECT pg_notify('rename_data_changed', ''), pg_notify('file_location_update', new.location_id::text || ',' || new.fid::text); +CREATE OR REPLACE RULE watched_directory_update_notify_rule AS + ON UPDATE TO watched_directory DO SELECT + CASE + WHEN old.host_id <> new.host_id THEN + pg_notify('watched_directory_changed', old.host_id::text) + ELSE NULL::void + END, + pg_notify('watched_directory_changed', new.host_id::text); + -- Delete rules CREATE OR REPLACE RULE anime_delete_notify_rule AS ON DELETE TO anime DO SELECT pg_notify('anime_delete', old.aid::text); @@ -394,6 +410,9 @@ CREATE OR REPLACE RULE file_delete_notify_rule AS CREATE OR REPLACE RULE file_location_delete_notify_rule AS ON DELETE TO file_location DO SELECT pg_notify('file_location_delete', old.location_id::text || ',' || old.fid::text); +CREATE OR REPLACE RULE watched_directory_delete_notify_rule AS + ON DELETE TO watched_directory DO SELECT + pg_notify('watched_directory_changed', old.host_id::text); -- Sequences CREATE SEQUENCE udp_client_session;