diff --git a/CHANGELOG.md b/CHANGELOG.md
index 722f546c8..b3d4c4515 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,6 +28,7 @@
Bug #5441: Enemies can't push a player character when in critical strike stance
Bug #5451: Magic projectiles don't disappear with the caster
Bug #5452: Autowalk is being included in savegames
+ Feature #5297: Add a search function to the "Datafiles" tab of the OpenMW launcher
Feature #5362: Show the soul gems' trapped soul in count dialog
Feature #5445: Handle NiLines
diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp
index 57f1fdcf3..6bb8e6e2c 100644
--- a/components/contentselector/view/contentselector.cpp
+++ b/components/contentselector/view/contentselector.cpp
@@ -40,16 +40,37 @@ void ContentSelectorView::ContentSelector::buildGameFileView()
ui.gameFileView->setCurrentIndex(0);
}
+class AddOnProxyModel : public QSortFilterProxyModel
+{
+public:
+ explicit AddOnProxyModel(QObject* parent = nullptr) :
+ QSortFilterProxyModel(parent)
+ {}
+
+ bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override
+ {
+ static const QString ContentTypeAddon = QString::number((int)ContentSelectorModel::ContentType_Addon);
+
+ QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent);
+ const QString userRole = sourceModel()->data(nameIndex, Qt::UserRole).toString();
+
+ return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent) && userRole == ContentTypeAddon;
+ }
+};
+
void ContentSelectorView::ContentSelector::buildAddonView()
{
ui.addonView->setVisible (true);
- mAddonProxyModel = new QSortFilterProxyModel(this);
- mAddonProxyModel->setFilterRegExp (QString::number((int)ContentSelectorModel::ContentType_Addon));
- mAddonProxyModel->setFilterRole (Qt::UserRole);
+ mAddonProxyModel = new AddOnProxyModel(this);
+ mAddonProxyModel->setFilterRegExp(searchFilter()->text());
+ mAddonProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
mAddonProxyModel->setDynamicSortFilter (true);
mAddonProxyModel->setSourceModel (mContentModel);
+ connect(ui.searchFilter, SIGNAL(textEdited(QString)), mAddonProxyModel, SLOT(setFilterWildcard(QString)));
+ connect(ui.searchFilter, SIGNAL(textEdited(QString)), this, SLOT(slotSearchFilterTextChanged(QString)));
+
ui.addonView->setModel(mAddonProxyModel);
connect(ui.addonView, SIGNAL(activated(const QModelIndex&)), this, SLOT(slotAddonTableItemActivated(const QModelIndex&)));
@@ -261,3 +282,8 @@ void ContentSelectorView::ContentSelector::slotCopySelectedItemsPaths()
clipboard->setText(filepaths);
}
}
+
+void ContentSelectorView::ContentSelector::slotSearchFilterTextChanged(const QString& newText)
+{
+ ui.addonView->setDragEnabled(newText.isEmpty());
+}
diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp
index 9c34e24fd..f1058d510 100644
--- a/components/contentselector/view/contentselector.hpp
+++ b/components/contentselector/view/contentselector.hpp
@@ -48,6 +48,9 @@ namespace ContentSelectorView
QToolButton *refreshButton() const
{ return ui.refreshButton; }
+ QLineEdit *searchFilter() const
+ { return ui.searchFilter; }
+
private:
@@ -74,6 +77,7 @@ namespace ContentSelectorView
void slotCheckMultiSelectedItems();
void slotUncheckMultiSelectedItems();
void slotCopySelectedItemsPaths();
+ void slotSearchFilterTextChanged(const QString& newText);
};
}
diff --git a/files/ui/contentselector.ui b/files/ui/contentselector.ui
index d13cb314e..c099649b3 100644
--- a/files/ui/contentselector.ui
+++ b/files/ui/contentselector.ui
@@ -66,6 +66,9 @@
+ -
+
+
-