]> Some of my projects - localmylist.git/commitdiff
Add Watched Directories Tab.
authorAPTX <marek321@gmail.com>
Mon, 9 Nov 2015 14:11:12 +0000 (15:11 +0100)
committerAPTX <marek321@gmail.com>
Mon, 9 Nov 2015 14:14:33 +0000 (15:14 +0100)
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.

localmylist-management/localmylist-management.pro
localmylist-management/registertabs.cpp
localmylist-management/tabs/watcheddirectoriestab.cpp [new file with mode: 0644]
localmylist-management/tabs/watcheddirectoriestab.h [new file with mode: 0644]
localmylist-management/tabs/watcheddirectoriestab.ui [new file with mode: 0644]
localmylist/database.cpp
localmylist/database.h
localmylist/directorywatcher.cpp
localmylist/share/schema/schema.sql

index 112f119e50420c1be0888c4add9ff0f9c97bae9e..d620ff446187a7084993acb32e3faf655220f250 100644 (file)
@@ -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
 
index 2e85cd943d41a16193d1a0e605961ced41481130..2115be5e357fddc85503ca52b478e80bce41d983 100644 (file)
@@ -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<DatabaseLogTab>();
        TabWidget::registerTab<ClientLogTab>();
        TabWidget::registerTab<PathMappingTab>();
+       TabWidget::registerTab<WatchedDirectoriesTab>();
        TabWidget::registerTab<HostTab>();
        TabWidget::registerTab<MyListTab>();
 }
diff --git a/localmylist-management/tabs/watcheddirectoriestab.cpp b/localmylist-management/tabs/watcheddirectoriestab.cpp
new file mode 100644 (file)
index 0000000..72c2721
--- /dev/null
@@ -0,0 +1,100 @@
+#include "watcheddirectoriestab.h"
+#include "ui_watcheddirectoriestab.h"
+
+#include <QSqlRelationalDelegate>
+#include <QSqlError>
+#include <QMessageBox>
+#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 (file)
index 0000000..441e3c8
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef WATCHEDDIRECTORIESTAB_H
+#define WATCHEDDIRECTORIESTAB_H
+
+#include "abstracttab.h"
+#include <QSqlRelationalTableModel>
+
+namespace Ui {
+class WatchedDirectoriesTab;
+}
+
+class WatchedDirectoriesTab : public AbstractTabBase<WatchedDirectoriesTab>
+{
+       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 (file)
index 0000000..40dbc93
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WatchedDirectoriesTab</class>
+ <widget class="QWidget" name="WatchedDirectoriesTab">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
+    <number>0</number>
+   </property>
+   <item>
+    <widget class="QTableView" name="watchedDirectoriesView"/>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
index 51893459805cd9bf2cc268b2afbad2518d1426db..a8ab87af9d4ca5f0cf8a78bb3f92ef9415bcdee4 100644 (file)
@@ -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
 }
 
index 9ee38a9ecb86f884e5f5cd719f7c1cae61fc5996..5ee7dbd1c027915d5b7a7c3affb2e2248952f134 100644 (file)
@@ -132,7 +132,7 @@ public slots:
        QList<PendingMyListUpdate> getPendingMyListUpdateBatch(int limit = 10);
        bool clearPendingMyListUpdate(const LocalMyList::PendingMyListUpdate &request);
 
-       QStringList getWatchedDirectories(int hostId);
+       QStringList getWatchedDirectories(int hostId, bool onlyEnabled = true);
 
        QList<LocalMyList::PathMapping> 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);
index ff07ac79e3b906ad175deaedbae7425264d4615b..d7a03ca022c0d5c8de0230982c7192e2e263d07b 100644 (file)
@@ -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()
index f44ce9fb96729d7812a17bae8551d29bcd390ecc..d5a91349970642b164ecdbc7ef439385581d56fa 100644 (file)
@@ -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;