From afd74157ef705fa2b0323727b3a37e2806bb0730 Mon Sep 17 00:00:00 2001 From: Arno Date: Sun, 16 Jan 2011 15:04:41 +0100 Subject: Implement favorites SeriesParts can be marked as favorites. They won't be selectable when filtering by local Movies only. --- configurationdialog.cpp | 17 +++++++- configurationdialog.h | 2 + filestreemodel.cpp | 32 ++++++++++---- filestreemodel.h | 5 ++- seriestreemodel.cpp | 113 ++++++++++++++++++++++++++++++++++++------------ seriestreemodel.h | 11 ++++- seriestreewidget.cpp | 20 ++++++++- seriestreewidget.h | 1 + shemov.cpp | 11 +++-- shemov.h | 1 + smglobals.cpp | 4 +- 11 files changed, 168 insertions(+), 49 deletions(-) diff --git a/configurationdialog.cpp b/configurationdialog.cpp index 39a6858..dbf83b4 100644 --- a/configurationdialog.cpp +++ b/configurationdialog.cpp @@ -280,14 +280,24 @@ ConfigurationDialog::ConfigurationDialog(QWidget *parent, Qt::WindowFlags f) : Q colorGrid->addWidget(mArchivedColorButton, 6, 2); colorMapper->setMapping(mArchivedColorButton, mArchivedColor); connect(mArchivedColorButton, SIGNAL(clicked()), colorMapper, SLOT(map())); + QLabel *colorl8 = new QLabel(tr("Favorites")); + mFavoriteColor = new QLabel; + mFavoriteColor->setFrameStyle(QFrame::Sunken | QFrame::Panel); + mFavoriteColor->setScaledContents(true); + mFavoriteColorButton = new QPushButton(tr("Choose...")); + colorGrid->addWidget(colorl8, 7, 0); + colorGrid->addWidget(mFavoriteColor, 7, 1); + colorGrid->addWidget(mFavoriteColorButton, 7, 2); + colorMapper->setMapping(mFavoriteColorButton, mFavoriteColor); + connect(mFavoriteColorButton, SIGNAL(clicked()), colorMapper, SLOT(map())); connect(colorMapper, SIGNAL(mapped(QWidget*)), this, SLOT(chooseColor(QWidget*))); mAlternateColors = new QCheckBox(tr("Use alternating row colors")); mAlternateColors->setTristate(false); connect(mAlternateColors, SIGNAL(stateChanged(int)), this, SLOT(alternateColorsChanged(int))); - colorGrid->addWidget(mAlternateColors, 7, 1, 1, 2, Qt::AlignLeft); + colorGrid->addWidget(mAlternateColors, 8, 1, 1, 2, Qt::AlignLeft); QVBoxLayout *colorStretchLayout = new QVBoxLayout; colorStretchLayout->addStretch(); - colorGrid->addLayout(colorStretchLayout, 8, 1, 3, Qt::AlignLeft); + colorGrid->addLayout(colorStretchLayout, 9, 1, 3, Qt::AlignLeft); colorsWidget->setLayout(colorGrid); mTab->addTab(colorsWidget, tr("Colors")); @@ -367,6 +377,8 @@ void ConfigurationDialog::readSettings(){ mColors.insert(mLocalColor, local.value()); QVariant archived = s.value("ui/archivedcolor", Qt::black); mColors.insert(mArchivedColor, archived.value()); + QVariant favorite = s.value("ui/favoritecolor", Qt::red); + mColors.insert(mFavoriteColor, favorite.value()); QHash::const_iterator it; for(it = mColors.constBegin(); it != mColors.constEnd(); ++it){ setColor(it.key()); @@ -428,6 +440,7 @@ void ConfigurationDialog::writeSettings(){ s.setValue("ui/fontcolor", mColors.value(mFontColor)); s.setValue("ui/localcolor", mColors.value(mLocalColor)); s.setValue("ui/archivedcolor", mColors.value(mArchivedColor)); + s.setValue("ui/favoritecolor", mColors.value(mFavoriteColor)); s.setValue("ui/allowalternate", mAlternateColors->isChecked()); } diff --git a/configurationdialog.h b/configurationdialog.h index e33928f..2b7d12c 100644 --- a/configurationdialog.h +++ b/configurationdialog.h @@ -74,6 +74,7 @@ class ConfigurationDialog : public QDialog { QLabel *mFontColor; QLabel *mLocalColor; QLabel *mArchivedColor; + QLabel *mFavoriteColor; QPushButton *mSeenButton; QPushButton *mClipboardButton; QPushButton *mBaseButton; @@ -81,6 +82,7 @@ class ConfigurationDialog : public QDialog { QPushButton *mFontColorButton; QPushButton *mLocalColorButton; QPushButton *mArchivedColorButton; + QPushButton *mFavoriteColorButton; QCheckBox *mAlternateColors; QHash mColors; QStandardItemModel *mIconModel; diff --git a/filestreemodel.cpp b/filestreemodel.cpp index 33c5be4..5b776dc 100644 --- a/filestreemodel.cpp +++ b/filestreemodel.cpp @@ -93,7 +93,7 @@ void FilesTreeModel::setIds(const QList &seriesPartIds){ foreach(int s, seriesPartIds){ ids << QString::number(s); } - QString query = QString("SELECT iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno, siquality, ifiles_id, series.tseries_name, seriesparts.iseriespart FROM files, seriesparts, series WHERE iseriespart_id IN (%1) AND files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id ORDER BY tfilename, sifileno ASC").arg(ids.join(",")); + QString query = QString("SELECT iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno, siquality, ifiles_id, series.tseries_name, seriesparts.iseriespart, seriesparts.bfavorite FROM files, seriesparts, series WHERE iseriespart_id IN (%1) AND files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id ORDER BY tfilename, sifileno ASC").arg(ids.join(",")); QSqlQuery filesQuery(mDb); filesQuery.prepare(query); populate(filesQuery); @@ -104,10 +104,10 @@ void FilesTreeModel::setMode(int mode){ bool queryOk = false; switch(mode){ case Local: - queryOk = modeQuery.prepare("SELECT iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno, siquality, ifiles_id, series.tseries_name, seriesparts.iseriespart FROM files, seriesparts, series WHERE files.idvd = -1 AND files.sifiletype = 1 AND files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id"); + queryOk = modeQuery.prepare("SELECT iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno, siquality, ifiles_id, series.tseries_name, seriesparts.iseriespart, seriesparts.bfavorite FROM files, seriesparts, series WHERE files.idvd = -1 AND files.sifiletype = 1 AND files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id"); break; case Archived: - queryOk = modeQuery.prepare("SELECT iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno, siquality, ifiles_id, series.tseries_name, seriesparts.iseriespart FROM files, seriesparts, series WHERE files.idvd != -1 AND files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id"); + queryOk = modeQuery.prepare("SELECT iseriespart_id, tfilename, cmd5sum, bisize, idvd, sifiletype, sifileno, siquality, ifiles_id, series.tseries_name, seriesparts.iseriespart, seriesparts.bfavorite FROM files, seriesparts, series WHERE files.idvd != -1 AND files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id"); break; default: ; @@ -202,7 +202,9 @@ QVariant FilesTreeModel::data(const QModelIndex &index, int role) const{ return QColor(Qt::green); } if(index.column() == FileName){ - if(item->data(DvdNo) == -1){ + if(item->data(Favorite).toBool() == true){ + return mFavoriteColor; + }else if(item->data(DvdNo) == -1){ return mLocalColor; }else if(item->data(DvdNo).toInt() > 0){ return mArchivedColor; @@ -256,6 +258,9 @@ QVariant FilesTreeModel::data(const QModelIndex &index, int role) const{ if(role == SeriesNameRole){ return item->data(SeriesName); } + if(role == FavoriteRole){ + return item->data(Favorite); + } return QVariant(); } @@ -322,11 +327,17 @@ Qt::ItemFlags FilesTreeModel::flags(const QModelIndex &index) const{ if(index.data(FileTypeRole) == QVariant()){ return Qt::ItemIsEnabled; } - Qt::ItemFlags retval = Qt::ItemIsEnabled | Qt::ItemIsSelectable; + int retval = Qt::ItemIsEnabled | Qt::ItemIsSelectable; if(mEditableColumns.values().contains(index.column())){ retval |= Qt::ItemIsEditable; } - return retval; + if(mode() == Local){ + if(index.data(FavoriteRole).toBool() == true){ + int inverse = ~Qt::ItemIsSelectable; + retval &= inverse; + } + } + return static_cast(retval); } QHash FilesTreeModel::filesBySeriesPartId(int seriesPartId) const{ @@ -532,14 +543,16 @@ void FilesTreeModel::readSettings(){ mLocalColor = local.value(); QVariant archived = s.value("ui/archivedcolor", Qt::black); mArchivedColor = archived.value(); + QVariant favorite = s.value("ui/favoritecolor", Qt::red); + mFavoriteColor = favorite.value(); } void FilesTreeModel::populate(QSqlQuery &filesQuery){ - SmTreeItem *root = new SmTreeItem(15); - SmTreeItem *files = new SmTreeItem(15, root); + SmTreeItem *root = new SmTreeItem(16); + SmTreeItem *files = new SmTreeItem(16, root); files->setData(FileName, tr("Movies")); root->appendChild(files); - SmTreeItem *covers = new SmTreeItem(15, root); + SmTreeItem *covers = new SmTreeItem(16, root); covers->setData(FileName, tr("Covers")); root->appendChild(covers); QLocale l; @@ -562,6 +575,7 @@ void FilesTreeModel::populate(QSqlQuery &filesQuery){ data << displayName; data << tr("N/A"); // duration or size data << filesQuery.value(9).toString(); // series name + data << filesQuery.value(11); QString fullPath = data.at(FullPath).toString(); QFileInfo fi(fullPath); switch(filesQuery.value(5).toInt()){ diff --git a/filestreemodel.h b/filestreemodel.h index af8dfbb..ac47faa 100644 --- a/filestreemodel.h +++ b/filestreemodel.h @@ -23,9 +23,9 @@ class SeriesTreeModel; class FilesTreeModel : public SmTreeModel { Q_OBJECT public: - enum CustomRoles { FileNameRole = Qt::UserRole + 1, FullPathRole = Qt::UserRole + 2, SizeRole = Qt::UserRole + 3, DvdNoRole = Qt::UserRole + 4, SizeDisplayRole = Qt::UserRole + 5, FileTypeRole = Qt::UserRole + 6, Md5SumRole = Qt::UserRole + 7, PartNoRole = Qt::UserRole + 8, SeriesPartIdRole = Qt::UserRole + 9, QualityRole = Qt::UserRole + 10, FilesIdRole = Qt::UserRole + 11, SeriesPartRole = Qt::UserRole + 12, DisplayNameRole = Qt::UserRole + 13, SizeDurationRole = Qt::UserRole + 14, SeriesNameRole = Qt::UserRole + 15 }; + enum CustomRoles { FileNameRole = Qt::UserRole + 1, FullPathRole = Qt::UserRole + 2, SizeRole = Qt::UserRole + 3, DvdNoRole = Qt::UserRole + 4, SizeDisplayRole = Qt::UserRole + 5, FileTypeRole = Qt::UserRole + 6, Md5SumRole = Qt::UserRole + 7, PartNoRole = Qt::UserRole + 8, SeriesPartIdRole = Qt::UserRole + 9, QualityRole = Qt::UserRole + 10, FilesIdRole = Qt::UserRole + 11, SeriesPartRole = Qt::UserRole + 12, DisplayNameRole = Qt::UserRole + 13, SizeDurationRole = Qt::UserRole + 14, SeriesNameRole = Qt::UserRole + 15, FavoriteRole = Qt::UserRole + 16 }; enum FileTypes { Movie = 1, FrontCover = 2, BackCover = 3, GeneralCover = 4 }; - enum Fields { FileName = 0, PartNo = 1, SizeDisplay = 2, Quality = 3, DvdNo = 4, FullPath = 5, Size = 6, FileType = 7, Md5Sum = 8, SeriesPartId = 9, FilesId = 10, SeriesPart = 11, DisplayName = 12, SizeDuration = 13, SeriesName = 14 }; + enum Fields { FileName = 0, PartNo = 1, SizeDisplay = 2, Quality = 3, DvdNo = 4, FullPath = 5, Size = 6, FileType = 7, Md5Sum = 8, SeriesPartId = 9, FilesId = 10, SeriesPart = 11, DisplayName = 12, SizeDuration = 13, SeriesName = 14, Favorite = 15 }; enum Mode { Normal = 0, Archived = 1, Local = 2 }; explicit FilesTreeModel(QStringList &headers, QObject *parent = 0); const QHash fileTypes() const { return mFileTypes; } @@ -87,6 +87,7 @@ class FilesTreeModel : public SmTreeModel { const int mMagic; QColor mLocalColor; QColor mArchivedColor; + QColor mFavoriteColor; }; #endif // FILESTREEMODEL_H diff --git a/seriestreemodel.cpp b/seriestreemodel.cpp index 555c0f4..fcc993f 100644 --- a/seriestreemodel.cpp +++ b/seriestreemodel.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "seriestreemodel.h" #include "smtreeitem.h" @@ -19,11 +20,13 @@ SeriesTreeModel::SeriesTreeModel(QStringList &headers, QObject *parent) : SmTreeModel(headers, parent){ mDb = QSqlDatabase::database("treedb"); mSeriesPartsQuery = new QSqlQuery(mDb); - mSeriesPartsQuery->prepare("SELECT iseriesparts_id, iseriespart FROM seriesparts WHERE iseries_id = :id ORDER BY iseriespart"); + mSeriesPartsQuery->prepare("SELECT iseriesparts_id, iseriespart, bfavorite FROM seriesparts WHERE iseries_id = :id ORDER BY iseriespart"); mUpdateSeriesIdQuery = new QSqlQuery(mDb); mUpdateSeriesIdQuery->prepare("UPDATE seriesparts SET iseries_id = :newid WHERE iseries_id = :oldid"); mUpdateSeriesNameQuery = new QSqlQuery(mDb); mUpdateSeriesNameQuery->prepare("UPDATE series SET tseries_name = :newname WHERE iseries_id = :id"); + mUpdateFavoriteQuery = new QSqlQuery(mDb); + mUpdateFavoriteQuery->prepare("UPDATE seriesparts SET bfavorite = :fav WHERE iseriesparts_id = :id"); mDeleteSeriesQuery = new QSqlQuery(mDb); mDeleteSeriesQuery->prepare("DELETE FROM series where iseries_id = :id"); mDeleteSeriesPartQuery = new QSqlQuery(mDb); @@ -49,6 +52,7 @@ SeriesTreeModel::~SeriesTreeModel(){ delete mSeriesPartsQuery; delete mUpdateSeriesIdQuery; delete mUpdateSeriesNameQuery; + delete mUpdateFavoriteQuery; delete mDeleteSeriesQuery; delete mDeleteSeriesPartQuery; delete mSeriesInsertQuery; @@ -99,6 +103,11 @@ QVariant SeriesTreeModel::data(const QModelIndex &index, int role) const{ return decorationIcon(); } } + if(role == Qt::ForegroundRole){ + if(item->data(Favorite).toBool()){ + return mFavoriteColor; + } + } if(role == Qt::EditRole){ if(index.data(TypeRole) == Series || index.data(TypeRole) == NewSeries){ if(index.column() == 0){ @@ -121,6 +130,9 @@ QVariant SeriesTreeModel::data(const QModelIndex &index, int role) const{ if(role == TypeRole){ return item->data(Type); } + if(role == FavoriteRole){ + return item->data(Favorite); + } return QVariant(); } @@ -129,25 +141,28 @@ bool SeriesTreeModel::setData(const QModelIndex &index, const QVariant &value, i return false; } if(role == Qt::EditRole){ - if(index.data(TypeRole).toInt() == Series){ - //change of series name - if(index.column() == Name){ - QModelIndex newSeries = findValue(value, index.parent(), index.column()); - if(newSeries == index){ - //no change made, exit gracefully - return false; - } - //int oldSeriesId = index.data(SeriesIdRole).toInt(); - if(newSeries != QModelIndex()){ - //series already exists, merge - return mergeSeries(index, newSeries); - }else{ - //rename series - return renameSeries(index, value); + if(index.column() == Name){ + if(index.data(TypeRole).toInt() == Series){ + //change of series name + if(index.column() == Name){ + QModelIndex newSeries = findValue(value, index.parent(), index.column()); + if(newSeries == index){ + //no change made, exit gracefully + return false; + } + if(newSeries != QModelIndex()){ + //series already exists, merge + return mergeSeries(index, newSeries); + }else{ + //rename series + return renameSeries(index, value); + } } + }else if(index.data(TypeRole).toInt() == NewSeries){ + return setNewSeries(index, value); } - }else if(index.data(TypeRole).toInt() == NewSeries){ - return setNewSeries(index, value); + }else if(index.column() == Favorite){ + return setFavorite(index, value); } } return false; @@ -351,12 +366,12 @@ void SeriesTreeModel::setMappingFilter(const QString &filter, const QString &tab if(ids.isEmpty()){ return; } - QString seriesPartsTemplate("SELECT DISTINCT(seriesparts.iseriesparts_id), seriesparts.iseriespart FROM seriesparts, seriesparts_%1map WHERE seriesparts.iseries_id = :id AND seriesparts_%1map.iseriesparts_id = seriesparts.iseriesparts_id AND seriesparts_%1map.i%1s_id IN (%2) ORDER BY iseriespart"); + QString seriesPartsTemplate("SELECT DISTINCT(seriesparts.iseriesparts_id), seriesparts.iseriespart, seriesparts.bfavorite FROM seriesparts, seriesparts_%1map WHERE seriesparts.iseries_id = :id AND seriesparts_%1map.iseriesparts_id = seriesparts.iseriesparts_id AND seriesparts_%1map.i%1s_id IN (%2) ORDER BY iseriespart"); QString seriesIdTemplate = QString("SELECT DISTINCT(series.iseries_id), series.tseries_name FROM series, seriesparts, seriesparts_%1map, %1s WHERE %1s.i%1s_id IN (%2) AND %1s.i%1s_id = seriesparts_%1map.i%1s_id AND seriesparts_%1map.iseriesparts_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id ORDER BY series.tseries_name").arg(table).arg(ids.join(",")); QSqlQuery seriesIdQuery(seriesIdTemplate, mDb); while(seriesIdQuery.next()){ QList seriesData; - seriesData << seriesIdQuery.value(1) << seriesIdQuery.value(0) << QVariant() << QVariant() << Series; + seriesData << seriesIdQuery.value(1) << seriesIdQuery.value(0) << QVariant() << QVariant() << Series << false; SmTreeItem *seriesItem = new SmTreeItem(seriesData, rootItem); rootItem->appendChild(seriesItem); QString partsQueryString = seriesPartsTemplate.arg(table).arg(ids.join(",")); @@ -366,7 +381,7 @@ void SeriesTreeModel::setMappingFilter(const QString &filter, const QString &tab partsQuery.exec(); while(partsQuery.next()){ QList partData; - partData << seriesData.at(Name) << seriesData.at(SeriesId) << partsQuery.value(0) << partsQuery.value(1) << Part; + partData << seriesData.at(Name) << seriesData.at(SeriesId) << partsQuery.value(0) << partsQuery.value(1) << Part << partsQuery.value(2); SmTreeItem *partItem = new SmTreeItem(partData, seriesItem); seriesItem->appendChild(partItem); mSeriesPartSeriesMap.insert(partsQuery.value(0).toInt(), seriesData.at(1).toInt()); @@ -386,7 +401,7 @@ void SeriesTreeModel::setFileFilter(const QString &filter, const QString &column seriesIdQuery.prepare(idQueryTemplate); value = QString("%%1%").arg(filter); seriesIdQuery.bindValue(":value", value); - partsQueryTemplate = QString("SELECT DISTINCT(seriesparts.iseriesparts_id), seriesparts.iseriespart FROM seriesparts, series, files WHERE series.iseries_id = :id AND series.iseries_id = seriesparts.iseries_id AND seriesparts.iseriesparts_id = files.iseriespart_id AND files.%1 LIKE :value"); + partsQueryTemplate = QString("SELECT DISTINCT(seriesparts.iseriesparts_id), seriesparts.iseriespart, seriesparts.bfavorite FROM seriesparts, series, files WHERE series.iseries_id = :id AND series.iseries_id = seriesparts.iseries_id AND seriesparts.iseriesparts_id = files.iseriespart_id AND files.%1 LIKE :value"); }else if(queryType == NumericQuery){ QRegExp valRe("([<>=]?)\\s*(\\d+)\\s*(\\w*)"); (void)valRe.indexIn(value.toString()); @@ -396,7 +411,7 @@ void SeriesTreeModel::setFileFilter(const QString &filter, const QString &column QString idQueryTemplate = QString("SELECT DISTINCT(series.iseries_id), series.tseries_name FROM series, seriesparts, files WHERE files.%1 %2 :value AND files.iseriespart_id = seriesparts.iseriesparts_id AND seriesparts.iseries_id = series.iseries_id ORDER BY series.tseries_name").arg(column).arg(op); seriesIdQuery.prepare(idQueryTemplate); seriesIdQuery.bindValue(":value", value); - partsQueryTemplate = QString("SELECT DISTINCT(seriesparts.iseriesparts_id), seriesparts.iseriespart FROM seriesparts, series, files WHERE series.iseries_id = :id AND series.iseries_id = seriesparts.iseries_id AND seriesparts.iseriesparts_id = files.iseriespart_id AND files.%1 %2 :value"); + partsQueryTemplate = QString("SELECT DISTINCT(seriesparts.iseriesparts_id), seriesparts.iseriespart, seriesparts.bfavorite FROM seriesparts, series, files WHERE series.iseries_id = :id AND series.iseries_id = seriesparts.iseries_id AND seriesparts.iseriesparts_id = files.iseriespart_id AND files.%1 %2 :value"); }else{ return; } @@ -405,7 +420,7 @@ void SeriesTreeModel::setFileFilter(const QString &filter, const QString &column SmTreeItem *rootItem = new SmTreeItem(5); while(seriesIdQuery.next()){ QList seriesData; - seriesData << seriesIdQuery.value(1) << seriesIdQuery.value(0) << QVariant() << QVariant() << Series; + seriesData << seriesIdQuery.value(1) << seriesIdQuery.value(0) << QVariant() << QVariant() << Series << false; SmTreeItem *seriesItem = new SmTreeItem(seriesData, rootItem); rootItem->appendChild(seriesItem); QString partsQueryString; @@ -422,7 +437,7 @@ void SeriesTreeModel::setFileFilter(const QString &filter, const QString &column if(partsQuery.exec()){ while(partsQuery.next()){ QList partData; - partData << seriesData.at(Name) << seriesData.at(SeriesId) << partsQuery.value(0) << partsQuery.value(1) << Part; + partData << seriesData.at(Name) << seriesData.at(SeriesId) << partsQuery.value(0) << partsQuery.value(1) << Part << partsQuery.value(2); SmTreeItem *partItem = new SmTreeItem(partData, seriesItem); seriesItem->appendChild(partItem); mSeriesPartSeriesMap.insert(partsQuery.value(0).toInt(), seriesData.at(1).toInt()); @@ -433,20 +448,46 @@ void SeriesTreeModel::setFileFilter(const QString &filter, const QString &column } } +void SeriesTreeModel::readSettings(){ + QSettings s; + QVariant fc = s.value("ui/favoritecolor"); + mFavoriteColor = fc.value(); + conditionalUpdate(index(0, 0, QModelIndex()), Favorite, true); +} + +void SeriesTreeModel::conditionalUpdate(const QModelIndex &parent, int field, const QVariant &value){ + SmTreeItem *item = static_cast(parent.internalPointer()); + if(item->childCount() > 0){ + //series + for(int i = 0; i < item->childCount(); ++i){ + QModelIndex newParent = parent.child(i, field); + if(newParent.isValid()){ + conditionalUpdate(newParent, field, value); + } + } + }else{ + //seriespart + if(item->data(field) == value){ + QModelIndex start = index(parent.row(), 0, parent.parent()); + emit dataChanged(start, parent); + } + } +} + void SeriesTreeModel::populate(){ QSqlQuery seriesQuery = QSqlQuery("SELECT iseries_id, tseries_name FROM series ORDER BY tseries_name", mDb); mSeriesPartSeriesMap.clear(); - SmTreeItem *rootItem = new SmTreeItem(5); + SmTreeItem *rootItem = new SmTreeItem(6); while(seriesQuery.next()){ QList seriesData; - seriesData << seriesQuery.value(1) << seriesQuery.value(0) << QVariant() << QVariant() << Series; + seriesData << seriesQuery.value(1) << seriesQuery.value(0) << QVariant() << QVariant() << Series << false; SmTreeItem *seriesItem = new SmTreeItem(seriesData, rootItem); rootItem->appendChild(seriesItem); mSeriesPartsQuery->bindValue(":id", seriesData.at(1)); mSeriesPartsQuery->exec(); while(mSeriesPartsQuery->next()){ QList partData; - partData << seriesData.at(Name) << seriesData.at(SeriesId) << mSeriesPartsQuery->value(0) << mSeriesPartsQuery->value(1) << Part; + partData << seriesData.at(Name) << seriesData.at(SeriesId) << mSeriesPartsQuery->value(0) << mSeriesPartsQuery->value(1) << Part << mSeriesPartsQuery->value(2); SmTreeItem *partItem = new SmTreeItem(partData, seriesItem); seriesItem->appendChild(partItem); mSeriesPartSeriesMap.insert(mSeriesPartsQuery->value(0).toInt(), seriesData.at(1).toInt()); @@ -538,3 +579,19 @@ bool SeriesTreeModel::setNewSeries(const QModelIndex &source, const QVariant &va mDb.rollback(); return false; } + +bool SeriesTreeModel::setFavorite(const QModelIndex &source, const QVariant &value){ + SmTreeItem *item = static_cast(source.internalPointer()); + mDb.transaction(); + mUpdateFavoriteQuery->bindValue(":fav", value); + mUpdateFavoriteQuery->bindValue(":id", item->data(SeriesPartId)); + if(mUpdateFavoriteQuery->exec()){ + item->setData(Favorite, value); + QModelIndex start = index(source.row(), 0, source.parent()); + emit dataChanged(start, source); + mDb.commit(); + return true; + } + mDb.rollback(); + return false; +} diff --git a/seriestreemodel.h b/seriestreemodel.h index e25c111..c20014d 100644 --- a/seriestreemodel.h +++ b/seriestreemodel.h @@ -20,8 +20,8 @@ class QSqlQuery; class SeriesTreeModel : public SmTreeModel { Q_OBJECT public: - enum CustomRoles { NameRole = Qt::UserRole + 1, SeriesIdRole = Qt::UserRole + 2, SeriesPartIdRole = Qt::UserRole + 3, SeriesPartRole = Qt::UserRole + 4, TypeRole = Qt::UserRole + 5 }; - enum Fields { Name = 0, SeriesId = 1, SeriesPartId = 2, SeriesPart = 3, Type = 4 }; + enum CustomRoles { NameRole = Qt::UserRole + 1, SeriesIdRole = Qt::UserRole + 2, SeriesPartIdRole = Qt::UserRole + 3, SeriesPartRole = Qt::UserRole + 4, TypeRole = Qt::UserRole + 5, FavoriteRole = Qt::UserRole + 6 }; + enum Fields { Name = 0, SeriesId = 1, SeriesPartId = 2, SeriesPart = 3, Type = 4, Favorite = 5 }; enum Types { Series, Part, NewSeries }; enum QueryType { NumericQuery, TextQuery }; explicit SeriesTreeModel(QStringList &headers, QObject *parent = 0); @@ -55,16 +55,22 @@ class SeriesTreeModel : public SmTreeModel { void needResort(); void consistencyMsg(const QString &msg); + public slots: + void readSettings(); + void conditionalUpdate(const QModelIndex &parent, int field, const QVariant &value); + private: void populate(); bool mergeSeries(const QModelIndex &from, const QModelIndex &to); bool renameSeries(const QModelIndex &source, const QVariant &value); bool setNewSeries(const QModelIndex &source, const QVariant &value); + bool setFavorite(const QModelIndex &source, const QVariant &value); QString archivePath(const QString &fileName, const QString &md5sum) const; QSqlDatabase mDb; QSqlQuery *mSeriesPartsQuery; QSqlQuery *mUpdateSeriesIdQuery; QSqlQuery *mUpdateSeriesNameQuery; + QSqlQuery *mUpdateFavoriteQuery; QSqlQuery *mDeleteSeriesQuery; QSqlQuery *mDeleteSeriesPartQuery; QSqlQuery *mSeriesInsertQuery; @@ -75,6 +81,7 @@ class SeriesTreeModel : public SmTreeModel { QSqlQuery *mNextDvdNoQuery; QSqlQuery *mGenreFilterQuery; QHash mSeriesPartSeriesMap; + QColor mFavoriteColor; }; #endif // SERIESTREEMODEL_H diff --git a/seriestreewidget.cpp b/seriestreewidget.cpp index 24e9eb4..518cac1 100644 --- a/seriestreewidget.cpp +++ b/seriestreewidget.cpp @@ -64,7 +64,7 @@ SeriesTreeWidget::SeriesTreeWidget(QWidget *parent) : QWidget(parent){ mProxy->setSourceModel(mModel); mView->setModel(mProxy); mView->setSortingEnabled(true); - for(int i = 1; i < 5 ;++i){ + for(int i = 1; i < 6 ;++i){ mView->setColumnHidden(i, true); } mView->resizeColumnToContents(0); @@ -137,6 +137,23 @@ void SeriesTreeWidget::seriesAdded(QString seriesName, int seriesPart, bool reso } } +void SeriesTreeWidget::toggleFavorite(){ + QModelIndexList selected = mView->selectionModel()->selectedRows(); + if(selected.isEmpty()){ + return; + } + foreach(QModelIndex idx, selected){ + if(idx.data(SeriesTreeModel::TypeRole).toInt() == SeriesTreeModel::Part){ + bool curFav = idx.data(SeriesTreeModel::FavoriteRole).toBool(); + QModelIndex source = mProxy->mapToSource(idx); + if(source.isValid()){ + source = mModel->index(source.row(), SeriesTreeModel::Favorite, source.parent()); + } + mModel->setData(source, !curFav, Qt::EditRole); + } + } +} + void SeriesTreeWidget::deleteFromSeries(){ QModelIndexList selected = mView->selectionModel()->selectedRows(); if(selected.isEmpty()){ @@ -217,6 +234,7 @@ void SeriesTreeWidget::readSettings(){ mView->setCurrentIndex(real); } mFilterEdit->setText(s.value("archive/filtertext").toString()); + mModel->readSettings(); } void SeriesTreeWidget::writeSettings(){ diff --git a/seriestreewidget.h b/seriestreewidget.h index f177943..c5027c7 100644 --- a/seriestreewidget.h +++ b/seriestreewidget.h @@ -47,6 +47,7 @@ class SeriesTreeWidget : public QWidget { public slots: void newSeries(); void seriesAdded(const QString seriesName, int seriesPart, bool resort = true); + void toggleFavorite(); void deleteFromSeries(); void readSettings(); void writeSettings(); diff --git a/shemov.cpp b/shemov.cpp index 51a432f..4036d9a 100644 --- a/shemov.cpp +++ b/shemov.cpp @@ -98,6 +98,7 @@ SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, fla connect(mFSWidget->dirModel(), SIGNAL(layoutChanged()), this, SLOT(setFsFree())); connect(mFSWidget->dirModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(setFsFree())); connect(this, SIGNAL(configChanged()), mFSWidget->fileView(), SLOT(readConfig())); + connect(this, SIGNAL(configChanged()), mATree->seriesWidget(), SLOT(readSettings())); connect(mFSWidget, SIGNAL(mounted(bool)), this, SLOT(checkMount(bool))); QWidget *centralWidget = new QWidget; @@ -383,6 +384,9 @@ void SheMov::createActions(){ editMapper->setMapping(a, it.value()); } connect(editMapper, SIGNAL(mapped(int)), mATree->filesWidget(), SLOT(edit(int))); + mToggleFavoriteA = new QAction(tr("Toggle as favorite"), this); + mToggleFavoriteA->setShortcut(tr("CTRL+m")); + connect(mToggleFavoriteA, SIGNAL(triggered()), mATree->seriesWidget(), SLOT(toggleFavorite())); //Edit menu rename submenu mTemplateA = new QAction(tr("Set as template"), this); @@ -668,9 +672,6 @@ void SheMov::createMenus(){ mFSViewMenu = new QMenu(tr("&View"), this); mFSHoverMenu = new QMenu(tr("Hover over"), this); mFSHoverMenu->addActions(mFSHoverGroup->actions()); - /*foreach(QAction *a, mFSHoverGroup->actions()){ - mFSHoverMenu->addAction(a); - }*/ mFSViewMenu->addMenu(mFSHoverMenu); mViewFSMenuA = menuBar()->addMenu(mFSViewMenu); @@ -743,6 +744,10 @@ void SheMov::createMenus(){ sep6->setSeparator(true); mATree->seriesWidget()->seriesTree()->addAction(sep6); mATree->seriesWidget()->seriesTree()->addAction(mAddCoverA); + QAction *sep18 = new QAction(this); + sep18->setSeparator(true); + mATree->seriesWidget()->seriesTree()->addAction(sep18); + mATree->seriesWidget()->seriesTree()->addAction(mToggleFavoriteA); //ArchiveTreeView fileWidget context menu mATree->filesWidget()->filesTree()->addAction(mMoveToBurnA); diff --git a/shemov.h b/shemov.h index cbe1301..9406263 100644 --- a/shemov.h +++ b/shemov.h @@ -70,6 +70,7 @@ class SheMov : public QMainWindow { //Actions QAction *mQuitA; QAction *mMarkFilesA; + QAction *mToggleFavoriteA; QAction *mUnmarkFilesA; QAction *mCreateFolderA; QAction *mDeleteFilesA; diff --git a/smglobals.cpp b/smglobals.cpp index c21cea4..3084bd6 100644 --- a/smglobals.cpp +++ b/smglobals.cpp @@ -57,13 +57,13 @@ SmGlobals *SmGlobals::instance(){ QAbstractItemModel *SmGlobals::model(const QString &which){ if(which == "SeriesModel"){ if(!mModels.contains(which)){ - QStringList headers = QStringList() << tr("Series") << tr("Series ID") << tr("Series part ID") << tr("Part") << tr("Type"); + QStringList headers = QStringList() << tr("Series") << tr("Series ID") << tr("Series part ID") << tr("Part") << tr("Type") << tr("Favorite"); SeriesTreeModel *model = new SeriesTreeModel(headers); mModels.insert(which, model); } }else if(which == "FilesModel"){ if(!mModels.contains(which)){ - QStringList headers = QStringList() << tr("Name") << tr("Part") << tr("Size") << tr("Qual.") << tr("Dvd") << tr("Full Path") << tr("Size (int)") << tr("Type") << tr("Md5 sum") << tr("Series part ID") << tr("File ID") << tr("Seriespart") << tr("Display name") << tr("Dur./Size") << tr("Series name"); + QStringList headers = QStringList() << tr("Name") << tr("Part") << tr("Size") << tr("Qual.") << tr("Dvd") << tr("Full Path") << tr("Size (int)") << tr("Type") << tr("Md5 sum") << tr("Series part ID") << tr("File ID") << tr("Seriespart") << tr("Display name") << tr("Dur./Size") << tr("Series name") << tr("Favorite"); FilesTreeModel *model = new FilesTreeModel(headers); mModels.insert(which, model); } -- cgit v1.2.3-70-g09d2