diff --git a/app/app.pro b/app/app.pro index b635b690..3bb3aa0d 100644 --- a/app/app.pro +++ b/app/app.pro @@ -43,6 +43,7 @@ SOURCES += \ config/storage.cpp \ config/value.cpp \ directory_ui/directorycontroller.cpp \ + directory_ui/directoryproxyfiltermodel.cpp \ directory_ui/directorysettings.cpp \ feedback_ui/feedbackform.cpp \ ipc/instance.cpp \ @@ -97,6 +98,7 @@ HEADERS += \ config/storage.h \ config/value.h \ directory_ui/directorycontroller.h \ + directory_ui/directoryproxyfiltermodel.h \ directory_ui/directorysettings.h \ feedback_ui/feedbackform.h \ ipc/instance.h \ diff --git a/app/directory_ui/directorycontroller.cpp b/app/directory_ui/directorycontroller.cpp index a821e320..9a6c29ba 100644 --- a/app/directory_ui/directorycontroller.cpp +++ b/app/directory_ui/directorycontroller.cpp @@ -29,6 +29,8 @@ namespace DirectoryUi { restore_scroll_once = true; model = new Model(this); + proxy = new ProxyFilterModel(model, this); + if (local_conf.libraryPaths().empty()) { model->loadAsync(QDir::homePath()); libswitch->addItem(QDir::homePath()); @@ -51,8 +53,8 @@ namespace DirectoryUi { } connect(model, &DirectoryUi::Model::directoryLoaded, [=] { - view->setModel(model); - view->setRootIndex(model->index(model->rootPath())); + view->setModel(proxy); + view->setRootIndex(proxy->mapToSource(model->index(model->rootPath()))); view->setHeaderHidden(true); view->setColumnHidden(1, true); view->setColumnHidden(2, true); @@ -105,7 +107,7 @@ namespace DirectoryUi { if (!index.isValid()) { return; } - auto filepath = model->filePath(index); + auto filepath = model->filePath(proxy->mapToSource(index)); QFileInfo fi(filepath); if (fi.exists() && fi.isFile()) { emit createNewPlaylist({ QDir(filepath) }); @@ -118,7 +120,7 @@ namespace DirectoryUi { if (me->button() == Qt::MidButton) { auto index = view->indexAt(me->pos()); if (index.isValid()) { - auto filepath = QDir(model->filePath(index)); + auto filepath = QDir(model->filePath(proxy->mapToSource(index))); emit createNewPlaylist({filepath}); } } diff --git a/app/directory_ui/directorycontroller.h b/app/directory_ui/directorycontroller.h index 1597b77d..1de86cc8 100644 --- a/app/directory_ui/directorycontroller.h +++ b/app/directory_ui/directorycontroller.h @@ -4,6 +4,7 @@ #include "directorymodel.h" #include "config/local.h" #include "directorycontextmenu.h" +#include "directoryproxyfiltermodel.h" #include "directorysortmenu.h" #include @@ -34,6 +35,7 @@ namespace DirectoryUi { private: QTreeView *view; Model *model; + ProxyFilterModel *proxy; QLineEdit *search; Config::Local &local_conf; bool restore_scroll_once; diff --git a/app/directory_ui/directoryproxyfiltermodel.cpp b/app/directory_ui/directoryproxyfiltermodel.cpp new file mode 100644 index 00000000..d664045d --- /dev/null +++ b/app/directory_ui/directoryproxyfiltermodel.cpp @@ -0,0 +1,44 @@ +#include "directoryproxyfiltermodel.h" + +#include + +namespace DirectoryUi { + ProxyFilterModel::ProxyFilterModel(Model *model, QObject *parent) : QSortFilterProxyModel(parent), source_model(model) { + Q_ASSERT(model); + setSourceModel(model); + setFilterCaseSensitivity(Qt::CaseInsensitive); + } + + int ProxyFilterModel::rowCount(const QModelIndex &parent) const { + Q_UNUSED(parent) + if (sourceModel()) { + return sourceModel()->rowCount(); + } + return 0; + } + + void ProxyFilterModel::filter(const QString &term) { + filter_term = term; + invalidateFilter(); + } + + bool ProxyFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { + Q_UNUSED(source_parent) + if (source_row >= source_model->rowCount()) { + return true; + } + + auto t = source_model->itemAt(source_model->buildIndex(source_row)); + + return (t.artist().contains(filter_term, Qt::CaseInsensitive) || + t.album().contains(filter_term, Qt::CaseInsensitive) || + t.filename().contains(filter_term, Qt::CaseInsensitive) || + t.title().contains(filter_term, Qt::CaseInsensitive)); + } + + bool ProxyFilterModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const { + Q_UNUSED(source_parent) + Q_UNUSED(source_column) + return true; + } +} diff --git a/app/directory_ui/directoryproxyfiltermodel.h b/app/directory_ui/directoryproxyfiltermodel.h new file mode 100644 index 00000000..1ec08fb9 --- /dev/null +++ b/app/directory_ui/directoryproxyfiltermodel.h @@ -0,0 +1,30 @@ +#ifndef DIRECTORYPROXYFILTERMODEL_H +#define DIRECTORYPROXYFILTERMODEL_H + +#include "directory_ui/directorymodel.h" + +#include +#include + +namespace DirectoryUi { + class ProxyFilterModel : public QSortFilterProxyModel { + Q_OBJECT + public: + explicit ProxyFilterModel(Model *model, QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + public slots: + void filter(const QString &term); + + protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; + bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const override; + + private: + Model *source_model; + QString filter_term; + }; +} + +#endif // DIRECTORYPROXYFILTERMODEL_H