feat: add initial filtering function

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
This commit is contained in:
Sefa Eyeoglu 2022-10-03 23:07:00 +02:00
parent b6c35491d5
commit b7bda70fb3
No known key found for this signature in database
GPG Key ID: C10411294912A422
6 changed files with 95 additions and 8 deletions

View File

@ -52,7 +52,6 @@
#include <QApplication>
#include <QButtonGroup>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QMainWindow>
#include <QToolBar>
@ -61,11 +60,13 @@
#include <QMenuBar>
#include <QMessageBox>
#include <QInputDialog>
#include <QLineEdit>
#include <QLabel>
#include <QToolButton>
#include <QWidgetAction>
#include <QProgressDialog>
#include <QShortcut>
#include <QVBoxLayout>
#include <BaseInstance.h>
#include <InstanceList.h>
@ -263,7 +264,7 @@ public:
QVector<TranslatedToolButton *> all_toolbuttons;
QWidget *centralWidget = nullptr;
QHBoxLayout *horizontalLayout = nullptr;
QVBoxLayout *verticalLayout = nullptr;
QMenuBar *menuBar = nullptr;
QMenu *fileMenu;
@ -804,11 +805,11 @@ public:
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QStringLiteral("centralWidget"));
horizontalLayout = new QHBoxLayout(centralWidget);
horizontalLayout->setSpacing(0);
horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
horizontalLayout->setSizeConstraint(QLayout::SetDefaultConstraint);
horizontalLayout->setContentsMargins(0, 0, 0, 0);
verticalLayout = new QVBoxLayout(centralWidget);
verticalLayout->setSpacing(0);
verticalLayout->setObjectName(QStringLiteral("horizontalLayout"));
verticalLayout->setSizeConstraint(QLayout::SetDefaultConstraint);
verticalLayout->setContentsMargins(0, 0, 0, 0);
MainWindow->setCentralWidget(centralWidget);
createNewsToolbar(MainWindow);
@ -870,13 +871,21 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow
updateNewsLabel();
}
// Create instance list filter box
{
filterView = new QLineEdit(ui->centralWidget);
ui->verticalLayout->addWidget(filterView);
}
// Create the instance list widget
{
view = new InstanceView(ui->centralWidget, APPLICATION->instances().get());
connect(view, &InstanceView::showContextMenu, this, &MainWindow::showInstanceContextMenu);
connect(filterView, &QLineEdit::textEdited, view, &InstanceView::setFilterQuery);
ui->horizontalLayout->addWidget(view);
ui->verticalLayout->addWidget(view);
}
// The cat background
{

View File

@ -55,6 +55,7 @@ class NewsChecker;
class QToolButton;
class LabeledToolButton;
class QLabel;
class QLineEdit;
class InstanceView;
class MinecraftLauncher;
class BaseProfilerFactory;
@ -220,6 +221,7 @@ private:
// these are managed by Qt's memory management model!
InstanceView *view = nullptr;
QLineEdit *filterView = nullptr;
QToolButton *newsLabel = nullptr;
QMenu *accountMenu = nullptr;
QToolButton *accountMenuButton = nullptr;

View File

@ -20,6 +20,7 @@
#include "InstanceList.h"
#include <QFont>
#include <QRegularExpression>
#include <QVariant>
InstanceTableProxyModel::InstanceTableProxyModel(QObject* parent) : QSortFilterProxyModel(parent)
@ -79,3 +80,58 @@ QVariant InstanceTableProxyModel::data(const QModelIndex& index, int role) const
}
return data;
}
void InstanceTableProxyModel::setFilterQuery(const QString query)
{
QList<InstanceFilterQuery> foo = parseFilterQuery(query);
setFilterQuery(foo);
}
void InstanceTableProxyModel::setFilterQuery(const QList<InstanceFilterQuery> query)
{
m_filter = query;
invalidateFilter();
}
bool InstanceTableProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
{
if (m_filter.isEmpty())
return true;
for (const InstanceFilterQuery& q : m_filter) {
const InstanceList::Column c = q.first;
const QString query = q.second;
QModelIndex index = sourceModel()->index(sourceRow, c, sourceParent);
QString content = sourceModel()->data(index).toString().toLower();
if (!query.isNull() && !content.contains(query))
return false;
}
return true;
}
QList<InstanceFilterQuery> InstanceTableProxyModel::parseFilterQuery(QString query)
{
const QRegularExpression pattern = QRegularExpression("(?:(?<prefix>\\w+):)?(?:(?<content1>\\w+)|\"(?<content2>.+)\")");
QList<InstanceFilterQuery> queries;
QRegularExpressionMatchIterator it = pattern.globalMatch(query);
while (it.hasNext()) {
const QRegularExpressionMatch& match = it.next();
InstanceList::Column c = InstanceList::NameColumn;
QString prefix = match.captured("prefix");
if (prefix.toLower() == "category")
c = InstanceList::CategoryColumn;
else if (prefix.toLower() == "version")
c = InstanceList::GameVersionColumn;
QString content = match.captured("content1");
if (content.isNull())
content = match.captured("content2");
queries << std::make_pair(c, content.toLower());
}
return queries;
}

View File

@ -15,18 +15,29 @@
#pragma once
#include "InstanceList.h"
#include <QCollator>
#include <QSortFilterProxyModel>
typedef std::pair<InstanceList::Column, QString> InstanceFilterQuery;
class InstanceTableProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
InstanceTableProxyModel(QObject* parent = 0);
void setFilterQuery(const QString query);
void setFilterQuery(const QList<InstanceFilterQuery> query);
static QList<InstanceFilterQuery> parseFilterQuery(const QString query);
protected:
QVariant data(const QModelIndex& index, int role) const override;
bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const;
private:
QCollator m_naturalSort;
QList<InstanceFilterQuery> m_filter;
};

View File

@ -221,6 +221,14 @@ QModelIndex InstanceView::mappedIndex(const QModelIndex& index) const
return m_tableProxy->mapToSource(index);
}
void InstanceView::setFilterQuery(const QString& query)
{
if (m_displayMode == DisplayMode::GridMode) {
return m_gridProxy->setFilterQuery(query);
}
return m_tableProxy->setFilterQuery(query);
}
void InstanceView::setCatDisplayed(bool enabled)
{
if (enabled) {

View File

@ -51,6 +51,7 @@ class InstanceView : public QStackedWidget {
void storeState();
void setCatDisplayed(bool enabled);
void setFilterQuery(const QString& query);
void editSelected(InstanceList::Column targetColumn = InstanceList::NameColumn);