diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-06-25 16:41:32 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-07-02 10:10:19 -0400 |
| commit | 19a19ead4059c600680d6e7ac193490e32e03245 (patch) | |
| tree | 3d19e3d8aa6f92207344a24a470bffb83ffde67d /src | |
| parent | 00d4921e47e5eef08b10dac127795ecc8ccf84ae (diff) | |
filterwidget now support automatically installing a proxy on lists
filters on txt and ini tabs
Diffstat (limited to 'src')
| -rw-r--r-- | src/filterwidget.cpp | 70 | ||||
| -rw-r--r-- | src/filterwidget.h | 41 | ||||
| -rw-r--r-- | src/modinfodialog.ui | 8 | ||||
| -rw-r--r-- | src/modinfodialogconflicts.cpp | 4 | ||||
| -rw-r--r-- | src/modinfodialogtextfiles.cpp | 13 | ||||
| -rw-r--r-- | src/modinfodialogtextfiles.h | 4 |
6 files changed, 123 insertions, 17 deletions
diff --git a/src/filterwidget.cpp b/src/filterwidget.cpp index 82644658..1b9efd7c 100644 --- a/src/filterwidget.cpp +++ b/src/filterwidget.cpp @@ -1,12 +1,41 @@ #include "filterwidget.h" #include "eventfilter.h" -FilterWidget::FilterWidget() - : m_edit(nullptr), m_eventFilter(nullptr), m_clear(nullptr) +FilterWidgetProxyModel::FilterWidgetProxyModel(FilterWidget& fw, QWidget* parent) + : QSortFilterProxyModel(parent), m_filter(fw) { + connect(&fw, &FilterWidget::changed, [&]{ invalidateFilter(); }); } -void FilterWidget::set(QLineEdit* edit) +bool FilterWidgetProxyModel::filterAcceptsRow( + int sourceRow, const QModelIndex& sourceParent) const +{ + const auto cols = sourceModel()->columnCount(); + + const auto m = m_filter.matches([&](auto&& what) { + for (int c=0; c<cols; ++c) { + QModelIndex index = sourceModel()->index(sourceRow, c, sourceParent); + const auto text = sourceModel()->data(index, Qt::DisplayRole).toString(); + + if (text.contains(what, Qt::CaseInsensitive)) { + return true; + } + } + + return false; + }); + + return m; +} + + +FilterWidget::FilterWidget() : + m_edit(nullptr), m_list(nullptr), m_proxy(nullptr), + m_eventFilter(nullptr), m_clear(nullptr) +{ +} + +void FilterWidget::setEdit(QLineEdit* edit) { unhook(); @@ -16,11 +45,22 @@ void FilterWidget::set(QLineEdit* edit) return; } + m_edit->setPlaceholderText(QObject::tr("Filter")); + createClear(); hookEvents(); clear(); } +void FilterWidget::setList(QAbstractItemView* list) +{ + m_list = list; + + m_proxy = new FilterWidgetProxyModel(*this); + m_proxy->setSourceModel(m_list->model()); + m_list->setModel(m_proxy); +} + void FilterWidget::clear() { if (!m_edit) { @@ -30,6 +70,16 @@ void FilterWidget::clear() m_edit->clear(); } +QModelIndex FilterWidget::map(const QModelIndex& index) +{ + if (m_proxy) { + return m_proxy->mapToSource(index); + } else { + qCritical() << "FilterWidget::map() called, but proxy isn't set up"; + return index; + } +} + void FilterWidget::compile() { m_compiled.clear(); @@ -83,6 +133,14 @@ void FilterWidget::unhook() if (m_edit) { m_edit->removeEventFilter(m_eventFilter); } + + if (m_proxy && m_list) { + auto* model = m_proxy->sourceModel(); + m_proxy->setSourceModel(nullptr); + delete m_proxy; + + m_list->setModel(model); + } } void FilterWidget::createClear() @@ -125,9 +183,11 @@ void FilterWidget::onTextChanged() m_text = text; compile(); - if (changed) { - changed(); + if (m_proxy) { + m_proxy->invalidateFilter(); } + + emit changed(); } } diff --git a/src/filterwidget.h b/src/filterwidget.h index 762d9b15..5b08c3ae 100644 --- a/src/filterwidget.h +++ b/src/filterwidget.h @@ -1,22 +1,55 @@ #ifndef FILTERWIDGET_H #define FILTERWIDGET_H +#include <QObject> +#include <QLineEdit> +#include <QToolButton> +#include <QList> +#include <QAbstractItemView> + class EventFilter; +class FilterWidget; -class FilterWidget +class FilterWidgetProxyModel : public QSortFilterProxyModel { + Q_OBJECT; + public: - std::function<void ()> changed; + FilterWidgetProxyModel(FilterWidget& fw, QWidget* parent=nullptr); + using QSortFilterProxyModel::invalidateFilter; + +protected: + bool filterAcceptsRow(int row, const QModelIndex& parent) const override; + +private: + FilterWidget& m_filter; +}; + + +class FilterWidget : public QObject +{ + Q_OBJECT; + +public: + using predFun = std::function<bool (const QString& what)>; FilterWidget(); - void set(QLineEdit* edit); + void setEdit(QLineEdit* edit); + void setList(QAbstractItemView* list); void clear(); - bool matches(std::function<bool (const QString& what)> pred) const; + QModelIndex map(const QModelIndex& index); + + bool matches(predFun pred) const; + +signals: + void changed(); private: QLineEdit* m_edit; + QAbstractItemView* m_list; + FilterWidgetProxyModel* m_proxy; EventFilter* m_eventFilter; QToolButton* m_clear; QString m_text; diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 9f4ae873..69e73da4 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -72,6 +72,9 @@ </property>
</widget>
</item>
+ <item>
+ <widget class="QLineEdit" name="textFileFilter"/>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="widget_7" native="true">
@@ -108,7 +111,7 @@ <enum>Qt::Horizontal</enum>
</property>
<widget class="QWidget" name="layoutWidget">
- <layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0">
+ <layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0,0">
<property name="spacing">
<number>6</number>
</property>
@@ -132,6 +135,9 @@ </property>
</widget>
</item>
+ <item>
+ <widget class="QLineEdit" name="iniFileFilter"/>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget1">
diff --git a/src/modinfodialogconflicts.cpp b/src/modinfodialogconflicts.cpp index c053e64c..e631db30 100644 --- a/src/modinfodialogconflicts.cpp +++ b/src/modinfodialogconflicts.cpp @@ -999,8 +999,8 @@ AdvancedConflictsTab::AdvancedConflictsTab( ui->conflictsAdvancedList, &QTreeView::customContextMenuRequested, [&](const QPoint& p){ m_tab->showContextMenu(p, ui->conflictsAdvancedList); }); - m_filter.set(ui->conflictsAdvancedFilter); - m_filter.changed = [&]{ update(); }; + m_filter.setEdit(ui->conflictsAdvancedFilter); + QObject::connect(&m_filter, &FilterWidget::changed, [&]{ update(); }); } void AdvancedConflictsTab::clear() diff --git a/src/modinfodialogtextfiles.cpp b/src/modinfodialogtextfiles.cpp index 675a4c79..2b5ab489 100644 --- a/src/modinfodialogtextfiles.cpp +++ b/src/modinfodialogtextfiles.cpp @@ -100,7 +100,7 @@ private: GenericFilesTab::GenericFilesTab( OrganizerCore& oc, PluginContainer& plugin, QWidget* parent, Ui::ModInfoDialog* ui, int id, - QListView* list, QSplitter* sp, TextEditor* e) : + QListView* list, QSplitter* sp, TextEditor* e, QLineEdit* filter) : ModInfoDialogTab(oc, plugin, parent, ui, id), m_list(list), m_editor(e), m_model(new FileListModel) { @@ -111,6 +111,9 @@ GenericFilesTab::GenericFilesTab( sp->setStretchFactor(0, 0); sp->setStretchFactor(1, 1); + m_filter.setEdit(filter); + m_filter.setList(m_list); + QObject::connect( m_list->selectionModel(), &QItemSelectionModel::currentRowChanged, [&](auto current, auto previous){ onSelection(current, previous); }); @@ -187,7 +190,7 @@ void GenericFilesTab::select(const QModelIndex& index) } m_editor->setEnabled(true); - m_editor->load(m_model->fullPath(index)); + m_editor->load(m_model->fullPath(m_filter.map(index))); } @@ -196,7 +199,8 @@ TextFilesTab::TextFilesTab( QWidget* parent, Ui::ModInfoDialog* ui, int id) : GenericFilesTab( oc, plugin, parent, ui, id, - ui->textFileList, ui->tabTextSplitter, ui->textFileEditor) + ui->textFileList, ui->tabTextSplitter, + ui->textFileEditor, ui->textFileFilter) { } @@ -218,7 +222,8 @@ IniFilesTab::IniFilesTab( QWidget* parent, Ui::ModInfoDialog* ui, int id) : GenericFilesTab( oc, plugin, parent, ui, id, - ui->iniFileList, ui->tabIniSplitter, ui->iniFileEditor) + ui->iniFileList, ui->tabIniSplitter, + ui->iniFileEditor, ui->iniFileFilter) { } diff --git a/src/modinfodialogtextfiles.h b/src/modinfodialogtextfiles.h index d879c2bd..037c6bb3 100644 --- a/src/modinfodialogtextfiles.h +++ b/src/modinfodialogtextfiles.h @@ -2,6 +2,7 @@ #define MODINFODIALOGTEXTFILES_H #include "modinfodialogtab.h" +#include "filterwidget.h" #include <QSplitter> #include <QListView> @@ -23,11 +24,12 @@ protected: QListView* m_list; TextEditor* m_editor; FileListModel* m_model; + FilterWidget m_filter; GenericFilesTab( OrganizerCore& oc, PluginContainer& plugin, QWidget* parent, Ui::ModInfoDialog* ui, int id, - QListView* list, QSplitter* splitter, TextEditor* editor); + QListView* list, QSplitter* splitter, TextEditor* editor, QLineEdit* filter); virtual bool wantsFile(const QString& rootPath, const QString& fullPath) const = 0; |
