summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArno <am@disconnect.de>2014-02-07 06:39:49 +0100
committerArno <am@disconnect.de>2014-02-07 06:39:49 +0100
commit9c85c8e441b5bc6bd9e6441a828599c137ea36be (patch)
treed1e3eaab343aa2d85e9ea05ce49f73ceed8be97d
parent3ac6968ebaf087aeb4bb3deeb1ded2bbbd54dfa5 (diff)
downloadSheMov-9c85c8e441b5bc6bd9e6441a828599c137ea36be.tar.gz
SheMov-9c85c8e441b5bc6bd9e6441a828599c137ea36be.tar.bz2
SheMov-9c85c8e441b5bc6bd9e6441a828599c137ea36be.zip
Implement ArchiveBrowser filtering
Filter ArchiveBrowser by Quality and/or size: * Quality: only show series with a quality less or equal * Size: only show series still fitting onto the DVD * Both: only show series with a quality less or equal _and_ still fitting on the DVD Use QItemSelection instead of going through the selected items in the tree. Seems to work somehow...
-rw-r--r--archivebrowser.cpp75
-rw-r--r--archivebrowser.h15
-rw-r--r--archivebrowsermodel.cpp88
-rw-r--r--archivebrowsermodel.h28
-rw-r--r--smglobals.cpp2
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);
}