diff options
-rw-r--r-- | archivebrowser.cpp | 75 | ||||
-rw-r--r-- | archivebrowser.h | 15 | ||||
-rw-r--r-- | archivebrowsermodel.cpp | 88 | ||||
-rw-r--r-- | archivebrowsermodel.h | 28 | ||||
-rw-r--r-- | smglobals.cpp | 2 |
5 files changed, 187 insertions, 21 deletions
diff --git a/archivebrowser.cpp b/archivebrowser.cpp index c39805b..e6a1efb 100644 --- a/archivebrowser.cpp +++ b/archivebrowser.cpp @@ -6,6 +6,10 @@ */ #include <QVBoxLayout> +#include <QHBoxLayout> +#include <QLabel> +#include <QComboBox> +#include <QCheckBox> #include <QSortFilterProxyModel> #include "archivebrowser.h" @@ -14,39 +18,84 @@ #include "smglobals.h" #include "delegates.h" -ArchiveBrowser::ArchiveBrowser(QWidget *parent) : QWidget(parent){ +ArchiveBrowser::ArchiveBrowser(QWidget *parent) : QWidget(parent), mSelectedSize(0), mSelectedItems(0){ //prep mModel = static_cast<ArchiveBrowserModel*>(SmGlobals::instance()->model("BrowserModel")); - mProxy = new QSortFilterProxyModel; + mProxy = new ArchiveBrowserModelProxy; mProxy->setSourceModel(mModel); mTree = new SmTreeView; mTree->setModel(mProxy); mTree->setColumnHidden(ArchiveBrowserModel::GenericId, true); mTree->setColumnHidden(ArchiveBrowserModel::NodeType, true); - mTree->setSortingEnabled(true); + mTree->setItemDelegateForColumn(ArchiveBrowserModel::TotalSize, new SizeDelegate(this)); mTree->setItemDelegateForColumn(ArchiveBrowserModel::FileType, new FileTypeDelegate(this)); mTree->setSelectionMode(QAbstractItemView::ExtendedSelection); + //filters + QHBoxLayout *filterLayout = new QHBoxLayout; + mQualityFilter = new QComboBox; + QLabel *filterL = new QLabel(tr("Filters:")); + QLabel *qualityL = new QLabel(tr("Quality")); + filterLayout->addWidget(filterL); + filterLayout->addWidget(qualityL); + setupQualityFilter(); + connect(mQualityFilter, SIGNAL(currentIndexChanged(QString)), mProxy, SLOT(setQualityFilter(QString))); + filterLayout->addWidget(mQualityFilter); + mSizeFilter = new QCheckBox(tr("Size Filter")); + connect(mSizeFilter, SIGNAL(stateChanged(int)), mProxy, SLOT(setSizeFilter(int))); + filterLayout->addWidget(mSizeFilter); + filterLayout->addStretch(); + //connect connect(mTree->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(browserSelectionChanged(QItemSelection,QItemSelection))); //make widget QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addLayout(filterLayout); mainLayout->addWidget(mTree); setLayout(mainLayout); + mTree->setSortingEnabled(true); } void ArchiveBrowser::browserSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { - Q_UNUSED(selected); - Q_UNUSED(deselected); - QModelIndexList sel = mTree->selectionModel()->selectedRows(); - qint64 size = 0; - int selItems = 0; - foreach(QModelIndex idx, sel){ - size += idx.data(ArchiveBrowserModel::TotalSizeRole).toDouble(); - ++selItems; + QModelIndexList selectedIdx = selectedRows(selected); + QModelIndexList deselectedIdx = selectedRows(deselected); + foreach(QModelIndex sel, selectedIdx){ + mSelectedSize += sel.data(ArchiveBrowserModel::TotalSizeRole).toDouble(); + ++mSelectedItems; + mModel->setData(sel, true, ArchiveBrowserModel::SelectedRole); + } + foreach(QModelIndex desel, deselectedIdx){ + mSelectedSize -= desel.data(ArchiveBrowserModel::TotalSizeRole).toDouble(); + --mSelectedItems; + mModel->setData(desel, false, ArchiveBrowserModel::SelectedRole); + } + emit sizeChanged(mSelectedSize); + emit itemCountChanged(mSelectedItems); + qint64 remaining = Q_INT64_C(1024 * 1024 * 1024 * 4) - mSelectedSize; + mProxy->setBytesRemaining(remaining); +} + +void ArchiveBrowser::setupQualityFilter(){ + mQualityFilter->clear(); + QList<int> qualities = mModel->availableQualities(); + qSort(qualities); + QStringList qualityList = QStringList() << tr("(none)"); + foreach(int q, qualities){ + qualityList << QString::number(q); + } + mQualityFilter->addItems(qualityList); +} + +QModelIndexList ArchiveBrowser::selectedRows(const QItemSelection &sel){ + QModelIndexList retval; + QModelIndexList selIdx = sel.indexes(); + foreach(QModelIndex idx, selIdx){ + QModelIndex real = mProxy->mapToSource(idx); + if(real.column() == 0){ + retval << real; + } } - emit sizeChanged(size); - emit itemCountChanged(selItems); + return retval; } diff --git a/archivebrowser.h b/archivebrowser.h index 78bec23..6986b84 100644 --- a/archivebrowser.h +++ b/archivebrowser.h @@ -9,12 +9,17 @@ #define ARCHIVEBROWSER_H #include <QWidget> +#include <QModelIndexList> +#include <QItemSelection> #include "smtreeview.h" class ArchiveBrowserModel; +class ArchiveBrowserModelProxy; class SmTreeView; class QSortFilterProxyModel; +class QComboBox; +class QCheckBox; class ArchiveBrowser : public QWidget { Q_OBJECT @@ -24,14 +29,22 @@ class ArchiveBrowser : public QWidget { public slots: void browserSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + private slots: + void setupQualityFilter(); + signals: void sizeChanged(qint64 size); void itemCountChanged(int items); private: + QModelIndexList selectedRows(const QItemSelection &sel); SmTreeView *mTree; + QComboBox *mQualityFilter; + QCheckBox *mSizeFilter; ArchiveBrowserModel *mModel; - QSortFilterProxyModel *mProxy; + ArchiveBrowserModelProxy *mProxy; + qint64 mSelectedSize; + int mSelectedItems; }; #endif // ARCHIVEBROWSER_H diff --git a/archivebrowsermodel.cpp b/archivebrowsermodel.cpp index 26dc438..222a243 100644 --- a/archivebrowsermodel.cpp +++ b/archivebrowsermodel.cpp @@ -7,12 +7,13 @@ #include <QSqlDatabase> #include <QSqlQuery> +#include <QItemSelectionModel> #include "archivebrowsermodel.h" #include "smtreeitem.h" #include "helper.h" -ArchiveBrowserModel::ArchiveBrowserModel(const QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mNumFields(7) { +ArchiveBrowserModel::ArchiveBrowserModel(const QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mNumFields(8) { mDb = QSqlDatabase::database("treedb"); populate(); } @@ -44,6 +45,9 @@ QVariant ArchiveBrowserModel::data(const QModelIndex &index, int role) const { if(role == FullPathRole){ return item->data(FullPath); } + if(role == SelectedRole){ + return item->data(Selected); + } if(role == Qt::ForegroundRole){ if(col == TotalSize){ qint64 s = item->data(TotalSize).toDouble(); @@ -74,6 +78,16 @@ QVariant ArchiveBrowserModel::data(const QModelIndex &index, int role) const { return SmTreeModel::data(index, role); } +bool ArchiveBrowserModel::setData(const QModelIndex &index, const QVariant &value, int role){ + if(role == SelectedRole){ + SmTreeItem *item = itemAt(index); + item->setData(Selected, value); + emit dataChanged(index, index); + return true; + } + return SmTreeModel::setData(index, value, role); +} + Qt::ItemFlags ArchiveBrowserModel::flags(const QModelIndex &index) const{ SmTreeItem *item = itemAt(index); int nt = item->data(NodeType).toInt(); @@ -85,6 +99,7 @@ Qt::ItemFlags ArchiveBrowserModel::flags(const QModelIndex &index) const{ void ArchiveBrowserModel::populate(){ SmTreeItem *rootItem = new SmTreeItem(mNumFields); + mAvailableQualities.clear(); QSqlQuery localFilesQ(mDb); localFilesQ.prepare("SELECT tfilename, bisize, sifiletype, siquality, cmd5sum FROM files WHERE iseriespart_id = :sid ORDER BY sifiletype"); QSqlQuery localQ = QSqlQuery("SELECT DISTINCT(series.iseries_id), tseries_name, seriesparts.iseriespart, seriesparts.tsubtitle, seriesparts.iseriesparts_id FROM series LEFT JOIN seriesparts ON series.iseries_id = seriesparts.iseries_id LEFT JOIN files ON seriesparts.iseriesparts_id = files.iseriespart_id WHERE files.sifiletype = 1 AND files.idvd < 1 ORDER BY tseries_name ASC", mDb); @@ -96,7 +111,7 @@ void ArchiveBrowserModel::populate(){ }else{ name = QString("%1 - %2").arg(localQ.value(1).toString()).arg(localQ.value(3).toString()); } - serPartData << name << localQ.value(4) << SeriesPartNode << QVariant() << QVariant() << QVariant() << QString(); + serPartData << name << localQ.value(4) << SeriesPartNode << QVariant() << QVariant() << QVariant() << QString() << false; SmTreeItem *seriesItem = new SmTreeItem(serPartData, rootItem); rootItem->appendChild(seriesItem); localFilesQ.bindValue(":sid", localQ.value(4)); @@ -105,10 +120,14 @@ void ArchiveBrowserModel::populate(){ int quality = -1; while(localFilesQ.next()){ QList<QVariant> fileData; - fileData << localFilesQ.value(0) << QVariant() << FileNode << localFilesQ.value(1) << localFilesQ.value(3) << localFilesQ.value(2) << Helper::createArchivePath(localFilesQ.value(0).toString(), localFilesQ.value(4).toString()); + fileData << localFilesQ.value(0) << QVariant() << FileNode << localFilesQ.value(1) << localFilesQ.value(3) << localFilesQ.value(2) << Helper::createArchivePath(localFilesQ.value(0).toString(), localFilesQ.value(4).toString()) << false; totalSize += localFilesQ.value(1).toDouble(); if(localFilesQ.value(2) == 1){ //this is a movie file, no need for another enum - quality = localFilesQ.value(3).toInt(); + int q = localFilesQ.value(3).toInt(); + quality = q; + if(!mAvailableQualities.contains(q)){ + mAvailableQualities << q; + } } SmTreeItem *fileItem = new SmTreeItem(fileData, seriesItem); seriesItem->appendChild(fileItem); @@ -118,3 +137,64 @@ void ArchiveBrowserModel::populate(){ } setRoot(rootItem); } + +//ArchiveBrowserModelProxy + +ArchiveBrowserModelProxy::ArchiveBrowserModelProxy(QObject *parent) : QSortFilterProxyModel(parent), mQuality(-1), mSizeFilter(false) {} + +void ArchiveBrowserModelProxy::setQualityFilter(QString quality){ + if(quality == tr("(none)")){ + mQuality = -1; + }else{ + mQuality = quality.toInt(); + } + invalidateFilter(); +} + +void ArchiveBrowserModelProxy::setSizeFilter(int activate){ + mSizeFilter = activate; + invalidateFilter(); +} + +void ArchiveBrowserModelProxy::setBytesRemaining(qint64 bytes){ + mBytesRemaining = bytes > 0 ? bytes : 0; + invalidateFilter(); +} + +bool ArchiveBrowserModelProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + if(mQuality == -1 && !mSizeFilter){ + return true; + } + QModelIndex selIdx = sourceModel()->index(sourceRow, ArchiveBrowserModel::Selected, sourceParent); + if(selIdx.data().toBool()){ + return true; + } + QModelIndex nodeIdx = sourceModel()->index(sourceRow, ArchiveBrowserModel::NodeType, sourceParent); + int nodeType = nodeIdx.data().toInt(); + if(nodeType == ArchiveBrowserModel::FileNode){ + return true; + } + QModelIndex qualIdx = sourceModel()->index(sourceRow, ArchiveBrowserModel::Quality, sourceParent); + int quality = qualIdx.data().toInt(); + QModelIndex sizeIdx = sourceModel()->index(sourceRow, ArchiveBrowserModel::TotalSize, sourceParent); + qint64 size = sizeIdx.data().toDouble(); + if(mQuality > -1 && mSizeFilter){ + if(quality <= mQuality && size <= mBytesRemaining){ + return true; + } + return false; + } + if(mQuality > -1){ + if(quality <= mQuality){ + return true; + } + return false; + } + if(mSizeFilter){ + if(size <= mBytesRemaining){ + return true; + } + return false; + } + return false; +} diff --git a/archivebrowsermodel.h b/archivebrowsermodel.h index 3b7fc14..46a8102 100644 --- a/archivebrowsermodel.h +++ b/archivebrowsermodel.h @@ -9,23 +9,47 @@ #define ARCHIVEBROWSERMODEL_H #include <QSqlDatabase> +#include <QSortFilterProxyModel> +#include <QList> #include "smtreemodel.h" class ArchiveBrowserModel : public SmTreeModel { Q_OBJECT public: - enum CustomRoles { NameRole = Qt::UserRole + 1, GenericIdRole = Qt::UserRole + 2, NodeTypeRole = Qt::UserRole + 3, TotalSizeRole = Qt::UserRole + 4, QualityRole = 5, FileTypeRole = Qt::UserRole + 6, FullPathRole = Qt::UserRole + 7 }; - enum Fields { Name = 0, GenericId = 1, NodeType = 2, TotalSize = 3, Quality = 4, FileType = 5, FullPath = 6 }; + enum CustomRoles { NameRole = Qt::UserRole + 1, GenericIdRole = Qt::UserRole + 2, NodeTypeRole = Qt::UserRole + 3, TotalSizeRole = Qt::UserRole + 4, QualityRole = 5, FileTypeRole = Qt::UserRole + 6, FullPathRole = Qt::UserRole + 7, SelectedRole = Qt::UserRole + 8 }; + enum Fields { Name = 0, GenericId = 1, NodeType = 2, TotalSize = 3, Quality = 4, FileType = 5, FullPath = 6, Selected = 7 }; enum NodeTypes { SeriesPartNode = 1, FileNode = 2 }; explicit ArchiveBrowserModel(const QStringList &headers, QObject *parent = 0); virtual QVariant data(const QModelIndex &index, int role) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role); virtual Qt::ItemFlags flags(const QModelIndex &index) const; + QList<int> availableQualities() { return mAvailableQualities; } private: void populate(); int mNumFields; + QList<int> mAvailableQualities; QSqlDatabase mDb; }; +class ArchiveBrowserModelProxy : public QSortFilterProxyModel { + Q_OBJECT + public: + explicit ArchiveBrowserModelProxy(QObject *parent = 0); + + public slots: + void setQualityFilter(QString quality); + void setSizeFilter(int activate); + void setBytesRemaining(qint64 bytes); + + protected: + virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; + + private: + int mQuality; + bool mSizeFilter; + qint64 mBytesRemaining; +}; + #endif // ARCHIVEBROWSERMODEL_H diff --git a/smglobals.cpp b/smglobals.cpp index 58c6d98..b82ba3c 100644 --- a/smglobals.cpp +++ b/smglobals.cpp @@ -97,7 +97,7 @@ QAbstractItemModel *SmGlobals::model(const QString &which){ ArchiveModel *model = new ArchiveModel(headers); mModels.insert(which, model); }else if(which == "BrowserModel"){ - QStringList headers = QStringList() << tr("Name") << tr("Generic Id") << tr("Node Type") << tr("Size") << tr("Quality") << tr("File Type") << tr("Full Path"); + QStringList headers = QStringList() << tr("Name") << tr("Generic Id") << tr("Node Type") << tr("Size") << tr("Quality") << tr("File Type") << tr("Full Path") << tr("Selected"); ArchiveBrowserModel *model = new ArchiveBrowserModel(headers); mModels.insert(which, model); } |