--- /dev/null
+#include "abstracttab.h"
+
+AbstractTab::AbstractTab(QWidget *parent) :
+ QWidget(parent)
+{
+}
+
+AbstractTab::~AbstractTab()
+{
+}
+
+QString AbstractTab::name() const
+{
+ return m_name;
+}
+
+MainWindow *AbstractTab::mainWindow() const
+{
+ return m_mainWindow;
+}
+
+void AbstractTab::init()
+{
+}
+
+void AbstractTab::deinit()
+{
+}
+
+void AbstractTab::activate()
+{
+}
+
+void AbstractTab::deactivate()
+{
+}
+
+void AbstractTab::loadSettings(QSettings *settings)
+{
+ Q_UNUSED(settings);
+}
+
+void AbstractTab::saveSettings(QSettings *settings)
+{
+ Q_UNUSED(settings);
+}
+
+void AbstractTab::setName(QString name)
+{
+ if (m_name != name)
+ {
+ m_name = name;
+ emit nameChanged(name);
+ }
+}
+
+void AbstractTab::setMainWindow(MainWindow *mainWindow)
+{
+ m_mainWindow = mainWindow;
+}
--- /dev/null
+#ifndef ABSTRACTTAB_H
+#define ABSTRACTTAB_H
+
+#include <QWidget>
+
+class QSettings;
+class MainWindow;
+
+class AbstractTab : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+
+public:
+ explicit AbstractTab(QWidget *parent = 0);
+ virtual ~AbstractTab();
+
+ QString name() const;
+ MainWindow *mainWindow() const;
+
+ virtual void init();
+ virtual void deinit();
+
+ virtual void activate();
+ virtual void deactivate();
+
+ virtual void loadSettings(QSettings *settings);
+ virtual void saveSettings(QSettings *settings);
+
+signals:
+ void nameChanged(QString name);
+
+public slots:
+ void setName(QString name);
+ void setMainWindow(MainWindow *mainWindow);
+
+protected:
+ QString m_name;
+ MainWindow *m_mainWindow;
+};
+
+#endif // ABSTRACTTAB_H
mylistfiltermodel.cpp \
reporteditordialog.cpp \
versiondialog.cpp \
- mylistitemdelegate.cpp
+ mylistitemdelegate.cpp \
+ tabwidget.cpp \
+ abstracttab.cpp \
+ tabs/mylisttab.cpp \
+ tabs/reportstab.cpp
HEADERS += mainwindow.h \
databaseconnectiondialog.h \
mylistfiltermodel.h \
reporteditordialog.h \
versiondialog.h \
- mylistitemdelegate.h
+ mylistitemdelegate.h \
+ tabwidget.h \
+ abstracttab.h \
+ tabs/mylisttab.h \
+ tabs/reportstab.h
FORMS += mainwindow.ui \
- databaseconnectiondialog.ui
+ databaseconnectiondialog.ui \
+ tabs/mylisttab.ui \
+ tabs/reportstab.ui
include(../localmylist.pri)
include(qtsingleapplication/qtsingleapplication.pri)
#include "reporteditordialog.h"
#include "versiondialog.h"
+#include "tabs/mylisttab.h"
+#include "tabs/reportstab.h"
+
#include <QDebug>
using namespace LocalMyList;
connect(MyList::instance()->database(), SIGNAL(newPendingRequest()), this, SLOT(handleNotification()));
connect(MyList::instance(), SIGNAL(allTasksFinished()), this, SLOT(allTasksFinished()));
- myListModel = new MyListModel(this);
- myListFilterModel = new MyListFilterModel(this);
- myListFilterModel->setSourceModel(myListModel);
- ui->myListView->setModel(myListFilterModel);
- ui->myListView->setItemDelegate(new MyListItemDelegate(ui->myListView));
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- ui->myListView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
-#else
- ui->myListView->header()->setResizeMode(0, QHeaderView::Stretch);
-#endif
- ui->myListView->header()->setStretchLastSection(false);
- ui->myListView->header()->resizeSection(4, 200);
-
- ui->filterType->addItems(QStringList()
- << tr("Fixed String")
- << tr("Wildcard")
- << tr("Regexp"));
-
- connect(ui->myListView, SIGNAL(renameTest(int)), this, SLOT(openRenameScriptEditor(int)));
+ m_myListModel = new MyListModel(this);
loadSettings();
MyList::instance()->database()->connect();
- reportResultModel = new QSqlQueryModel(this);
- ui->reportResultView->setModel(reportResultModel);
-
- myListFilterModel->configChanged();
-
setAcceptDrops(true);
if (autostartDirectoryWatcher)
ui->actionRenameFiles->setDisabled(true);
}
- ui->filterInput->setFocus();
+
+ AbstractTab *tab;
+ tab = new MyListTab();
+ tab->setMainWindow(this);
+ ui->tabWidget->addTab(tab);
+ tab = new ReportsTab();
+ tab->setMainWindow(this);
+ ui->tabWidget->addTab(tab);
+
}
MainWindow::~MainWindow()
delete ui;
}
+MyListModel *MainWindow::myListModel() const
+{
+ return m_myListModel;
+}
+
void MainWindow::dbConnected()
{
databaseConnectionStatusIndicator->setText("Connected");
MyList::instance()->executeTask(new AddRelatedEpisodesTask());
}
-void MainWindow::on_refreshButton_clicked()
-{
- myListModel->reload();
-}
-
-void MainWindow::on_myListView_openFileRequested(const QModelIndex &index)
-{
- MyListNode *node = myListFilterModel->node(index);
-
- if (!node->id())
- return;
-
- OpenFileData data;
-
- if (node->type() == MyListNode::AnimeNode)
- {
- data = MyList::instance()->database()->firstUnwatchedByAid(node->id());
- }
- else if (node->type() == MyListNode::EpisodeNode)
- {
- data = MyList::instance()->database()->openFileByEid(node->id());
- }
- else if (node->type() == MyListNode::FileNode)
- {
- data = MyList::instance()->database()->openFile(node->id());
- }
- else
- {
- return;
- }
-
- if (!data.fid)
- {
- ui->statusBar->showMessage(tr("No file found."));
- return;
- }
-
- QDesktopServices::openUrl(QUrl("file:///" + data.path, QUrl::TolerantMode));
- ui->statusBar->showMessage(tr("Openieng file: %1").arg(data.path));
-
-}
-
-void MainWindow::on_myListView_renameFilesRequested(const QModelIndex &index)
-{
- MyListNode *node = myListFilterModel->node(index);
-
- if (!node->id())
- return;
-
- QString path;
- QSqlQuery q(MyList::instance()->database()->connection());
-
- QChar typeLetter;
- if (node->type() == MyListNode::AnimeNode)
- {
- q.prepare(
- "UPDATE file_location fl SET renamed = NULL, failed_rename = false "
- " FROM file f "
- " WHERE f.fid = fl.fid AND f.aid = :aid");
- q.bindValue(":aid", node->id());
-
- typeLetter = 'a';
- }
- else if (node->type() == MyListNode::EpisodeNode)
- {
- q.prepare(
- "UPDATE file_location fl SET renamed = NULL, failed_rename = false "
- " FROM file f "
- " WHERE f.fid = fl.fid AND f.eid = :eid");
- q.bindValue(":eid", node->id());
-
- typeLetter = 'e';
- }
- else if (node->type() == MyListNode::FileNode)
- {
- q.prepare(
- "UPDATE file_location fl SET renamed = NULL, failed_rename = false "
- " WHERE fl.fid = :fid");
- q.bindValue(":fid", node->id());
-
- typeLetter = 'f';
- }
- else
- {
- return;
- }
-
- if (!q.exec())
- {
- qDebug() << q.lastError();
- return;
- }
-
- ui->statusBar->showMessage(tr("Files for %1%2 scheduled for rename").arg(typeLetter).arg(node->id()));
-}
-
-void MainWindow::on_myListView_dataRequested(const QModelIndex &index)
-{
- MyListNode *node = myListFilterModel->node(index);
-
- if (!node->id())
- return;
-
- PendingRequest r;
-
- switch (node->type())
- {
- case MyListNode::AnimeNode:
- r.aid = node->id();
- break;
- case MyListNode::EpisodeNode:
- r.eid = node->id();
- break;
- case MyListNode::FileNode:
- r.fid = node->id();
- break;
- default:
- return;
- break;
- }
-
- MyList::instance()->database()->addRequest(r);
-}
-
-void MainWindow::on_myListView_removeFileLocationRequested(int id)
-{
- myListModel->removeFileLocation(id);
-}
-
-void MainWindow::on_filterInput_textChanged(const QString &filter)
-{
- switch (ui->filterType->currentIndex())
- {
- case 1:
- myListFilterModel->setFilterWildcard(filter);
- break;
- case 2:
- myListFilterModel->setFilterRegExp(filter);
- break;
- case 0:
- default:
- myListFilterModel->setFilterFixedString(filter);
- break;
- }
-}
-
-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"))
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(int idx)
-{
- QWidget *tab = ui->tabWidget->widget(idx);
- if (tab != ui->reportsTab)
- return;
-
- if (ui->reports->count())
- return;
-
- on_reloadReports_clicked();
-}
-
void MainWindow::loadSettings()
{
MyList::instance()->loadLocalSettings();
QSettings &s = *MyList::instance()->defaultLocalQSettings();
s.beginGroup("management-gui");
- ui->filterType->setCurrentIndex(s.value("filterType", 0).toInt());
autostartDirectoryWatcher = s.value("autostartDirectoryWatcher", false).toBool();
autostartRenameHandler = s.value("autostartRenameHandler", false).toBool();
autostartUdpClient = s.value("autostartUdpClient", false).toBool();
QSettings &s = *MyList::instance()->defaultLocalQSettings();
s.beginGroup("management-gui");
- s.setValue("filterType", ui->filterType->currentIndex());
s.setValue("autostartDirectoryWatcher", autostartDirectoryWatcher);
s.setValue("autostartRenameHandler", autostartRenameHandler);
s.setValue("autostartUdpClient", autostartUdpClient);
VersionDialog d;
d.exec();
}
+
+void MainWindow::showMessage(const QString &message)
+{
+ ui->statusBar->showMessage(message);
+}
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
+ LocalMyList::MyListModel *myListModel() const;
+
+ void showMessage(const QString &message);
+
private slots:
void dbConnected();
void dbDisconnected();
void on_actionAddRelatedEpisodeInfo_triggered();
- void on_refreshButton_clicked();
- void on_myListView_openFileRequested(const QModelIndex &index);
- void on_myListView_renameFilesRequested(const QModelIndex &index);
- void on_myListView_dataRequested(const QModelIndex &index);
- void on_myListView_removeFileLocationRequested(int id);
-
- 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(int idx);
-
void on_actionAboutLocalMyList_triggered();
protected:
QLabel *databaseConnectionStatusIndicator;
QLabel *taskCountLabel;
- LocalMyList::MyListModel *myListModel;
- MyListFilterModel *myListFilterModel;
-
- QSqlQueryModel *reportResultModel;
+ LocalMyList::MyListModel *m_myListModel;
bool autostartDirectoryWatcher;
bool autostartRenameHandler;
<number>0</number>
</property>
<item>
- <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="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <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>
+ <widget class="TabWidget" name="tabWidget" native="true"/>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
- <class>MyListView</class>
- <extends>QTreeView</extends>
- <header>mylistview.h</header>
+ <class>TabWidget</class>
+ <extends>QWidget</extends>
+ <header>tabwidget.h</header>
+ <container>1</container>
</customwidget>
</customwidgets>
<resources/>
--- /dev/null
+#include "mylisttab.h"
+#include "ui_mylisttab.h"
+
+#include <QDesktopServices>
+#include <QUrl>
+#include <QSqlError>
+
+#include "mainwindow.h"
+#include "database.h"
+#include "mylist.h"
+#include "mylistmodel.h"
+#include "mylistnode.h"
+#include "mylistfiltermodel.h"
+#include "mylistitemdelegate.h"
+
+#include <QDebug>
+
+using namespace LocalMyList;
+
+MyListTab::MyListTab(QWidget *parent) :
+ AbstractTab(parent),
+ ui(new Ui::MyListTab)
+{
+ ui->setupUi(this);
+ m_name = tr("MyList");
+}
+
+MyListTab::~MyListTab()
+{
+ delete ui;
+}
+
+
+void MyListTab::init()
+{
+ myListFilterModel = new MyListFilterModel(this);
+ myListFilterModel->setSourceModel(myListModel());
+ ui->myListView->setModel(myListFilterModel);
+ ui->myListView->setItemDelegate(new MyListItemDelegate(ui->myListView));
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ ui->myListView->header()->setSectionResizeMode(0, QHeaderView::Stretch);
+#else
+ ui->myListView->header()->setResizeMode(0, QHeaderView::Stretch);
+#endif
+ ui->myListView->header()->setStretchLastSection(false);
+ ui->myListView->header()->resizeSection(4, 200);
+
+ ui->filterType->addItems(QStringList()
+ << tr("Fixed String")
+ << tr("Wildcard")
+ << tr("Regexp"));
+
+ connect(ui->myListView, SIGNAL(renameTest(int)), mainWindow(), SLOT(openRenameScriptEditor(int)));
+
+ myListFilterModel->configChanged();
+
+
+ ui->filterInput->setFocus();
+}
+
+void MyListTab::loadSettings(QSettings *settings)
+{
+ ui->filterType->setCurrentIndex(settings->value("filterType", 0).toInt());
+}
+
+void MyListTab::saveSettings(QSettings *settings)
+{
+ settings->setValue("filterType", ui->filterType->currentIndex());
+}
+
+void MyListTab::on_refreshButton_clicked()
+{
+ myListModel()->reload();
+}
+
+void MyListTab::on_myListView_openFileRequested(const QModelIndex &index)
+{
+ MyListNode *node = myListFilterModel->node(index);
+
+ if (!node->id())
+ return;
+
+ OpenFileData data;
+
+ if (node->type() == MyListNode::AnimeNode)
+ {
+ data = MyList::instance()->database()->firstUnwatchedByAid(node->id());
+ }
+ else if (node->type() == MyListNode::EpisodeNode)
+ {
+ data = MyList::instance()->database()->openFileByEid(node->id());
+ }
+ else if (node->type() == MyListNode::FileNode)
+ {
+ data = MyList::instance()->database()->openFile(node->id());
+ }
+ else
+ {
+ return;
+ }
+
+ if (!data.fid)
+ {
+ mainWindow()->showMessage(tr("No file found."));
+ return;
+ }
+
+ QDesktopServices::openUrl(QUrl("file:///" + data.path, QUrl::TolerantMode));
+ mainWindow()->showMessage(tr("Openieng file: %1").arg(data.path));
+
+}
+
+void MyListTab::on_myListView_renameFilesRequested(const QModelIndex &index)
+{
+ MyListNode *node = myListFilterModel->node(index);
+
+ if (!node->id())
+ return;
+
+ QString path;
+ QSqlQuery q(MyList::instance()->database()->connection());
+
+ QChar typeLetter;
+ if (node->type() == MyListNode::AnimeNode)
+ {
+ q.prepare(
+ "UPDATE file_location fl SET renamed = NULL, failed_rename = false "
+ " FROM file f "
+ " WHERE f.fid = fl.fid AND f.aid = :aid");
+ q.bindValue(":aid", node->id());
+
+ typeLetter = 'a';
+ }
+ else if (node->type() == MyListNode::EpisodeNode)
+ {
+ q.prepare(
+ "UPDATE file_location fl SET renamed = NULL, failed_rename = false "
+ " FROM file f "
+ " WHERE f.fid = fl.fid AND f.eid = :eid");
+ q.bindValue(":eid", node->id());
+
+ typeLetter = 'e';
+ }
+ else if (node->type() == MyListNode::FileNode)
+ {
+ q.prepare(
+ "UPDATE file_location fl SET renamed = NULL, failed_rename = false "
+ " WHERE fl.fid = :fid");
+ q.bindValue(":fid", node->id());
+
+ typeLetter = 'f';
+ }
+ else
+ {
+ return;
+ }
+
+ if (!q.exec())
+ {
+ qDebug() << q.lastError();
+ return;
+ }
+
+ mainWindow()->showMessage(tr("Files for %1%2 scheduled for rename").arg(typeLetter).arg(node->id()));
+}
+
+void MyListTab::on_myListView_dataRequested(const QModelIndex &index)
+{
+ MyListNode *node = myListFilterModel->node(index);
+
+ if (!node->id())
+ return;
+
+ PendingRequest r;
+
+ switch (node->type())
+ {
+ case MyListNode::AnimeNode:
+ r.aid = node->id();
+ break;
+ case MyListNode::EpisodeNode:
+ r.eid = node->id();
+ break;
+ case MyListNode::FileNode:
+ r.fid = node->id();
+ break;
+ default:
+ return;
+ break;
+ }
+
+ MyList::instance()->database()->addRequest(r);
+}
+
+void MyListTab::on_myListView_removeFileLocationRequested(int id)
+{
+ myListModel()->removeFileLocation(id);
+}
+
+void MyListTab::on_filterInput_textChanged(const QString &filter)
+{
+ switch (ui->filterType->currentIndex())
+ {
+ case 1:
+ myListFilterModel->setFilterWildcard(filter);
+ break;
+ case 2:
+ myListFilterModel->setFilterRegExp(filter);
+ break;
+ case 0:
+ default:
+ myListFilterModel->setFilterFixedString(filter);
+ break;
+ }
+}
+
+void MyListTab::on_filterType_currentIndexChanged(int)
+{
+ on_filterInput_textChanged(ui->filterInput->text());
+}
+
+MyListModel *MyListTab::myListModel() const
+{
+ return m_mainWindow->myListModel();
+}
--- /dev/null
+#ifndef MYLISTTAB_H
+#define MYLISTTAB_H
+
+#include "abstracttab.h"
+
+
+class MyListFilterModel;
+
+namespace LocalMyList {
+ class MyListModel;
+}
+
+namespace Ui {
+class MyListTab;
+}
+
+class MyListTab : public AbstractTab
+{
+ Q_OBJECT
+
+public:
+ explicit MyListTab(QWidget *parent = 0);
+ ~MyListTab();
+
+ void init();
+
+ void loadSettings(QSettings *settings);
+ void saveSettings(QSettings *settings);
+
+private slots:
+ void on_refreshButton_clicked();
+ void on_myListView_openFileRequested(const QModelIndex &index);
+ void on_myListView_renameFilesRequested(const QModelIndex &index);
+ void on_myListView_dataRequested(const QModelIndex &index);
+ void on_myListView_removeFileLocationRequested(int id);
+
+ void on_filterInput_textChanged(const QString &filter);
+ void on_filterType_currentIndexChanged(int);
+
+private:
+ LocalMyList::MyListModel *myListModel() const;
+
+ MyListFilterModel *myListFilterModel;
+
+ Ui::MyListTab *ui;
+};
+
+#endif // MYLISTTAB_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MyListTab</class>
+ <widget class="QWidget" name="MyListTab">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>610</width>
+ <height>493</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>
+ <layout class="QHBoxLayout" name="filterLayout">
+ <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="refreshButtonLayout">
+ <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>
+ <customwidgets>
+ <customwidget>
+ <class>MyListView</class>
+ <extends>QTreeView</extends>
+ <header>mylistview.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+#include "reportstab.h"
+#include "ui_reportstab.h"
+
+#include <QSqlQueryModel>
+
+#include "mylist.h"
+#include "database.h"
+#include "reportengine.h"
+#include "reporteditordialog.h"
+
+using namespace LocalMyList;
+
+ReportsTab::ReportsTab(QWidget *parent) :
+ AbstractTab(parent),
+ ui(new Ui::ReportsTab)
+{
+ ui->setupUi(this);
+ m_name = tr("Reports");
+}
+
+ReportsTab::~ReportsTab()
+{
+ delete ui;
+}
+
+void ReportsTab::init()
+{
+ reportResultModel = new QSqlQueryModel(this);
+ ui->reportResultView->setModel(reportResultModel);
+ QList<int> sizes;
+ sizes << ui->splitter->width() << 0;
+ ui->splitter->setSizes(sizes);
+}
+
+void ReportsTab::activate()
+{
+ if (ui->reports->count())
+ return;
+
+ on_reloadReports_clicked();
+}
+
+void ReportsTab::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 ReportsTab::on_reports_currentIndexChanged(int)
+{
+ on_runReport_clicked();
+}
+
+void ReportsTab::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 ReportsTab::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 ReportsTab::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);
+}
--- /dev/null
+#ifndef REPORTSTAB_H
+#define REPORTSTAB_H
+
+#include "abstracttab.h"
+
+namespace Ui {
+class ReportsTab;
+}
+
+class QSqlQueryModel;
+
+class ReportsTab : public AbstractTab
+{
+ Q_OBJECT
+
+public:
+ explicit ReportsTab(QWidget *parent = 0);
+ ~ReportsTab();
+
+ void init();
+ void activate();
+
+private slots:
+ void on_reloadReports_clicked();
+ void on_reports_currentIndexChanged(int index);
+ void on_runReport_clicked();
+ void on_editReport_clicked();
+ void on_addReport_clicked();
+
+private:
+ Ui::ReportsTab *ui;
+
+ QSqlQueryModel *reportResultModel;
+};
+
+#endif // REPORTSTAB_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ReportsTab</class>
+ <widget class="QWidget" name="ReportsTab">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>835</width>
+ <height>632</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="buttonLayout">
+ <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">
+ <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>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+#include "tabwidget.h"
+
+#include <QSettings>
+
+#include "abstracttab.h"
+#include "mainwindow.h"
+#include "mylist.h"
+
+#include <QDebug>
+
+TabWidget::TabWidget(QWidget *parent) :
+ QTabWidget(parent), previousTab(0)
+{
+ setDocumentMode(true);
+// setTabsClosable(true);
+// setMovable(true);
+
+ connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(removeTab(int)));
+ connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentTabChanged(int)));
+}
+
+TabWidget::~TabWidget()
+{
+ while (count())
+ removeTab(0);
+}
+
+int TabWidget::addTab(AbstractTab *tab)
+{
+ initTab(tab);
+ return QTabWidget::addTab(tab, tab->name());
+}
+
+int TabWidget::insertTab(int index, AbstractTab *tab)
+{
+ initTab(tab);
+ return QTabWidget::insertTab(index, tab, tab->name());
+}
+
+void TabWidget::removeTab(int index)
+{
+ AbstractTab *removedTab = tab(index);
+ Q_ASSERT_X(removedTab, "TabWidget", "removeTab, invalid tab");
+
+ QTabWidget::removeTab(index);
+ deinitTab(removedTab);
+}
+
+void TabWidget::removeTab(AbstractTab *tab)
+{
+ int index = indexOf(tab);
+ if (index != -1)
+ removeTab(index);
+}
+
+AbstractTab *TabWidget::tab(int index) const
+{
+ return qobject_cast<AbstractTab *>(QTabWidget::widget(index));
+}
+
+void TabWidget::tabNameChanged(const QString &newName)
+{
+ AbstractTab *tab = qobject_cast<AbstractTab *>(sender());
+
+ if (!tab)
+ return;
+
+ int index = indexOf(tab);
+
+ setTabText(index, newName);
+}
+
+void TabWidget::currentTabChanged(int newIndex)
+{
+ if (previousTab)
+ previousTab->deactivate();
+
+ previousTab = tab(newIndex);
+
+ if (previousTab)
+ previousTab->activate();
+}
+
+void TabWidget::initTab(AbstractTab *tab)
+{
+ Q_ASSERT_X(tab, "TabWidget", "initTab, Invalid tab");
+ connect(tab, SIGNAL(nameChanged(QString)), this, SLOT(tabNameChanged(QString)));
+ tab->init();
+ QSettings *s = LocalMyList::instance()->defaultLocalQSettings();
+ s->beginGroup("management-gui");
+ tab->loadSettings(s);
+ s->endGroup();
+}
+
+void TabWidget::deinitTab(AbstractTab *tab)
+{
+ Q_ASSERT_X(tab, "TabWidget", "deinitTab, Invalid tab");
+ if (tab == previousTab)
+ previousTab = 0;
+
+ QSettings *s = LocalMyList::instance()->defaultLocalQSettings();
+ s->beginGroup("management-gui");
+ tab->saveSettings(s);
+ s->endGroup();
+
+ tab->deinit();
+ delete tab;
+}
--- /dev/null
+#ifndef TABWIDGET_H
+#define TABWIDGET_H
+
+#include <QTabWidget>
+
+class AbstractTab;
+
+class TabWidget : public QTabWidget
+{
+ Q_OBJECT
+public:
+ explicit TabWidget(QWidget *parent = 0);
+ ~TabWidget();
+
+public slots:
+ int addTab(AbstractTab *tab);
+ int insertTab(int index, AbstractTab *tab);
+
+ void removeTab(int index);
+ void removeTab(AbstractTab *tab);
+
+ AbstractTab *tab(int index) const;
+
+private slots:
+ void tabNameChanged(const QString &newName);
+
+ void currentTabChanged(int newIndex);
+
+private:
+ void initTab(AbstractTab *tab);
+ void deinitTab(AbstractTab *tab);
+
+ AbstractTab *previousTab;
+};
+
+#endif // TABWIDGET_H