]> Some of my projects - localmylist.git/commitdiff
Add scriptable MyList Reports (currently just allows you to run an SQL query)
authorAPTX <marek321@gmail.com>
Tue, 28 Aug 2012 13:53:17 +0000 (15:53 +0200)
committerAPTX <marek321@gmail.com>
Tue, 28 Aug 2012 13:53:38 +0000 (15:53 +0200)
14 files changed:
localmylist/database.cpp
localmylist/database.h
localmylist/localmylist.pro
localmylist/reportengine.cpp [new file with mode: 0644]
localmylist/reportengine.h [new file with mode: 0644]
localmylist/scriptablesql.cpp [new file with mode: 0644]
localmylist/scriptablesql.h [new file with mode: 0644]
localmylist/share/schema/schema.sql
management-gui/mainwindow.cpp
management-gui/mainwindow.h
management-gui/mainwindow.ui
management-gui/management-gui.pro
management-gui/reporteditordialog.cpp [new file with mode: 0644]
management-gui/reporteditordialog.h [new file with mode: 0644]

index 34cb6ce0306e3b32613f3db204ebbb7c21c2d94e..e65259750b39d4f8e821efd281662214fc37b226 100644 (file)
@@ -118,6 +118,10 @@ OpenFileData::OpenFileData()
        epno = 0;
 }
 
+Report::Report()
+{
+       reportId = 0;
+}
 
 DatabaseConnectionSettings::DatabaseConnectionSettings()
 {
@@ -1188,6 +1192,7 @@ bool Database::clearPendingMyListUpdate(const PendingMyListUpdate &request)
 QStringList Database::getWatchedDirectories(int hostId)
 {
        QSqlQuery &q = prepare("SELECT directory FROM watched_directory WHERE host_id = :hostId");
+
        q.bindValue(":hostId", hostId);
 
        if (!exec(q))
@@ -1205,6 +1210,62 @@ QStringList Database::getWatchedDirectories(int hostId)
        return ret;
 }
 
+QList<Report> Database::getReports()
+{
+       QList<Report> reports;
+
+       QSqlQuery &q = prepare("SELECT report_id, name, script FROM report");
+
+       if (!exec(q))
+               return reports;
+
+       while (q.next())
+       {
+               Report report;
+               report.reportId = q.value(0).toInt();
+               report.name = q.value(1).toString();
+               report.script = q.value(2).toString();
+
+               reports << report;
+       }
+
+       return reports;
+}
+
+bool Database::addReport(const Report &report)
+{
+       QSqlQuery &q = prepare("INSERT INTO report VALUES (DEFAULT, :name, :script)");
+       q.bindValue(":name", report.name);
+       q.bindValue(":script", report.script);
+
+       return exec(q);
+}
+
+bool Database::setReport(const Report &report)
+{
+       QSqlQuery &q = prepare(
+       "UPDATE report "
+       "       SET name = :name, script = :script "
+       "       WHERE report_id = :reportId");
+
+       q.bindValue(":reportId", report.reportId);
+       q.bindValue(":name", report.name);
+       q.bindValue(":script", report.script);
+
+       return exec(q);
+}
+
+bool Database::removeReport(int reportId)
+{
+       QSqlQuery &q = prepare(
+       "DELETE FROM report "
+       "       WHERE report_id = :reportId");
+
+       q.bindValue(":reportId", reportId);
+
+       return exec(q);
+}
+
 bool Database::clearStartedPendingRequests()
 {
        return exec(
@@ -1361,7 +1422,10 @@ void Database::disconnect()
                qDebug() << "Not connected";
                return;
        }
+
+       d->preparedQueries.clear();
        d->db.close();
+
        emit disconnected();
 }
 
index 23ea7ca797c92153bf6fae3a287b45cbe4f6a364..21b563a633e139e575ad34d2a22aa94dbef953ac 100644 (file)
@@ -207,6 +207,15 @@ struct LOCALMYLISTSHARED_EXPORT OpenFileData
        OpenFileData();
 };
 
+struct LOCALMYLISTSHARED_EXPORT Report
+{
+       int reportId;
+       QString name;
+       QString script;
+
+       Report();
+};
+
 struct LOCALMYLISTSHARED_EXPORT DatabaseConnectionSettings
 {
        QString host;
@@ -285,6 +294,11 @@ public slots:
 
        QStringList getWatchedDirectories(int hostId);
 
+       QList<LocalMyList::Report> getReports();
+       bool addReport(const LocalMyList::Report &report);
+       bool setReport(const LocalMyList::Report &report);
+       bool removeReport(int reportId);
+
        bool clearStartedPendingRequests();
        bool clearStartedMyListUpdateRequests();
        bool clearFileRenames();
@@ -399,6 +413,10 @@ Q_DECLARE_METATYPE(LocalMyList::OpenFileData)
 Q_DECLARE_METATYPE(LocalMyList::OpenFileData*)
 Q_DECLARE_METATYPE(QList<LocalMyList::OpenFileData>)
 Q_DECLARE_METATYPE(QList<LocalMyList::OpenFileData*>)
+Q_DECLARE_METATYPE(LocalMyList::Report)
+Q_DECLARE_METATYPE(LocalMyList::Report*)
+Q_DECLARE_METATYPE(QList<LocalMyList::Report>)
+Q_DECLARE_METATYPE(QList<LocalMyList::Report*>)
 Q_DECLARE_METATYPE(LocalMyList::DatabaseConnectionSettings)
 Q_DECLARE_METATYPE(LocalMyList::DatabaseConnectionSettings*)
 Q_DECLARE_METATYPE(QList<LocalMyList::DatabaseConnectionSettings>)
index df032e4e4a0ae548375a9c6caf50479c5666c4e9..9dee8a88e7c5872df4e29407534192f232c5f5f9 100644 (file)
@@ -26,7 +26,9 @@ SOURCES += \
        unknownfilelookuptask.cpp \
        renameutils.cpp \
        directorywatcher.cpp \
-       addrelatedepisodestask.cpp
+       addrelatedepisodestask.cpp \
+       scriptablesql.cpp \
+       reportengine.cpp
 
 HEADERS += \
        localmylist_global.h \
@@ -46,7 +48,9 @@ HEADERS += \
        unknownfilelookuptask.h \
        renameutils.h \
        directorywatcher.h \
-       addrelatedepisodestask.h
+       addrelatedepisodestask.h \
+       scriptablesql.h \
+       reportengine.h
 
 CONV_HEADERS += \
        include/LocalMyList/AbstractTask \
diff --git a/localmylist/reportengine.cpp b/localmylist/reportengine.cpp
new file mode 100644 (file)
index 0000000..eecfeb2
--- /dev/null
@@ -0,0 +1,43 @@
+#include "reportengine.h"
+
+#include <QScriptEngine>
+#include <QSqlError>
+#include "database.h"
+#include "scriptablesql.h"
+
+#include <QDebug>
+
+namespace LocalMyList {
+
+ReportEngine::ReportEngine(QObject *parent) :
+       QObject(parent)
+{
+       m_engine = new QScriptEngine(this);
+       registerSqlTypes(m_engine);
+}
+
+QSqlQuery ReportEngine::query() const
+{
+       QSqlQuery q = m_engine->globalObject().property("query").toVariant().value<QSqlQuery>();
+       qDebug() << q.lastError();
+       return q;
+}
+
+QScriptEngine *ReportEngine::engine() const
+{
+       return m_engine;
+}
+
+void ReportEngine::run(const Report &report)
+{
+       run(report.script);
+}
+
+void ReportEngine::run(const QString &report)
+{
+       m_engine->evaluate(report);
+       if (m_engine->hasUncaughtException())
+               qDebug() << m_engine->uncaughtException().toString();
+}
+
+} // namespace LocalMyList
diff --git a/localmylist/reportengine.h b/localmylist/reportengine.h
new file mode 100644 (file)
index 0000000..79f55c3
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef REPORTENGINE_H
+#define REPORTENGINE_H
+
+#include "localmylist_global.h"
+#include <QObject>
+
+#include <QSqlQuery>
+
+class QScriptEngine;
+
+namespace LocalMyList {
+
+struct Report;
+
+class LOCALMYLISTSHARED_EXPORT ReportEngine : public QObject
+{
+       Q_OBJECT
+       Q_PROPERTY(QSqlQuery query READ query)
+       Q_PROPERTY(QScriptEngine *engine READ engine)
+
+public:
+       explicit ReportEngine(QObject *parent = 0);
+       
+       QSqlQuery query() const;
+       QScriptEngine *engine() const;
+signals:
+       
+public slots:
+       void run(const Report &report);
+       void run(const QString &report);
+
+private:
+       QScriptEngine *m_engine;
+};
+
+} // namespace LocalMyList
+
+#endif // REPORTENGINE_H
diff --git a/localmylist/scriptablesql.cpp b/localmylist/scriptablesql.cpp
new file mode 100644 (file)
index 0000000..373e5a5
--- /dev/null
@@ -0,0 +1,84 @@
+#include "scriptablesql.h"
+
+#include <QSqlRecord>
+
+#include "mylist.h"
+#include "database.h"
+#include <QDebug>
+
+namespace LocalMyList {
+
+void registerSqlTypes(QScriptEngine *engine)
+{
+       Scriptable::SqlQuery *SqlQueryPrototype = new Scriptable::SqlQuery();
+       engine->setDefaultPrototype(qMetaTypeId<QSqlQuery>(), engine->newQObject(SqlQueryPrototype));
+       engine->setDefaultPrototype(qMetaTypeId<QSqlQuery*>(), engine->newQObject(SqlQueryPrototype));
+       engine->globalObject().setProperty("SqlQuery", engine->newFunction(Scriptable::SqlQuery_ctor));
+}
+
+namespace Scriptable {
+
+SqlQuery::SqlQuery(QObject *parent) :
+       QObject(parent), QScriptable()
+{
+}
+
+bool SqlQuery::prepare(const QString &sql)
+{
+       auto o = thisObj();
+       if (!o) return false;
+       QString tmp = sql;
+       tmp.replace(QRegExp("[\\n\\r]+"), " ");
+       qDebug() << tmp;
+       *o = MyList::instance()->database()->prepareOneShot(tmp);
+       return true;
+}
+
+bool SqlQuery::bindValue(const QString &name, const QVariant &value)
+{
+       auto o = thisObj();
+       if (!o) return false;
+       o->bindValue(name, value);
+       return true;
+}
+
+bool SqlQuery::exec()
+{
+       auto o = thisObj();
+       if (!o) return false;
+       return MyList::instance()->database()->exec(*o);
+}
+
+bool SqlQuery::next()
+{
+       auto o = thisObj();
+       if (!o) return false;
+       return o->next();
+}
+
+QVariant SqlQuery::column(const QString &column)
+{
+       auto o = thisObj();
+       if (!o) return QVariant();
+       return o->record().value(column);
+}
+
+QVariant SqlQuery::columnNo(int column)
+{
+       auto o = thisObj();
+       if (!o) return QVariant();
+       return o->value(column);
+}
+
+QSqlQuery *SqlQuery::thisObj() const
+{
+       return qscriptvalue_cast<QSqlQuery *>(thisObject());
+}
+
+QScriptValue SqlQuery_ctor(QScriptContext *, QScriptEngine *engine)
+{
+       return engine->toScriptValue(QSqlQuery());
+}
+
+} // namespace Scriptable
+} // namespace LocalMyList
diff --git a/localmylist/scriptablesql.h b/localmylist/scriptablesql.h
new file mode 100644 (file)
index 0000000..1f6f2ea
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef SCRIPTABLESQL_H
+#define SCRIPTABLESQL_H
+
+#include "localmylist_global.h"
+
+#include <QObject>
+#include <QtScript/QScriptable>
+#include <QtScript/QScriptEngine>
+
+#include <QSqlQuery>
+
+namespace LocalMyList {
+
+void LOCALMYLISTSHARED_EXPORT registerSqlTypes(QScriptEngine *engine);
+
+namespace Scriptable {
+
+class LOCALMYLISTSHARED_EXPORT SqlQuery : public QObject, protected QScriptable
+{
+       Q_OBJECT
+public:
+       SqlQuery(QObject *parent = 0);
+
+public slots:
+       bool prepare(const QString &sql);
+       bool bindValue(const QString &name, const QVariant &value);
+
+       bool exec();
+
+       bool next();
+
+       QVariant column(const QString &column);
+       QVariant columnNo(int column);
+
+private:
+       QSqlQuery *thisObj() const;
+};
+
+QScriptValue SqlQuery_ctor(QScriptContext *, QScriptEngine *engine);
+
+} // namespace Scriptable
+} // namespace LocalMyList
+
+Q_DECLARE_METATYPE(QSqlQuery)
+Q_DECLARE_METATYPE(QSqlQuery*)
+
+#endif // SCRIPTABLESQL_H
index 0c064de3fe328d040bfbb8c06449ddde72613367..a4c2be8dedb50ba7ba93299b0d59accf735b3674 100644 (file)
@@ -204,6 +204,14 @@ CREATE TABLE watched_directory
        CONSTRAINT watched_directory_pk PRIMARY KEY (host_id, directory)
 );
 
+CREATE TABLE report
+(
+       report_id serial,
+       name character varying(500),
+       script text,
+       CONSTRAINT report_pk PRIMARY KEY (report_id)
+);
+
 CREATE TABLE log (
        log_id serial NOT NULL,
        type integer,
index 72dfb3009e2cbed76812e211f9387bc365652a5f..92e0e0bf694a73fb03dbd59b6049b66c2c0bdb15 100644 (file)
@@ -9,6 +9,8 @@
 #include <QSortFilterProxyModel>
 #include <QDragEnterEvent>
 #include <QDropEvent>
+#include <QSqlQueryModel>
+#include <QScriptEngineDebugger>
 
 #include "mylist.h"
 #include "database.h"
@@ -18,7 +20,9 @@
 #include "mylistfiltermodel.h"
 #include "unknownfilelookuptask.h"
 #include "addrelatedepisodestask.h"
+#include "reportengine.h"
 #include "renamesettingsdialog.h"
+#include "reporteditordialog.h"
 
 #include <QDebug>
 
@@ -63,6 +67,9 @@ MainWindow::MainWindow(QWidget *parent) :
 
        connect(ui->myListView, SIGNAL(renameTest(int)), this, SLOT(openRenameScriptEditor(int)));
 
+       reportResultModel = new QSqlQueryModel(this);
+       ui->reportResultView->setModel(reportResultModel);
+
        setAcceptDrops(true);
 }
 
@@ -397,6 +404,18 @@ void MainWindow::on_filterType_currentIndexChanged(int)
        on_filterInput_textChanged(ui->filterInput->text());
 }
 
+void MainWindow::on_reloadReports_clicked()
+{
+       ui->reports->clear();
+
+       QList<Report> reports = MyList::instance()->database()->getReports();
+
+       foreach (const Report &report, reports)
+       {
+               ui->reports->addItem(report.name, QVariant::fromValue(report));
+       }
+}
+
 void MainWindow::dragEnterEvent(QDragEnterEvent *event)
 {
        if (event->mimeData()->hasFormat("text/uri-list"))
@@ -417,3 +436,66 @@ void MainWindow::dropEvent(QDropEvent *event)
        }
        event->acceptProposedAction();
 }
+
+
+
+void MainWindow::on_reports_currentIndexChanged(int)
+{
+       on_runReport_clicked();
+}
+
+void MainWindow::on_runReport_clicked()
+{
+       Report report = ui->reports->itemData(ui->reports->currentIndex()).value<Report>();
+       ReportEngine e;
+
+       e.run(report);
+
+       reportResultModel->setQuery(e.query());
+       ui->reportResultView->resizeColumnsToContents();
+}
+
+void MainWindow::on_editReport_clicked()
+{
+       if (!ui->reports->count())
+               return;
+
+       int idx = ui->reports->currentIndex();
+
+       ReportEditorDialog d;
+       d.setReport(ui->reports->itemData(idx).value<Report>());
+
+       if (!d.exec())
+               return;
+
+       MyList::instance()->database()->setReport(d.report());
+
+       ui->reports->setItemData(idx, QVariant::fromValue(d.report()));
+       on_runReport_clicked();
+}
+
+void MainWindow::on_addReport_clicked()
+{
+       ReportEditorDialog d;
+
+       if (!d.exec())
+               return;
+
+       MyList::instance()->database()->addReport(d.report());
+
+       ui->reports->addItem(d.report().name, QVariant::fromValue(d.report()));
+
+       ui->reports->setCurrentIndex(ui->reports->count() - 1);
+}
+
+
+void MainWindow::on_tabWidget_currentChanged(QWidget *arg1)
+{
+       if (arg1 != ui->reportsTab)
+               return;
+
+       if (ui->reports->count())
+               return;
+
+       on_reloadReports_clicked();
+}
index 42c94b02c8b9629d98cfd02eb23836b33357440c..c402ec3f7f620171fe9a5399112d79a5fe5cda7f 100644 (file)
@@ -10,8 +10,11 @@ class MainWindow;
 
 namespace LocalMyList {
        class MyListModel;
+       class ReportEngine;
 }
+
 class QLabel;
+class QSqlQueryModel;
 
 class RenameSettingsDialog;
 class MyListFilterModel;
@@ -74,6 +77,14 @@ private slots:
        void on_filterInput_textChanged(const QString &filter);
        void on_filterType_currentIndexChanged(int);
 
+       // Reports
+       void on_reloadReports_clicked();
+       void on_reports_currentIndexChanged(int index);
+       void on_runReport_clicked();
+       void on_editReport_clicked();
+       void on_addReport_clicked();
+       void on_tabWidget_currentChanged(QWidget *arg1);
+
 protected:
        void dragEnterEvent(QDragEnterEvent *event);
        void dropEvent(QDropEvent *event);
@@ -87,6 +98,8 @@ private:
 
        LocalMyList::MyListModel *myListModel;
        MyListFilterModel *myListFilterModel;
+
+       QSqlQueryModel *reportResultModel;
 };
 
 #endif // MAINWINDOW_H
index 53547d6322374039290aab9d802098de4caab9b9..be80f43a635e653d352c02d8d05ca7835ff8b43e 100644 (file)
    <string>LocalMyList Management</string>
   </property>
   <widget class="QWidget" name="centralWidget">
-   <layout class="QVBoxLayout" name="verticalLayout">
-    <item>
-     <layout class="QHBoxLayout" name="horizontalLayout_2">
-      <item>
-       <widget class="QLineEdit" name="filterInput"/>
-      </item>
-      <item>
-       <widget class="QComboBox" name="filterType"/>
-      </item>
-     </layout>
-    </item>
-    <item>
-     <widget class="MyListView" name="myListView"/>
-    </item>
+   <layout class="QVBoxLayout" name="verticalLayout_2">
+    <property name="spacing">
+     <number>0</number>
+    </property>
+    <property name="margin">
+     <number>0</number>
+    </property>
     <item>
-     <layout class="QHBoxLayout" name="horizontalLayout">
-      <item>
-       <spacer name="horizontalSpacer">
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
+     <widget class="QTabWidget" name="tabWidget">
+      <property name="currentIndex">
+       <number>0</number>
+      </property>
+      <property name="documentMode">
+       <bool>true</bool>
+      </property>
+      <widget class="QWidget" name="myListTab">
+       <attribute name="title">
+        <string>MyList</string>
+       </attribute>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>9</number>
         </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>40</width>
-          <height>20</height>
-         </size>
+        <property name="rightMargin">
+         <number>0</number>
         </property>
-       </spacer>
-      </item>
-      <item>
-       <widget class="QPushButton" name="refreshButton">
-        <property name="text">
-         <string>Refresh</string>
+        <property name="bottomMargin">
+         <number>0</number>
         </property>
-       </widget>
-      </item>
-     </layout>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
+          <item>
+           <widget class="QLineEdit" name="filterInput"/>
+          </item>
+          <item>
+           <widget class="QComboBox" name="filterType"/>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="MyListView" name="myListView"/>
+        </item>
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout">
+          <item>
+           <spacer name="horizontalSpacer">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QPushButton" name="refreshButton">
+            <property name="text">
+             <string>Refresh</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+       </layout>
+      </widget>
+      <widget class="QWidget" name="reportsTab">
+       <attribute name="title">
+        <string>Reports</string>
+       </attribute>
+       <layout class="QVBoxLayout" name="verticalLayout_3" stretch="0,1">
+        <item>
+         <layout class="QHBoxLayout" name="horizontalLayout_3">
+          <item>
+           <widget class="QLabel" name="label">
+            <property name="text">
+             <string>Report:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QComboBox" name="reports">
+            <property name="minimumSize">
+             <size>
+              <width>300</width>
+              <height>0</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="editReport">
+            <property name="text">
+             <string>Edit...</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="addReport">
+            <property name="text">
+             <string>Add</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="deleteReport">
+            <property name="text">
+             <string>Delete</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <spacer name="horizontalSpacer_2">
+            <property name="orientation">
+             <enum>Qt::Horizontal</enum>
+            </property>
+            <property name="sizeHint" stdset="0">
+             <size>
+              <width>40</width>
+              <height>20</height>
+             </size>
+            </property>
+           </spacer>
+          </item>
+          <item>
+           <widget class="QPushButton" name="runReport">
+            <property name="text">
+             <string>Run</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPushButton" name="reloadReports">
+            <property name="text">
+             <string>Reload</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QSplitter" name="splitter">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <widget class="QTableView" name="reportResultView"/>
+          <widget class="QPlainTextEdit" name="plainTextEdit"/>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </widget>
     </item>
    </layout>
   </widget>
    <header>mylistview.h</header>
   </customwidget>
  </customwidgets>
- <tabstops>
-  <tabstop>filterInput</tabstop>
-  <tabstop>filterType</tabstop>
-  <tabstop>myListView</tabstop>
-  <tabstop>refreshButton</tabstop>
- </tabstops>
  <resources/>
  <connections/>
 </ui>
index a2384761d90e5499e2853c595227e42c1faa2d4d..ebc27ba769843eb5f0f5a985f05f4d52d58fb97a 100644 (file)
@@ -1,4 +1,4 @@
-QT += core gui
+QT += core gui scripttools
 
 include(../config.pri)
 
@@ -12,13 +12,15 @@ SOURCES += main.cpp\
        databaseconnectiondialog.cpp \
        mylistview.cpp \
        renamesettingsdialog.cpp \
-       mylistfiltermodel.cpp
+       mylistfiltermodel.cpp \
+       reporteditordialog.cpp
 
 HEADERS += mainwindow.h \
        databaseconnectiondialog.h \
        mylistview.h \
        renamesettingsdialog.h \
-       mylistfiltermodel.h
+       mylistfiltermodel.h \
+       reporteditordialog.h
 
 FORMS += mainwindow.ui \
        databaseconnectiondialog.ui \
diff --git a/management-gui/reporteditordialog.cpp b/management-gui/reporteditordialog.cpp
new file mode 100644 (file)
index 0000000..53aea37
--- /dev/null
@@ -0,0 +1,66 @@
+#include "reporteditordialog.h"
+
+#include <QLabel>
+#include <QLineEdit>
+#include <QPlainTextEdit>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QDialogButtonBox>
+
+ReportEditorDialog::ReportEditorDialog(QWidget *parent) :
+       QDialog(parent)
+{
+       resize(800, 600);
+       QLabel *nameLabel = new QLabel("Report Name:", this);
+       name = new QLineEdit(this);
+       QHBoxLayout *hLayout = new QHBoxLayout;
+
+       hLayout->addWidget(nameLabel);
+       hLayout->addWidget(name);
+
+       script = new QPlainTextEdit(this);
+
+       buttons = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel | QDialogButtonBox::Reset, Qt::Horizontal, this);
+
+       QVBoxLayout *vLayout = new QVBoxLayout;
+
+       vLayout->addLayout(hLayout);
+       vLayout->addWidget(script);
+       vLayout->addWidget(buttons);
+
+       setLayout(vLayout);
+
+       connect(buttons, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonClicked(QAbstractButton*)));
+}
+
+LocalMyList::Report ReportEditorDialog::report() const
+{
+       m_report.name = name->text();
+       m_report.script = script->toPlainText();
+       return m_report;
+}
+
+void ReportEditorDialog::setReport(const LocalMyList::Report &report)
+{
+       m_report = report;
+       name->setText(m_report.name);
+       script->setPlainText(m_report.script);
+}
+
+void ReportEditorDialog::buttonClicked(QAbstractButton *button)
+{
+       switch (buttons->standardButton(button))
+       {
+               case QDialogButtonBox::Save:
+                       accept();
+               break;
+               case QDialogButtonBox::Cancel:
+                       reject();
+               break;
+               case QDialogButtonBox::Reset:
+                       name->setText(m_report.name);
+                       script->setPlainText(m_report.script);
+               break;
+               default: ;
+       }
+}
diff --git a/management-gui/reporteditordialog.h b/management-gui/reporteditordialog.h
new file mode 100644 (file)
index 0000000..e5db463
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef REPORTEDITORDIALOG_H
+#define REPORTEDITORDIALOG_H
+
+#include <QDialog>
+
+#include "database.h"
+
+class QAbstractButton;
+class QLineEdit;
+class QDialogButtonBox;
+class QPlainTextEdit;
+
+class ReportEditorDialog : public QDialog
+{
+       Q_OBJECT
+public:
+       explicit ReportEditorDialog(QWidget *parent = 0);
+       
+       LocalMyList::Report report() const;
+       void setReport(const LocalMyList::Report &report);
+
+signals:
+       
+private slots:
+       void buttonClicked(QAbstractButton *button);
+
+private:
+       mutable LocalMyList::Report m_report;
+
+       QLineEdit *name;
+       QDialogButtonBox *buttons;
+       QPlainTextEdit *script;
+};
+
+#endif // REPORTEDITORDIALOG_H