summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArno <am@disconnect.de>2013-06-01 22:52:19 +0200
committerArno <am@disconnect.de>2013-06-01 22:52:19 +0200
commit6fec376f7f44145efa509668927a0179c8ffa65e (patch)
tree49bbc7fe883085ff39e24b5f12fbef25d8cf48c5
parent6e92f5deb39aed43d72d8a64733f5b11e1650d5d (diff)
downloadSheMov-6fec376f7f44145efa509668927a0179c8ffa65e.tar.gz
SheMov-6fec376f7f44145efa509668927a0179c8ffa65e.tar.bz2
SheMov-6fec376f7f44145efa509668927a0179c8ffa65e.zip
Gather archive data in a thread
Fetching data sometimes takes a long time, so do it in a QThread and show a progress dialog. Some kludges included :)
-rw-r--r--archivemodel.cpp125
-rw-r--r--archivemodel.h38
-rw-r--r--archiveview.cpp44
-rw-r--r--archiveview.h29
-rw-r--r--shemov.cpp3
-rw-r--r--smdirwatcher.h2
6 files changed, 177 insertions, 64 deletions
diff --git a/archivemodel.cpp b/archivemodel.cpp
index 90c6cd9..c317c32 100644
--- a/archivemodel.cpp
+++ b/archivemodel.cpp
@@ -15,7 +15,8 @@ ArchiveModel::ArchiveModel(const QStringList &headers, QObject *parent) : SmTree
mAvailableOrders.insert("Series Name", SeriesName);
mAvailableOrders.insert("Actor", Actor);
mAvailableOrders.insert("Genre", Genre);
- setOrder(mOrder);
+ mCollector = new ArchiveCollector(NumFields, this);
+ connect(mCollector, SIGNAL(finished()), this, SLOT(collectorFinished()));
}
const QStringList ArchiveModel::availableOrders() const {
@@ -58,83 +59,103 @@ QVariant ArchiveModel::data(const QModelIndex &index, int role) const{
void ArchiveModel::setOrder(int order) {
mOrder = order;
- switch (order) {
- case SeriesName:
+ SmTreeItem *rootItem = new SmTreeItem(NumFields);
+ mCollector->populate(mOrder, rootItem);
+ if(!mCollector->isRunning()){
+ mCollector->start();
+ }
+}
+
+void ArchiveModel::setOrder(const QString &order){
+ int orderNum = mAvailableOrders.value(order);
+ setOrder(orderNum);
+}
+
+void ArchiveModel::collectorFinished(){
+ SmTreeItem *item = mCollector->rootItem();
+ setRoot(item);
+}
+
+ArchiveCollector::ArchiveCollector(int numFields, QObject *parent) : QThread(parent), mNumFields(numFields) {
+ mDb = QSqlDatabase::cloneDatabase(QSqlDatabase::database("treedb"), "archivedb");
+ mDb.open();
+}
+
+void ArchiveCollector::populate(int order, SmTreeItem *rootItem){
+ mRootItem = rootItem;
+ mSortOrder = order;
+}
+
+void ArchiveCollector::run(){
+ switch (mSortOrder){
+ case ArchiveModel::SeriesName:
populateBySeriesName();
break;
- case Actor:
- populateByActor();
- break;
- case Genre:
+ case ArchiveModel::Genre:
populateByGenre();
break;
+ case ArchiveModel::Actor:
+ populateByActor();
+ break;
default:
return;
}
}
-void ArchiveModel::setOrder(const QString &order){
- int orderNum = mAvailableOrders.value(order);
- setOrder(orderNum);
-}
-
-void ArchiveModel::populateBySeriesName() {
- SmTreeItem *rootItem = new SmTreeItem(NumFields);
- fetchChildren(rootItem);
- fetchSeries(QVariant(), rootItem);
- for(int i = 0; i < rootItem->childCount(); ++i){
- fetchParts(QVariant(), rootItem->child(i));
+void ArchiveCollector::populateBySeriesName() {
+ fetchSeries(QVariant(), mRootItem);
+ for(int i = 0; i < mRootItem->childCount(); ++i){
+ QString msg = QString("Processing %1").arg(mRootItem->child(i)->data(ArchiveModel::Name).toString());
+ emit message(msg);
+ fetchParts(QVariant(), mRootItem->child(i));
}
- setRoot(rootItem);
}
-void ArchiveModel::populateByGenre(){
+void ArchiveCollector::populateByGenre(){
QSqlQuery genreIdQuery = QSqlQuery("SELECT igenres_id, tgenrename FROM genres ORDER BY tgenrename", mDb);
- SmTreeItem *rootItem = new SmTreeItem(NumFields);
while(genreIdQuery.next()){
QList<QVariant> genreIdData;
- genreIdData << genreIdQuery.value(1) << genreIdQuery.value(0) << QVariant() << QVariant() << GenreNode << false << QVariant() << QVariant() << QVariant();
- SmTreeItem *genreIdItem = new SmTreeItem(genreIdData, rootItem);
- rootItem->appendChild(genreIdItem);
+ genreIdData << genreIdQuery.value(1) << genreIdQuery.value(0) << QVariant() << QVariant() << ArchiveModel::GenreNode << false << QVariant() << QVariant() << QVariant();
+ SmTreeItem *genreIdItem = new SmTreeItem(genreIdData, mRootItem);
+ mRootItem->appendChild(genreIdItem);
}
- fetchChildren(rootItem);
- setRoot(rootItem);
+ fetchChildren(mRootItem);
}
-void ArchiveModel::populateByActor(){
+void ArchiveCollector::populateByActor(){
QSqlQuery actorIdQuery = QSqlQuery("SELECT iactors_id, tactorname FROM actors ORDER BY tactorname", mDb);
- SmTreeItem *rootItem = new SmTreeItem(NumFields);
while(actorIdQuery.next()){
QList<QVariant> actorIdData;
- actorIdData << actorIdQuery.value(1) << actorIdQuery.value(0) << QVariant() << QVariant() << GenreNode << false << QVariant() << QVariant() << QVariant();
- SmTreeItem *actorIdItem = new SmTreeItem(actorIdData, rootItem);
- rootItem->appendChild(actorIdItem);
+ actorIdData << actorIdQuery.value(1) << actorIdQuery.value(0) << QVariant() << QVariant() << ArchiveModel::GenreNode << false << QVariant() << QVariant() << QVariant();
+ SmTreeItem *actorIdItem = new SmTreeItem(actorIdData, mRootItem);
+ mRootItem->appendChild(actorIdItem);
}
- fetchChildren(rootItem);
- setRoot(rootItem);
+ fetchChildren(mRootItem);
}
-void ArchiveModel::fetchChildren(SmTreeItem *parent){
+void ArchiveCollector::fetchChildren(SmTreeItem *parent){
for(int i = 0; i < parent->childCount(); ++i){
- fetchSeries(parent->child(i)->data(GenericId), parent->child(i));
+ QString msg = QString("Processing %1").arg(parent->child(i)->data(ArchiveModel::Name).toString());
+ emit message(msg);
+ fetchSeries(parent->child(i)->data(ArchiveModel::GenericId), parent->child(i));
for(int j = 0; j < parent->child(i)->childCount(); ++j){
SmTreeItem *seriesItem = parent->child(i)->child(j);
- fetchParts(parent->child(i)->data(GenericId), seriesItem);
+ fetchParts(parent->child(i)->data(ArchiveModel::GenericId), seriesItem);
}
}
}
-void ArchiveModel::fetchSeries(const QVariant &id, SmTreeItem *parent){
+void ArchiveCollector::fetchSeries(const QVariant &id, SmTreeItem *parent){
QSqlQuery seriesIdQuery(mDb);
- switch (mOrder) {
- case SeriesName:
+ switch (mSortOrder) {
+ case ArchiveModel::SeriesName:
seriesIdQuery.prepare("SELECT iseries_id, tseries_name FROM series ORDER BY tseries_name");
break;
- case Genre:
+ case ArchiveModel::Genre:
seriesIdQuery.prepare("SELECT distinct(series.iseries_id), tseries_name FROM series, seriesparts, seriesparts_genremap WHERE seriesparts_genremap.igenres_id = :genreid AND seriesparts_genremap.iseriesparts_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id ORDER BY tseries_name");
seriesIdQuery.bindValue(":genreid", id);
break;
- case Actor:
+ case ArchiveModel::Actor:
seriesIdQuery.prepare("SELECT distinct(series.iseries_id), tseries_name FROM series, seriesparts, seriesparts_actormap WHERE seriesparts_actormap.iactors_id = :actorid AND seriesparts_actormap.iseriesparts_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id ORDER BY tseries_name");
seriesIdQuery.bindValue(":actorid", id);
break;
@@ -148,34 +169,34 @@ void ArchiveModel::fetchSeries(const QVariant &id, SmTreeItem *parent){
}
while(seriesIdQuery.next()){
QList<QVariant> seriesData;
- seriesData << seriesIdQuery.value(1) << seriesIdQuery.value(0) << QVariant() << QVariant() << SeriesNode << false << QVariant() << QVariant() << QVariant();
+ seriesData << seriesIdQuery.value(1) << seriesIdQuery.value(0) << QVariant() << QVariant() << ArchiveModel::SeriesNode << false << QVariant() << QVariant() << QVariant();
SmTreeItem *seriesItem = new SmTreeItem(seriesData, parent);
parent->appendChild(seriesItem);
}
- parent->setData(Count, parent->childCount());
+ parent->setData(ArchiveModel::Count, parent->childCount());
}
-void ArchiveModel::fetchParts(const QVariant &id, SmTreeItem *parent){
+void ArchiveCollector::fetchParts(const QVariant &id, SmTreeItem *parent){
QSqlQuery partsQuery(mDb);
- if(mOrder == SeriesName){
+ if(mSortOrder == ArchiveModel::SeriesName){
partsQuery.prepare("SELECT iseriesparts_id, iseriespart, bfavorite, tsubtitle FROM seriesparts WHERE iseries_id = :id ORDER BY iseriespart");
- partsQuery.bindValue(":id", parent->data(GenericId));
- }else if(mOrder == Genre){
+ partsQuery.bindValue(":id", parent->data(ArchiveModel::GenericId));
+ }else if(mSortOrder == ArchiveModel::Genre){
partsQuery.prepare("SELECT seriesparts.iseriesparts_id, iseriespart, bfavorite, tsubtitle FROM seriesparts, seriesparts_genremap WHERE iseries_id = :id AND seriesparts.iseriesparts_id = seriesparts_genremap.iseriesparts_id AND seriesparts_genremap.igenres_id = :genreid ORDER BY iseriespart");
- partsQuery.bindValue(":id", parent->data(GenericId));
+ partsQuery.bindValue(":id", parent->data(ArchiveModel::GenericId));
partsQuery.bindValue(":genreid", id);
- }else if(mOrder == Actor){
+ }else if(mSortOrder == ArchiveModel::Actor){
partsQuery.prepare("SELECT seriesparts.iseriesparts_id, iseriespart, bfavorite, tsubtitle FROM seriesparts, seriesparts_actormap WHERE iseries_id = :id AND seriesparts.iseriesparts_id = seriesparts_actormap.iseriesparts_id AND seriesparts_actormap.iactors_id = :actorid ORDER BY iseriespart");
- partsQuery.bindValue(":id", parent->data(GenericId));
+ partsQuery.bindValue(":id", parent->data(ArchiveModel::GenericId));
partsQuery.bindValue(":actorid", id);
}
partsQuery.exec();
while(partsQuery.next()){
QList<QVariant> partData;
- partData << parent->data(Name) << parent->data(GenericId) << partsQuery.value(0) << partsQuery.value(1) << SeriesPartNode << partsQuery.value(2) << partsQuery.value(3) << QVariant();
+ partData << parent->data(ArchiveModel::Name) << parent->data(ArchiveModel::GenericId) << partsQuery.value(0) << partsQuery.value(1) << ArchiveModel::SeriesPartNode << partsQuery.value(2) << partsQuery.value(3) << QVariant();
SmTreeItem *partItem = new SmTreeItem(partData, parent);
parent->appendChild(partItem);
}
- parent->setData(Count, parent->childCount());
+ parent->setData(ArchiveModel::Count, parent->childCount());
}
diff --git a/archivemodel.h b/archivemodel.h
index 1f39717..c07fc7b 100644
--- a/archivemodel.h
+++ b/archivemodel.h
@@ -8,11 +8,14 @@
#ifndef ARCHIVEMODEL_H
#define ARCHIVEMODEL_H
-#include <QSqlDatabase>
#include <QHash>
+#include <QSqlDatabase>
+#include <QThread>
#include "smtreemodel.h"
+class ArchiveCollector;
+
class ArchiveModel : public SmTreeModel {
Q_OBJECT
public:
@@ -24,14 +27,38 @@ class ArchiveModel : public SmTreeModel {
explicit ArchiveModel(const QStringList &headers, QObject *parent = 0);
const QStringList availableOrders() const;
const QHash<QString, int> availableOrdersHash() const { return mAvailableOrders; }
+ ArchiveCollector *collector() { return mCollector; }
virtual QVariant data(const QModelIndex &index, int role) const;
- signals:
-
public slots:
void setOrder(int order);
void setOrder(const QString &order);
+ private slots:
+ void collectorFinished();
+
+ private:
+ QSqlDatabase mDb;
+ QHash<QString, int> mAvailableOrders;
+ ArchiveCollector *mCollector;
+ int mOrder;
+};
+
+class ArchiveCollector : public QThread {
+ Q_OBJECT
+ public:
+ explicit ArchiveCollector(int numFields, QObject *parent = 0);
+ SmTreeItem *rootItem() { return mRootItem; }
+
+ public slots:
+ void populate(int order, SmTreeItem *rootItem);
+
+ signals:
+ void message(const QString message);
+
+ protected:
+ virtual void run();
+
private:
void populateBySeriesName();
void populateByGenre();
@@ -40,8 +67,9 @@ class ArchiveModel : public SmTreeModel {
void fetchSeries(const QVariant &id, SmTreeItem *parent);
void fetchParts(const QVariant &id, SmTreeItem *parent);
QSqlDatabase mDb;
- QHash<QString, int> mAvailableOrders;
- int mOrder;
+ SmTreeItem *mRootItem;
+ int mNumFields;
+ int mSortOrder;
};
#endif // ARCHIVEMODEL_H
diff --git a/archiveview.cpp b/archiveview.cpp
index def3609..dbc3c39 100644
--- a/archiveview.cpp
+++ b/archiveview.cpp
@@ -6,6 +6,7 @@
*/
#include <QComboBox>
+#include <QDialog>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
@@ -17,9 +18,15 @@
#include "archiveview.h"
#include "smglobals.h"
-ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent) {
+ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent), mConstructing(true) {
QSettings s;
mArchiveModel = static_cast<ArchiveModel*>(SmGlobals::instance()->model("ArchiveModel"));
+ connect(mArchiveModel->collector(), SIGNAL(started()), this, SLOT(collectorStarted()));
+ connect(mArchiveModel->collector(), SIGNAL(finished()), this, SLOT(collectorFinished()));
+ mProgress = new ArchiveProgressDialog(this);
+ mProgress->setHidden(true);
+ connect(mArchiveModel->collector(), SIGNAL(message(QString)), mProgress, SLOT(setMessage(QString)));
+
mProxy = new ArchiveProxy;
mProxy->setSourceModel(mArchiveModel);
mTree = new ArchiveTree;
@@ -32,12 +39,16 @@ ArchiveView::ArchiveView(QWidget *parent) : QWidget(parent) {
mTree->setColumnHidden(ArchiveModel::Subtitle, true);
mTree->setColumnHidden(ArchiveModel::Count, true);
mTree->resizeColumnToContents(ArchiveModel::Name);
+
QString sortOrderName = s.value("archivemodel/sortorder", "Series Name").toString();
mSortOrder = new QComboBox;
mSortOrder->addItems(mArchiveModel->availableOrders());
- connect(mSortOrder, SIGNAL(currentIndexChanged(QString)), mArchiveModel, SLOT(setOrder(QString)));
- connect(mSortOrder, SIGNAL(currentTextChanged(QString)), mArchiveModel, SLOT(setOrder(QString)));
mSortOrder->setCurrentText(sortOrderName);
+ // this is _not_ redundant! when sortOrderName is the first
+ // item in the list, nothing will happen otherwise!
+ mArchiveModel->setOrder(sortOrderName);
+ connect(mSortOrder, SIGNAL(currentIndexChanged(QString)), mArchiveModel, SLOT(setOrder(QString)));
+
QLabel *l1 = new QLabel(tr("Filter"));
mFilter = new QLineEdit;
QString savedFilter = s.value("archivemodel/filter", QString()).toString();
@@ -80,6 +91,10 @@ void ArchiveView::writeSettings() {
s.setValue("archivemodel/filter", mFilter->text());
}
+QWidget *ArchiveView::progressDialog(){
+ return qobject_cast<QWidget *>(mProgress);
+}
+
void ArchiveView::setFilter(){
QString filter = mFilter->text();
mProxy->setFilter(filter, currentSortOrder());
@@ -92,9 +107,32 @@ void ArchiveView::clearFilter(){
mTree->collapseAll();
}
+void ArchiveView::collectorStarted(){
+ if(mConstructing){
+ return;
+ }
+ mProgress->show();
+}
+
+void ArchiveView::collectorFinished(){
+ mProgress->hide();
+}
+
ArchiveTree::ArchiveTree(QWidget *parent) : SmTreeView(parent) {
}
+ArchiveProgressDialog::ArchiveProgressDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f){
+ QHBoxLayout *mainLayout = new QHBoxLayout;
+ mMessage = new QLabel;
+ mainLayout->addWidget(mMessage);
+ setLayout(mainLayout);
+}
+
+void ArchiveProgressDialog::setMessage(const QString &msg){
+ QString message = QString(tr("<b>Gathering data... please wait!</b><br/><ul><li>%1</li></ul>")).arg(msg);
+ mMessage->setText(message);
+}
+
ArchiveFiles::ArchiveFiles(QWidget *parent) : SmTreeView(parent){
}
diff --git a/archiveview.h b/archiveview.h
index b76e487..a62fd66 100644
--- a/archiveview.h
+++ b/archiveview.h
@@ -8,20 +8,23 @@
#ifndef ARCHIVEVIEW_H
#define ARCHIVEVIEW_H
-#include <QWidget>
-#include <QSortFilterProxyModel>
+#include <QDialog>
#include <QRegExp>
+#include <QSortFilterProxyModel>
+#include <QWidget>
#include "archivemodel.h"
#include "smtreeview.h"
-class QSortFilterProxyModel;
class QComboBox;
+class QLabel;
class QLineEdit;
+class QSortFilterProxyModel;
class ArchiveTree;
class ArchiveFiles;
class ArchiveProxy;
+class ArchiveProgressDialog;
class ArchiveView : public QWidget {
Q_OBJECT
@@ -29,10 +32,16 @@ class ArchiveView : public QWidget {
explicit ArchiveView(QWidget *parent = 0);
int currentSortOrder() const;
void writeSettings();
+ // this is needed for displaying the progress dialog in the
+ // center of the main window...
+ void setConstructingDone() { mConstructing = false; }
+ QWidget *progressDialog();
private slots:
void setFilter();
void clearFilter();
+ void collectorStarted();
+ void collectorFinished();
private:
QComboBox *mSortOrder;
@@ -41,6 +50,8 @@ class ArchiveView : public QWidget {
ArchiveFiles *mFiles;
ArchiveModel *mArchiveModel;
ArchiveProxy *mProxy;
+ ArchiveProgressDialog *mProgress;
+ bool mConstructing;
};
class ArchiveTree : public SmTreeView {
@@ -52,6 +63,18 @@ class ArchiveTree : public SmTreeView {
ArchiveModel *mModel;
};
+class ArchiveProgressDialog : public QDialog {
+ Q_OBJECT
+ public:
+ explicit ArchiveProgressDialog(QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowStaysOnTopHint);
+
+ public slots:
+ void setMessage(const QString &msg);
+
+ private:
+ QLabel *mMessage;
+};
+
class ArchiveFiles : public SmTreeView {
public:
explicit ArchiveFiles(QWidget *parent = 0);
diff --git a/shemov.cpp b/shemov.cpp
index 6c53879..1baa7d5 100644
--- a/shemov.cpp
+++ b/shemov.cpp
@@ -140,6 +140,9 @@ SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, fla
readSettings();
mFSWidget->fileView()->setFocus(Qt::ActiveWindowFocusReason);
mPicWidget->readSettings();
+ mArchive->setConstructingDone();
+ Helper::centerWidget(mArchive->progressDialog());
+ mArchive->progressDialog()->show();
Helper::centerWidget(picViewer);
}
diff --git a/smdirwatcher.h b/smdirwatcher.h
index 5f3ef55..b0edd2f 100644
--- a/smdirwatcher.h
+++ b/smdirwatcher.h
@@ -1,4 +1,4 @@
-/*
+ /*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version