diff options
-rw-r--r-- | archivetreeview.cpp | 11 | ||||
-rw-r--r-- | archivetreeview.h | 1 | ||||
-rw-r--r-- | dbanalyzer.cpp | 160 | ||||
-rw-r--r-- | dbanalyzer.h | 78 | ||||
-rw-r--r-- | shemov.cpp | 11 | ||||
-rw-r--r-- | shemov.h | 3 | ||||
-rw-r--r-- | shemov.pro | 8 |
7 files changed, 269 insertions, 3 deletions
diff --git a/archivetreeview.cpp b/archivetreeview.cpp index cc6e529..52863f9 100644 --- a/archivetreeview.cpp +++ b/archivetreeview.cpp @@ -178,6 +178,17 @@ void ArchiveTreeView::showNoCoverDialog(){ mNoCoverDialog->show(); } +void ArchiveTreeView::selectMoviePart(int seriespartId, int seriesId){ + QModelIndex seriesIdx = mSeriesModel->findValue(seriesId, QModelIndex(), SeriesTreeModel::SeriesId); + QModelIndex partIdx = mSeriesModel->findValue(seriespartId, seriesIdx, SeriesTreeModel::SeriesPartId); + if(partIdx.isValid()){ + QModelIndex viewSelect = mSeriesWidget->seriesProxy()->mapFromSource(partIdx); + mSeriesWidget->seriesTree()->expand(viewSelect.parent()); + mSeriesWidget->seriesTree()->selectionModel()->select(viewSelect, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + mSeriesWidget->seriesTree()->scrollTo(viewSelect, QAbstractItemView::PositionAtCenter); + } +} + void ArchiveTreeView::selectMovie(const QModelIndex &idx){ if(!idx.isValid()){ return; diff --git a/archivetreeview.h b/archivetreeview.h index 2163fe5..f784d14 100644 --- a/archivetreeview.h +++ b/archivetreeview.h @@ -51,6 +51,7 @@ class ArchiveTreeView : public QWidget void cleanDatabase(const QString &table); void showNoCoverDialog(); void selectMovie(const QModelIndex &idx); + void selectMoviePart(int seriespartId, int seriesId); void copyPath(int type); void readSettings(); diff --git a/dbanalyzer.cpp b/dbanalyzer.cpp new file mode 100644 index 0000000..87d3dd2 --- /dev/null +++ b/dbanalyzer.cpp @@ -0,0 +1,160 @@ +/* + 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 + 2 of the License, or (at your option) any later version. +*/ + +#include <QSqlQuery> +#include <QTableWidget> +#include <QTreeView> +#include <QPushButton> +#include <QHBoxLayout> +#include <QVBoxLayout> +#include <QMutexLocker> +#include <QTableWidget> +#include <QModelIndex> + +#include <QDebug> + +#include "dbanalyzer.h" +#include "smtreemodel.h" +#include "smtreeitem.h" + +DbAnalyzerDialog::DbAnalyzerDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f){ + //create tab widget + mTab = new QTabWidget; + + //setup analyzer + mAnalyzer = new DbAnalyzer(this); + + // no actors + QWidget *noActorsT = new QWidget; + QStringList noActorsHeaders = QStringList() << tr("Series") << tr("Series part") << tr("Series Id") << tr("Seriespart"); + mNoActorsV = new QTreeView; + mNoActorsM = new SmTreeModel(noActorsHeaders, this); + mNoActorsV->setModel(mNoActorsM); + QVBoxLayout *noActorsL = new QVBoxLayout; + noActorsL->addWidget(mNoActorsV); + mNoActorsV->setColumnHidden(1, true); + mNoActorsV->setColumnHidden(2, true); + mNoActorsV->setColumnHidden(3, true); + mNoActorsV->setEditTriggers(QTreeView::NoEditTriggers); + mNoActorsV->setSelectionBehavior(QAbstractItemView::SelectRows); + mNoActorsV->setSelectionMode(QAbstractItemView::SingleSelection); + connect(mNoActorsV, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(noActorsDoubleClicked(QModelIndex))); + noActorsT->setLayout(noActorsL); + + //buttons + mCancel = new QPushButton(tr("Cancel")); + connect(mCancel, SIGNAL(clicked()), this, SLOT(cancelAnalyzer())); + mClose = new QPushButton(tr("Close")); + connect(mClose, SIGNAL(clicked()), this, SLOT(accept())); + + //setup dialog + mTab->addTab(noActorsT, tr("No Actors")); + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(mTab); + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addStretch(); + buttonLayout->addWidget(mCancel); + buttonLayout->addWidget(mClose); + mainLayout->addLayout(buttonLayout); + setLayout(mainLayout); + setMinimumWidth(500); + + //get things going + connect(mAnalyzer, SIGNAL(started()), this, SLOT(analyzerStarted())); + connect(mAnalyzer, SIGNAL(finished()), this, SLOT(analyzerFinished())); + mAnalyzer->start(); +} + +void DbAnalyzerDialog::cancelAnalyzer(){ + mAnalyzer->setCancel(true); +} + +void DbAnalyzerDialog::analyzerStarted(){ + mCancel->setEnabled(true); + mClose->setEnabled(false); +} + +void DbAnalyzerDialog::analyzerFinished(){ + mCancel->setEnabled(false); + mClose->setEnabled(true); + populateNoActors(); +} + +void DbAnalyzerDialog::noActorsDoubleClicked(const QModelIndex &idx){ + qDebug() << idx; + if(!idx.isValid()){ + return; + } + QModelIndex seriesPartIdx = mNoActorsM->index(idx.row(), 3, idx.parent()); + QModelIndex seriesIdx = mNoActorsM->index(idx.row(), 2, idx.parent()); + qDebug() << seriesPartIdx << seriesIdx; + //if(spIdx.isValid()){ + emit partClicked(seriesPartIdx.data().toInt(), seriesIdx.data().toInt()); + //} +} + +void DbAnalyzerDialog::populateNoActors(){ + const int columns = 4; + QList<QList<QVariant> > noActors = mAnalyzer->noActors(); + SmTreeItem *root = new SmTreeItem(columns); + foreach(QList<QVariant> l, noActors){ + SmTreeItem *child = new SmTreeItem(l, root); + root->appendChild(child); + } + mNoActorsM->setRoot(root); + mNoActorsV->resizeColumnToContents(0); +} + +DbAnalyzer::DbAnalyzer(QObject *parent) : QThread(parent), mCanceled(false), mStatus(Fail) { + mDb = QSqlDatabase::cloneDatabase(QSqlDatabase::database("treedb"), "analyzerDB"); + mDb.open(); + mStatus = mDb.isOpen() ? Ok : Fail; + mNoActorQuery = new QSqlQuery(mDb); + mNoActorQuery->prepare("SELECT series.tseries_name, seriesparts.iseriespart, series.iseries_id, seriesparts.iseriesparts_id FROM series, seriesparts LEFT JOIN seriesparts_actormap ON seriesparts.iseriesparts_id = seriesparts_actormap.iseriesparts_id WHERE iactors_id IS NULL AND seriesparts.iseries_id = series.iseries_id ORDER BY tseries_name"); +} + +DbAnalyzer::~DbAnalyzer(){ + delete mNoActorQuery; + mDb.close(); +} + +void DbAnalyzer::setCancel(bool canceled){ + QMutexLocker m(&mCancelMutex); + mCanceled = canceled; +} + +void DbAnalyzer::run(){ + noActorsCheck(); +} + +void DbAnalyzer::noActorsCheck(){ + if(!mNoActorQuery->exec()){ + mStatus = Fail; + return; + } + emit message(tr("Fetching movies without actors")); + while(mNoActorQuery->next()){ + if(mCanceled){ + break; + } + QList<QVariant> res; + for(int i = 0; i < 4; ++i){ + if(i == 0){ + if(mNoActorQuery->value(1).toInt() > 1){ + QString title = QString("%1 %2").arg(mNoActorQuery->value(0).toString(), mNoActorQuery->value(1).toString()); + res << title; + continue; + }else{ + res << mNoActorQuery->value(0); + } + } + res << mNoActorQuery->value(i); + } + mNoActorR << res; + } + emit message(tr("Done!")); +} diff --git a/dbanalyzer.h b/dbanalyzer.h new file mode 100644 index 0000000..2005c85 --- /dev/null +++ b/dbanalyzer.h @@ -0,0 +1,78 @@ +/* + 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 + 2 of the License, or (at your option) any later version. +*/ + +#ifndef DBANALYZER_H +#define DBANALYZER_H + +#include <QThread> +#include <QVariant> +#include <QList> +#include <QDialog> +#include <QSqlDatabase> +#include <QMutex> +#include <QModelIndex> + +class QSqlQuery; +class QTabWidget; +class QTreeView; +class QPushButton; +class SmTreeModel; +class DbAnalyzer; + +class DbAnalyzerDialog : public QDialog { + Q_OBJECT + public: + explicit DbAnalyzerDialog(QWidget *parent = 0, Qt::WindowFlags f = 0); + + signals: + void partClicked(int seriesPartId, int seriesId); + + private slots: + void cancelAnalyzer(); + void analyzerStarted(); + void analyzerFinished(); + void noActorsDoubleClicked(const QModelIndex &); + + private: + void populateNoActors(); + QTabWidget *mTab; + QTreeView *mNoActorsV; + SmTreeModel *mNoActorsM; + QPushButton *mClose; + QPushButton *mCancel; + DbAnalyzer *mAnalyzer; +}; + +class DbAnalyzer : public QThread { + Q_OBJECT + public: + enum Status { Ok, Fail }; + explicit DbAnalyzer(QObject *parent = 0); + ~DbAnalyzer(); + int status() { return mStatus; } + const QList<QList<QVariant> > noActors() { return mNoActorR; } + + public slots: + void setCancel(bool canceled); + + signals: + void message(const QString &); + + protected: + void run(); + + private: + void noActorsCheck(); + QSqlDatabase mDb; + QSqlQuery *mNoActorQuery; + QList<QList<QVariant> > mNoActorR; + QMutex mCancelMutex; + bool mCanceled; + int mStatus; +}; + +#endif // DBANALYZER_H @@ -51,6 +51,7 @@ #include "filestreemodel.h" #include "consistencycheck.h" #include "mappingtableeditor.h" +#include "dbanalyzer.h" SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), mOpenWithGroupFS(0), mOpenWithGroupAV(0) { //application icon @@ -333,6 +334,9 @@ void SheMov::createActions(){ mCleanupGroup->addAction(cleanup2); mConsistencyA = new QAction(tr("Check consisteny..."), this); connect(mConsistencyA, SIGNAL(triggered()), this, SLOT(checkConsistency())); + mAnalyzerA = new QAction(tr("Analyze Db..."), this); + connect(mAnalyzerA, SIGNAL(triggered()), this, SLOT(analyzeDb())); + //connnect mQuitA = new QAction(tr("Quit"), this); mQuitA->setShortcut(tr("CTRL+q")); @@ -620,6 +624,7 @@ void SheMov::createMenus(){ cleanupMenu->addActions(mCleanupGroup->actions()); fileMenu->addMenu(cleanupMenu); fileMenu->addAction(mConsistencyA); + fileMenu->addAction(mAnalyzerA); fileMenu->addAction(mShowNoCoverDialogA); fileMenu->addSeparator(); fileMenu->addAction(mQuitA); @@ -978,6 +983,12 @@ void SheMov::checkConsistency(){ c.exec(); } +void SheMov::analyzeDb(){ + DbAnalyzerDialog d(this); + connect(&d, SIGNAL(partClicked(int, int)), mATree, SLOT(selectMoviePart(int, int))); + d.exec(); +} + void SheMov::toggleHover(QObject *object){ QAction *action = qobject_cast<QAction*>(object); if(action){ @@ -22,6 +22,7 @@ class QMenu; class QActionGroup; class ArchiveTreeView; class NewMovieWizard; +class DbAnalyzerDialog; class SheMov : public QMainWindow { Q_OBJECT @@ -45,6 +46,7 @@ class SheMov : public QMainWindow { void newMovieWizardWithFiles(); void setSize(qint64 size); void checkConsistency(); + void analyzeDb(); void toggleHover(QObject *object); void checkMount(bool mounted); void toggleFilterGroup(bool checked); @@ -101,6 +103,7 @@ class SheMov : public QMainWindow { QAction *mRenameMenuA; QAction *mArchiveSelectedA; QAction *mConsistencyA; + QAction *mAnalyzerA; //hmm QAction *mHoverDirectoriesA; @@ -34,7 +34,8 @@ SOURCES = main.cpp \ seriesmetadatamodel.cpp \ mappingtableeditor.cpp \ smdialog.cpp \ - propertiesdialog.cpp + propertiesdialog.cpp \ + dbanalyzer.cpp HEADERS = listitem.h \ filesystemdirproxy.h \ filesystemwidget.h \ @@ -64,6 +65,7 @@ HEADERS = listitem.h \ seriesmetadatamodel.h \ mappingtableeditor.h \ smdialog.h \ - propertiesdialog.h -LIBS += -lmagic -lXfixes + propertiesdialog.h \ + dbanalyzer.h +LIBS += -lmagic -lXfixes -lX11 RESOURCES = shemov.qrc |