summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dbanalyzer.cpp156
-rw-r--r--dbanalyzer.h28
-rw-r--r--smtreeitem.cpp8
-rw-r--r--smtreeitem.h3
-rw-r--r--smtreemodel.cpp5
5 files changed, 181 insertions, 19 deletions
diff --git a/dbanalyzer.cpp b/dbanalyzer.cpp
index 4de88da..95bf5a9 100644
--- a/dbanalyzer.cpp
+++ b/dbanalyzer.cpp
@@ -15,12 +15,15 @@
#include <QTableWidget>
#include <QModelIndex>
#include <QLabel>
+#include <QColor>
+#include <QMenu>
+#include <QAction>
#include "dbanalyzer.h"
#include "smtreemodel.h"
#include "smtreeitem.h"
-DbAnalyzerDialog::DbAnalyzerDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f){
+DbAnalyzerDialog::DbAnalyzerDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f), mMarkMode(DbAnalyzer::NOMARKS), mCurrentView(0){
//create tab widget
mTab = new QTabWidget;
@@ -41,10 +44,12 @@ DbAnalyzerDialog::DbAnalyzerDialog(QWidget *parent, Qt::WindowFlags f) : QDialog
mNoActorsV->setColumnHidden(5, true);
mNoActorsV->setEditTriggers(QTreeView::NoEditTriggers);
mNoActorsV->setSelectionBehavior(QAbstractItemView::SelectRows);
- mNoActorsV->setSelectionMode(QAbstractItemView::SingleSelection);
+ mNoActorsV->setSelectionMode(QAbstractItemView::ExtendedSelection);
mNoActorsV->setAlternatingRowColors(true);
connect(mNoActorsV, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(noDataDoubleClicked(QModelIndex)));
noActorsT->setLayout(noActorsL);
+ mCurrentView = mNoActorsV;
+ mMarkMode = DbAnalyzer::MARKS_ACTORS;
//no covers
QWidget *noCoversT = new QWidget;
@@ -60,7 +65,7 @@ DbAnalyzerDialog::DbAnalyzerDialog(QWidget *parent, Qt::WindowFlags f) : QDialog
mNoCoversV->setColumnHidden(5, true);
mNoCoversV->setEditTriggers(QTreeView::NoEditTriggers);
mNoCoversV->setSelectionBehavior(QAbstractItemView::SelectRows);
- mNoCoversV->setSelectionMode(QAbstractItemView::SingleSelection);
+ mNoCoversV->setSelectionMode(QAbstractItemView::ExtendedSelection);
mNoCoversV->setAlternatingRowColors(true);
connect(mNoCoversV, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(noDataDoubleClicked(QModelIndex)));
noCoversT->setLayout(noCoversL);
@@ -102,9 +107,17 @@ DbAnalyzerDialog::DbAnalyzerDialog(QWidget *parent, Qt::WindowFlags f) : QDialog
connect(mRefresh, SIGNAL(clicked()), this, SLOT(refresh()));
mClose = new QPushButton(tr("Close"));
connect(mClose, SIGNAL(clicked()), this, SLOT(accept()));
- mDelete = new QPushButton(tr("Delete..."));
- mDelete->setEnabled(false);
- connect(mDelete, SIGNAL(clicked()), this, SLOT(deleteItems()));
+ mMark = new QPushButton(tr("Mark"));
+
+ //button menu
+ QMenu *markMenu = new QMenu(mMark);
+ QAction *markOkA = new QAction(tr("Set OK"), this);
+ QAction *deleteMarkA = new QAction(tr("Delete mark"), this);
+ markMenu->addAction(markOkA);
+ markMenu->addAction(deleteMarkA);
+ mMark->setMenu(markMenu);
+ connect(markOkA, SIGNAL(triggered()), this, SLOT(setMarks()));
+ connect(deleteMarkA, SIGNAL(triggered()), this, SLOT(deleteMarks()));
//setup dialog
mTab->addTab(noActorsT, tr("No Actors"));
@@ -112,13 +125,12 @@ DbAnalyzerDialog::DbAnalyzerDialog(QWidget *parent, Qt::WindowFlags f) : QDialog
mTab->addTab(strayActorsT, tr("Stray actors"));
mTab->addTab(strayGenresT, tr("Stray genres"));
-
//buttons
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(mCancel);
buttonLayout->addWidget(mRefresh);
buttonLayout->addStretch();
- buttonLayout->addWidget(mDelete);
+ buttonLayout->addWidget(mMark);
buttonLayout->addWidget(mClose);
//totals
@@ -165,8 +177,8 @@ void DbAnalyzerDialog::analyzerFinished(){
mCancel->setEnabled(false);
mRefresh->setEnabled(true);
mClose->setEnabled(true);
- populate(mNoActorsV, mNoActorsM, mAnalyzer->noActors());
- populate(mNoCoversV, mNoCoversM, mAnalyzer->noCovers());
+ populate(mNoActorsV, mNoActorsM, mAnalyzer->noActors(), mAnalyzer->actorMarks());
+ populate(mNoCoversV, mNoCoversM, mAnalyzer->noCovers(), mAnalyzer->coverMarks());
populate(mStrayActorsV, mStrayActorsM, mAnalyzer->strayActors());
populate(mStrayGenresV, mStrayGenresM, mAnalyzer->strayGenres());
QString totalString = QString(tr("<b>Total items: %1</b>"));
@@ -220,11 +232,48 @@ void DbAnalyzerDialog::deleteItems(){
}
void DbAnalyzerDialog::tabChanged(int index){
- mDelete->setEnabled(index > 1);
+ switch(index){
+ case 0:
+ mMarkMode = DbAnalyzer::MARKS_ACTORS;
+ mCurrentView = mNoActorsV;
+ break;
+ case 1:
+ mMarkMode = DbAnalyzer::MARKS_COVERS;
+ mCurrentView = mNoCoversV;
+ break;
+ case 2:
+ mMarkMode = DbAnalyzer::NOMARKS;
+ mCurrentView = mStrayActorsV;
+ break;
+ case 3:
+ mMarkMode = DbAnalyzer::NOMARKS;
+ mCurrentView = mStrayGenresV;
+ break;
+ default:
+ mMarkMode = DbAnalyzer::NOMARKS;
+ mCurrentView = 0;
+ break;
+ }
mTotal->setText(mTotals.at(index));
}
-void DbAnalyzerDialog::populate(QTreeView *view, SmTreeModel *model, const QList<QList<QVariant> > &data){
+void DbAnalyzerDialog::setMarks(){
+ if(mMarkMode != DbAnalyzer::NOMARKS){
+ const QList<int> curIds = currentIds();
+ mAnalyzer->setMarks(curIds, mMarkMode, 1);
+ refresh();
+ }
+}
+
+void DbAnalyzerDialog::deleteMarks(){
+ if(mMarkMode != DbAnalyzer::NOMARKS){
+ const QList<int> curIds = currentIds();
+ mAnalyzer->deleteMarks(curIds, mMarkMode);
+ refresh();
+ }
+}
+
+void DbAnalyzerDialog::populate(QTreeView *view, SmTreeModel *model, const QList<QList<QVariant> > &data, const QHash<int, QVariant> &marks){
const int columns = data.first().count();
if(columns == 0){
return;
@@ -232,12 +281,31 @@ void DbAnalyzerDialog::populate(QTreeView *view, SmTreeModel *model, const QList
SmTreeItem *root = new SmTreeItem(columns);
foreach(QList<QVariant> l, data){
SmTreeItem *child = new SmTreeItem(l, root);
+ if(!marks.isEmpty()){
+ int seriesId = l.at(4).toInt();
+ QColor fgColor = Qt::red;
+ if(marks.contains(seriesId) && marks.value(seriesId).toInt() > 0){
+ fgColor = Qt::green;
+ }
+ child->setForegroundColor(fgColor);
+ }
root->appendChild(child);
}
model->setRoot(root);
view->resizeColumnToContents(0);
}
+const QList<int> DbAnalyzerDialog::currentIds() const {
+ QTreeView *curView = qobject_cast<QTreeView*>(mCurrentView);
+ Q_ASSERT(curView);
+ QModelIndexList curIdxs = curView->selectionModel()->selectedRows(4);
+ QList<int> retval;
+ foreach(QModelIndex i, curIdxs){
+ retval << i.data().toInt();
+ }
+ return retval;
+}
+
DbAnalyzer::DbAnalyzer(QObject *parent) : QThread(parent), mCanceled(false), mStatus(Fail) {
mDb = QSqlDatabase::cloneDatabase(QSqlDatabase::database("treedb"), "analyzerDb");
mDb.open();
@@ -250,6 +318,12 @@ DbAnalyzer::DbAnalyzer(QObject *parent) : QThread(parent), mCanceled(false), mSt
mStrayGenresQuery->prepare("SELECT genres.tgenrename, genres.igenres_id, COUNT(seriesparts_genremap.igenres_id) FROM genres LEFT JOIN seriesparts_genremap ON genres.igenres_id = seriesparts_genremap.igenres_id WHERE seriesparts_genremap.igenres_id IS NULL GROUP BY genres.igenres_id, genres.tgenrename ORDER BY genres.tgenrename");
mNoCoverQuery = new QSqlQuery(mDb);
mNoCoverQuery->prepare("SELECT series.tseries_name, seriesparts.iseriespart, seriesparts.tsubtitle, series.iseries_id, seriesparts.iseriesparts_id FROM files, series, seriesparts WHERE files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id GROUP BY files.iseriespart_id, series.tseries_name,seriesparts.iseriespart, seriesparts.tsubtitle, seriesparts.iseriesparts_id, series.iseries_id HAVING COUNT(iseriespart_id) = 1 ORDER BY series.tseries_name");
+ mMarksQuery = new QSqlQuery(mDb);
+ mMarksQuery->prepare("SELECT id, mark_id FROM marks where mark_reason = :reason");
+ mSetMarksQuery = new QSqlQuery(mDb);
+ mSetMarksQuery->prepare("INSERT INTO marks (id, mark_reason, mark_id) VALUES(:seriesid, :reason, :mark_id)");
+ mDeleteMarksQuery = new QSqlQuery(mDb);
+ mDeleteMarksQuery->prepare("DELETE FROM marks WHERE id = :id AND mark_reason = :reason");
}
DbAnalyzer::~DbAnalyzer(){
@@ -257,6 +331,9 @@ DbAnalyzer::~DbAnalyzer(){
delete mNoCoverQuery;
delete mStrayActorsQuery;
delete mStrayGenresQuery;
+ delete mMarksQuery;
+ delete mSetMarksQuery;
+ delete mDeleteMarksQuery;
mDb.close();
mDb = QSqlDatabase();
QSqlDatabase::removeDatabase("analyzerDb");
@@ -267,19 +344,49 @@ void DbAnalyzer::setCancel(bool canceled){
mCanceled = canceled;
}
+void DbAnalyzer::setMarks(const QList<int> &ids, int reason, int mark_id){
+ mDb.transaction();
+ mSetMarksQuery->bindValue(":reason", reason);
+ mSetMarksQuery->bindValue(":mark_id", mark_id);
+ foreach(int id, ids){
+ mSetMarksQuery->bindValue(":seriesid", id);
+ if(!mSetMarksQuery->exec()){
+ mDb.rollback();
+ return;
+ }
+ }
+ mDb.commit();
+}
+
+void DbAnalyzer::deleteMarks(const QList<int> &ids, int reason){
+ mDb.transaction();
+ mDeleteMarksQuery->bindValue(":reason", reason);
+ foreach(int id, ids){
+ mDeleteMarksQuery->bindValue(":id", id);
+ if(!mDeleteMarksQuery->exec()){
+ mDb.rollback();
+ return;
+ }
+ }
+ mDb.commit();
+}
+
void DbAnalyzer::run(){
mNoActorR = noDataCheck(mNoActorQuery);
+ mActorMarks = marks(MARKS_ACTORS);
mNoCoverR = noDataCheck(mNoCoverQuery);
+ mCoverMarks = marks(MARKS_COVERS);
mStrayActorR = strayCheck(mStrayActorsQuery);
mStrayGenresR = strayCheck(mStrayGenresQuery);
}
const QList<QList<QVariant> > DbAnalyzer::noDataCheck(QSqlQuery *query){
if(!query->exec()){
- QMutexLocker m(&mStatusMutex);
- mStatus = Fail;
+ setStatus(Fail);
return QList<QList<QVariant> >();
}
+
+ //read data
QList<QList<QVariant> > retval;
while(query->next()){
if(mCanceled){
@@ -315,3 +422,24 @@ const QList<QList<QVariant> > DbAnalyzer::strayCheck(QSqlQuery *query){
}
return retval;
}
+
+QHash<int, QVariant> DbAnalyzer::marks(int markType){
+ QHash<int, QVariant> retval;
+ if(markType == NOMARKS){
+ return retval;
+ }
+ mMarksQuery->bindValue(":reason", markType);
+ if(!mMarksQuery->exec()){
+ setStatus(Fail);
+ return retval;
+ }
+ while(mMarksQuery->next()){
+ retval.insert(mMarksQuery->value(0).toInt(), mMarksQuery->value(1));
+ }
+ return retval;
+}
+
+void DbAnalyzer::setStatus(int status){
+ QMutexLocker m(&mStatusMutex);
+ mStatus = status;
+}
diff --git a/dbanalyzer.h b/dbanalyzer.h
index 653aa70..25b0bfb 100644
--- a/dbanalyzer.h
+++ b/dbanalyzer.h
@@ -11,6 +11,7 @@
#include <QThread>
#include <QVariant>
#include <QList>
+#include <QHash>
#include <QDialog>
#include <QSqlDatabase>
#include <QMutex>
@@ -27,7 +28,7 @@ class QLabel;
class DbAnalyzerDialog : public QDialog {
Q_OBJECT
public:
- enum DeleteMode { Actors, Genres };
+ enum Mode { Actors, Genres };
explicit DbAnalyzerDialog(QWidget *parent = 0, Qt::WindowFlags f = 0);
public slots:
@@ -44,9 +45,12 @@ class DbAnalyzerDialog : public QDialog {
void noDataDoubleClicked(const QModelIndex &);
void deleteItems();
void tabChanged(int index);
+ void setMarks();
+ void deleteMarks();
private:
- void populate(QTreeView *view ,SmTreeModel *model, const QList<QList<QVariant> > &data);
+ void populate(QTreeView *view ,SmTreeModel *model, const QList<QList<QVariant> > &data, const QHash<int, QVariant> &marks = QHash<int, QVariant>());
+ const QList<int> currentIds() const;
QTabWidget *mTab;
QTreeView *mNoActorsV;
QTreeView *mNoCoversV;
@@ -58,27 +62,34 @@ class DbAnalyzerDialog : public QDialog {
SmTreeModel *mStrayGenresM;
QPushButton *mClose;
QPushButton *mCancel;
- QPushButton *mDelete;
+ QPushButton *mMark;
QPushButton *mRefresh;
QLabel *mTotal;
QList<QString> mTotals;
DbAnalyzer *mAnalyzer;
+ int mMarkMode;
+ QTreeView *mCurrentView;
};
class DbAnalyzer : public QThread {
Q_OBJECT
public:
enum Status { Ok, Fail };
+ enum Marks { NOMARKS = 0, MARKS_ACTORS = 1, MARKS_COVERS = 2 };
explicit DbAnalyzer(QObject *parent = 0);
~DbAnalyzer();
int status() { return mStatus; }
- const QList<QList<QVariant> > noActors() { return mNoActorR; }
- const QList<QList<QVariant> > noCovers() { return mNoCoverR; }
+ const QList<QList<QVariant> > noActors() const { return mNoActorR; }
+ const QHash<int, QVariant> actorMarks() const { return mActorMarks; }
+ const QList<QList<QVariant> > noCovers() const { return mNoCoverR; }
+ const QHash<int, QVariant> coverMarks() const { return mCoverMarks; }
const QList<QList<QVariant> > strayActors() { return mStrayActorR; }
const QList<QList<QVariant> > strayGenres() { return mStrayGenresR; }
public slots:
void setCancel(bool canceled);
+ void setMarks(const QList<int> &ids, int reason, int mark_id);
+ void deleteMarks(const QList<int> &ids, int reason);
signals:
void message(const QString &);
@@ -89,15 +100,22 @@ class DbAnalyzer : public QThread {
private:
const QList<QList<QVariant> > noDataCheck(QSqlQuery *query);
const QList<QList<QVariant> > strayCheck(QSqlQuery *query);
+ QHash<int, QVariant> marks(int markType);
+ void setStatus(int status);
QSqlDatabase mDb;
QSqlQuery *mNoActorQuery;
QSqlQuery *mNoCoverQuery;
QSqlQuery *mStrayActorsQuery;
QSqlQuery *mStrayGenresQuery;
+ QSqlQuery *mMarksQuery;
+ QSqlQuery *mSetMarksQuery;
+ QSqlQuery *mDeleteMarksQuery;
QList<QList<QVariant> > mNoActorR;
QList<QList<QVariant> > mNoCoverR;
QList<QList<QVariant> > mStrayActorR;
QList<QList<QVariant> > mStrayGenresR;
+ QHash<int, QVariant> mActorMarks;
+ QHash<int, QVariant> mCoverMarks;
QMutex mCancelMutex;
QMutex mStatusMutex;
bool mCanceled;
diff --git a/smtreeitem.cpp b/smtreeitem.cpp
index 5584319..56d9b6e 100644
--- a/smtreeitem.cpp
+++ b/smtreeitem.cpp
@@ -73,6 +73,14 @@ void SmTreeItem::setData(int column, const QVariant &data){
mData[column] = data;
}
+QVariant SmTreeItem::foregroundColor() const{
+ return mForegroundColor;
+}
+
+void SmTreeItem::setForegroundColor(const QVariant &data){
+ mForegroundColor = data;
+}
+
bool SmTreeItem::insertChild(int where, SmTreeItem *child){
if((where < 0) || (where > mChildren.count())){
return false;
diff --git a/smtreeitem.h b/smtreeitem.h
index 591f2a4..28ab77a 100644
--- a/smtreeitem.h
+++ b/smtreeitem.h
@@ -26,6 +26,8 @@ class SmTreeItem {
void setParent(SmTreeItem *parent);
QVariant data(int column) const;
void setData(int column, const QVariant &data);
+ QVariant foregroundColor() const;
+ void setForegroundColor(const QVariant &data);
bool insertChild(int where, SmTreeItem *child);
bool removeChild(int where, bool deleteChild = true);
@@ -33,6 +35,7 @@ class SmTreeItem {
private:
QList<SmTreeItem*> mChildren;
QList<QVariant> mData;
+ QVariant mForegroundColor;
SmTreeItem *mParent;
};
diff --git a/smtreemodel.cpp b/smtreemodel.cpp
index 50a55d0..86d2b77 100644
--- a/smtreemodel.cpp
+++ b/smtreemodel.cpp
@@ -7,6 +7,7 @@
#include <QIcon>
#include <QSettings>
+#include <QBrush>
#include "smtreemodel.h"
#include "smtreeitem.h"
@@ -107,6 +108,10 @@ QVariant SmTreeModel::data(const QModelIndex &index, int role) const{
return mDecorationIcon;
}
}
+ if(role == Qt::ForegroundRole){
+ QColor fgCol = item->foregroundColor().value<QColor>();
+ return QBrush(fgCol);
+ }
return QVariant();
}