summaryrefslogtreecommitdiff
path: root/view
diff options
context:
space:
mode:
authorJosh Ferrell <josh@vector35.com>2026-01-26 14:23:12 -0500
committerJosh Ferrell <josh@vector35.com>2026-02-06 17:53:45 -0500
commit70bbb18a9444824a8ec2b9a7ff57fc848e017b6e (patch)
treefe87c0976b75a7557986d1ac6bcc2409a839624c /view
parent9b7604d13e8bd98c6998facb9326926ed96281b5 (diff)
Add regex and case sensitivity options to FilterEdit
Diffstat (limited to 'view')
-rw-r--r--view/kernelcache/ui/kctriage.cpp8
-rw-r--r--view/kernelcache/ui/kctriage.h15
-rw-r--r--view/kernelcache/ui/symboltable.cpp40
-rw-r--r--view/kernelcache/ui/symboltable.h5
-rw-r--r--view/sharedcache/ui/dsctriage.cpp16
-rw-r--r--view/sharedcache/ui/dsctriage.h13
-rw-r--r--view/sharedcache/ui/symboltable.cpp39
-rw-r--r--view/sharedcache/ui/symboltable.h5
8 files changed, 102 insertions, 39 deletions
diff --git a/view/kernelcache/ui/kctriage.cpp b/view/kernelcache/ui/kctriage.cpp
index 6dd13067..e13ebdcf 100644
--- a/view/kernelcache/ui/kctriage.cpp
+++ b/view/kernelcache/ui/kctriage.cpp
@@ -256,8 +256,8 @@ QWidget* KCTriageView::initImageTable()
auto loadImageFilterEdit = new FilterEdit(m_imageTable);
loadImageFilterEdit->setPlaceholderText("Filter images");
- connect(loadImageFilterEdit, &FilterEdit::textChanged, [this](const QString& filter) {
- m_imageTable->setFilter(filter.toStdString());
+ connect(loadImageFilterEdit, &FilterEdit::textChanged, [this, loadImageFilterEdit](const QString& filter) {
+ m_imageTable->setFilter(filter.toStdString(), loadImageFilterEdit->getFilterOptions());
});
connect(m_imageTable, &FilterableTableView::activated, this, [=, this](const QModelIndex& index) {
@@ -310,8 +310,8 @@ void KCTriageView::initSymbolTable()
auto symbolFilterEdit = new FilterEdit(m_symbolTable);
symbolFilterEdit->setPlaceholderText("Filter symbols");
- connect(symbolFilterEdit, &FilterEdit::textChanged, [this](const QString& filter) {
- m_symbolTable->setFilter(filter.toStdString());
+ connect(symbolFilterEdit, &FilterEdit::textChanged, [this, symbolFilterEdit](const QString& filter) {
+ m_symbolTable->setFilter(filter.toStdString(), symbolFilterEdit->getFilterOptions());
});
auto loadSymbolImageButton = new QPushButton();
diff --git a/view/kernelcache/ui/kctriage.h b/view/kernelcache/ui/kctriage.h
index c69c6a0a..f73fd264 100644
--- a/view/kernelcache/ui/kctriage.h
+++ b/view/kernelcache/ui/kctriage.h
@@ -102,7 +102,9 @@ public:
class FilterableTableView : public QTableView, public FilterTarget {
Q_OBJECT
+ std::string m_filter;
bool m_filterByHiding;
+ FilterOptions m_filterOptions;
public:
explicit FilterableTableView(QWidget* parent = nullptr, bool filterByHiding = true)
@@ -113,19 +115,24 @@ public:
~FilterableTableView() override = default;
- void setFilter(const std::string& filter) override {
+ void setFilter(const std::string& filter, FilterOptions options) override {
+ m_filter = filter;
+ m_filterOptions = options;
+ QString qFilter = QString::fromStdString(m_filter);
+
if (!m_filterByHiding)
{
- emit filterTextChanged(QString::fromStdString(filter));
+ emit filterTextChanged(qFilter);
return;
}
- QString qFilter = QString::fromStdString(filter);
+
+ bool caseSensitive = options.testFlag(CaseSensitiveOption);
for (int row = 0; row < model()->rowCount(); ++row) {
bool match = false;
for (int col = 0; col < model()->columnCount(); ++col) {
QModelIndex index = model()->index(row, col);
QString data = model()->data(index).toString();
- if (data.contains(qFilter, Qt::CaseInsensitive)) {
+ if (data.contains(qFilter, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive)) {
match = true;
break;
}
diff --git a/view/kernelcache/ui/symboltable.cpp b/view/kernelcache/ui/symboltable.cpp
index 90d0d18b..c3c45b8a 100644
--- a/view/kernelcache/ui/symboltable.cpp
+++ b/view/kernelcache/ui/symboltable.cpp
@@ -128,7 +128,7 @@ void SymbolTableModel::sort(int column, Qt::SortOrder order)
void SymbolTableModel::updateSymbols(std::vector<CacheSymbol>&& symbols)
{
m_preparedSymbols = symbols;
- setFilter(m_filter);
+ setFilter(m_filter, m_filterOptions);
}
@@ -138,20 +138,42 @@ const CacheSymbol& SymbolTableModel::symbolAt(int row) const
}
-void SymbolTableModel::setFilter(std::string text)
+void SymbolTableModel::setFilter(const std::string& text, FilterOptions options)
{
- beginResetModel();
-
m_filter = text;
+ m_filterOptions = options;
m_modelSymbols = {};
+ bool caseSensitive = options.testFlag(CaseSensitiveOption);
+ beginResetModel();
// Skip filtering if no filter applied.
if (!m_filter.empty())
{
m_modelSymbols.reserve(m_preparedSymbols.size());
for (const auto& symbol : m_preparedSymbols)
- if (((std::string_view)symbol.name).find(m_filter) != std::string::npos)
+ {
+ const std::string& symbolName = symbol.name;
+ bool match;
+ if (caseSensitive)
+ {
+ match = (symbolName.find(m_filter) != std::string::npos);
+ }
+ else
+ {
+ auto it = std::search(
+ symbolName.begin(), symbolName.end(),
+ m_filter.begin(), m_filter.end(),
+ [](char c1, char c2) { return std::tolower(c1) == std::tolower(c2); }
+ );
+
+ match = (it != symbolName.end());
+ }
+
+ if (match)
+ {
m_modelSymbols.push_back(symbol);
+ }
+ }
m_modelSymbols.shrink_to_fit();
}
else
@@ -163,6 +185,8 @@ void SymbolTableModel::setFilter(std::string text)
}
+
+
SymbolTableView::SymbolTableView(QWidget* parent)
: QTableView(parent), m_model(new SymbolTableModel(this)) {
@@ -215,6 +239,8 @@ void SymbolTableView::populateSymbols(BinaryView &view)
}
}
-void SymbolTableView::setFilter(const std::string& filter) {
- m_model->setFilter(filter);
+
+void SymbolTableView::setFilter(const std::string& filter, FilterOptions options)
+{
+ m_model->setFilter(filter, options);
}
diff --git a/view/kernelcache/ui/symboltable.h b/view/kernelcache/ui/symboltable.h
index 28d07199..64a20010 100644
--- a/view/kernelcache/ui/symboltable.h
+++ b/view/kernelcache/ui/symboltable.h
@@ -19,6 +19,7 @@ Q_OBJECT
SymbolTableView* m_parent;
QFont m_font;
std::string m_filter;
+ FilterOptions m_filterOptions;
std::vector<KernelCacheAPI::CacheSymbol> m_preparedSymbols{};
// These are the symbols we actually use
std::vector<KernelCacheAPI::CacheSymbol> m_modelSymbols{};
@@ -32,7 +33,7 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
void sort(int column, Qt::SortOrder order) override;
void updateSymbols(std::vector<KernelCacheAPI::CacheSymbol>&& symbols);
- void setFilter(std::string text);
+ void setFilter(const std::string& text, FilterOptions options);
const KernelCacheAPI::CacheSymbol& symbolAt(int row) const;
};
@@ -94,7 +95,7 @@ public:
return m_model->symbolAt(row);
}
- void setFilter(const std::string& filter) override;
+ void setFilter(const std::string& filter, FilterOptions options) override;
};
diff --git a/view/sharedcache/ui/dsctriage.cpp b/view/sharedcache/ui/dsctriage.cpp
index 48ad6130..43302534 100644
--- a/view/sharedcache/ui/dsctriage.cpp
+++ b/view/sharedcache/ui/dsctriage.cpp
@@ -267,8 +267,8 @@ QWidget* DSCTriageView::initImageTable()
auto loadImageFilterEdit = new FilterEdit(m_imageTable);
loadImageFilterEdit->setPlaceholderText("Filter images");
- connect(loadImageFilterEdit, &FilterEdit::textChanged, [this](const QString& filter) {
- m_imageTable->setFilter(filter.toStdString());
+ connect(loadImageFilterEdit, &FilterEdit::textChanged, [this, loadImageFilterEdit](const QString& filter) {
+ m_imageTable->setFilter(filter.toStdString(), loadImageFilterEdit->getFilterOptions());
});
connect(m_imageTable, &FilterableTableView::activated, this, [=, this](const QModelIndex& index) {
@@ -321,8 +321,8 @@ void DSCTriageView::initSymbolTable()
auto symbolFilterEdit = new FilterEdit(m_symbolTable);
symbolFilterEdit->setPlaceholderText("Filter symbols");
- connect(symbolFilterEdit, &FilterEdit::textChanged, [this](const QString& filter) {
- m_symbolTable->setFilter(filter.toStdString());
+ connect(symbolFilterEdit, &FilterEdit::textChanged, [this, symbolFilterEdit](const QString& filter) {
+ m_symbolTable->setFilter(filter.toStdString(), symbolFilterEdit->getFilterOptions());
});
auto loadSymbolImageButton = new QPushButton();
@@ -454,8 +454,8 @@ void DSCTriageView::initCacheInfoTables()
auto mappingLabel = new QLabel("Mappings");
auto mappingFilterEdit = new FilterEdit(m_mappingTable);
mappingFilterEdit->setPlaceholderText("Filter mappings");
- connect(mappingFilterEdit, &FilterEdit::textChanged, [this](const QString& filter) {
- m_mappingTable->setFilter(filter.toStdString());
+ connect(mappingFilterEdit, &FilterEdit::textChanged, [this, mappingFilterEdit](const QString& filter) {
+ m_mappingTable->setFilter(filter.toStdString(), mappingFilterEdit->getFilterOptions());
});
auto mappingHeaderLayout = new QHBoxLayout;
@@ -467,8 +467,8 @@ void DSCTriageView::initCacheInfoTables()
auto regionLabel = new QLabel("Regions");
auto regionFilterEdit = new FilterEdit(m_regionTable);
regionFilterEdit->setPlaceholderText("Filter regions");
- connect(regionFilterEdit, &FilterEdit::textChanged, [this](const QString& filter) {
- m_regionTable->setFilter(filter.toStdString());
+ connect(regionFilterEdit, &FilterEdit::textChanged, [this, regionFilterEdit](const QString& filter) {
+ m_regionTable->setFilter(filter.toStdString(), regionFilterEdit->getFilterOptions());
});
auto regionHeaderLayout = new QHBoxLayout;
diff --git a/view/sharedcache/ui/dsctriage.h b/view/sharedcache/ui/dsctriage.h
index 02a41eab..03eea6be 100644
--- a/view/sharedcache/ui/dsctriage.h
+++ b/view/sharedcache/ui/dsctriage.h
@@ -102,6 +102,8 @@ public:
class FilterableTableView : public QTableView, public FilterTarget {
Q_OBJECT
+ std::string m_filter;
+ FilterOptions m_filterOptions;
bool m_filterByHiding;
public:
@@ -113,19 +115,22 @@ public:
~FilterableTableView() override = default;
- void setFilter(const std::string& filter) override {
+ void setFilter(const std::string& filter, FilterOptions options) override {
+ m_filter = filter;
+ m_filterOptions = options;
+ QString qFilter = QString::fromStdString(m_filter);
if (!m_filterByHiding)
{
- emit filterTextChanged(QString::fromStdString(filter));
+ emit filterTextChanged(qFilter);
return;
}
- QString qFilter = QString::fromStdString(filter);
+ bool caseSensitive = options.testFlag(CaseSensitiveOption);
for (int row = 0; row < model()->rowCount(); ++row) {
bool match = false;
for (int col = 0; col < model()->columnCount(); ++col) {
QModelIndex index = model()->index(row, col);
QString data = model()->data(index).toString();
- if (data.contains(qFilter, Qt::CaseInsensitive)) {
+ if (data.contains(qFilter, caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive)) {
match = true;
break;
}
diff --git a/view/sharedcache/ui/symboltable.cpp b/view/sharedcache/ui/symboltable.cpp
index a876bf61..2a6cb467 100644
--- a/view/sharedcache/ui/symboltable.cpp
+++ b/view/sharedcache/ui/symboltable.cpp
@@ -127,7 +127,7 @@ void SymbolTableModel::sort(int column, Qt::SortOrder order)
void SymbolTableModel::updateSymbols(std::vector<CacheSymbol> symbols)
{
m_symbols = std::move(symbols);
- setFilter(m_filter);
+ setFilter(m_filter, m_filterOptions);
}
@@ -137,12 +137,12 @@ const CacheSymbol& SymbolTableModel::symbolAt(int row) const
}
-void SymbolTableModel::setFilter(std::string text)
+void SymbolTableModel::setFilter(const std::string& text, FilterOptions options)
{
+ m_filter = text;
+ m_filterOptions = options;
+ bool caseSensitive = options.testFlag(CaseSensitiveOption);
beginResetModel();
-
- m_filter = std::move(text);
-
// Skip filtering if no filter applied.
if (m_filter.empty())
{
@@ -156,8 +156,27 @@ void SymbolTableModel::setFilter(std::string text)
for (const auto& symbol : m_symbols)
{
- if (symbol.name.find(m_filter) != std::string::npos)
+ const std::string& symbolName = symbol.name;
+ bool match;
+ if (caseSensitive)
+ {
+ match = (symbolName.find(m_filter) != std::string::npos);
+ }
+ else
+ {
+ auto it = std::search(
+ symbolName.begin(), symbolName.end(),
+ m_filter.begin(), m_filter.end(),
+ [](char c1, char c2) { return std::tolower(c1) == std::tolower(c2); }
+ );
+
+ match = (it != symbolName.end());
+ }
+
+ if (match)
+ {
m_filteredSymbols.push_back(symbol);
+ }
}
// If the filtered vector is using less than 25% of its capacity,
@@ -172,6 +191,8 @@ void SymbolTableModel::setFilter(std::string text)
}
+
+
SymbolTableView::SymbolTableView(QWidget* parent) :
QTableView(parent), m_model(new SymbolTableModel(this))
{
@@ -223,6 +244,8 @@ void SymbolTableView::populateSymbols(BinaryView &view)
}
}
-void SymbolTableView::setFilter(const std::string& filter) {
- m_model->setFilter(filter);
+
+void SymbolTableView::setFilter(const std::string& filter, FilterOptions options)
+{
+ m_model->setFilter(filter, options);
}
diff --git a/view/sharedcache/ui/symboltable.h b/view/sharedcache/ui/symboltable.h
index ab0174f9..bcaef294 100644
--- a/view/sharedcache/ui/symboltable.h
+++ b/view/sharedcache/ui/symboltable.h
@@ -19,6 +19,7 @@ Q_OBJECT
SymbolTableView* m_parent;
QFont m_font;
std::string m_filter;
+ FilterOptions m_filterOptions;
std::vector<SharedCacheAPI::CacheSymbol> m_symbols;
std::vector<SharedCacheAPI::CacheSymbol> m_filteredSymbols;
@@ -36,7 +37,7 @@ public:
void sort(int column, Qt::SortOrder order) override;
void updateSymbols(std::vector<SharedCacheAPI::CacheSymbol> symbols);
- void setFilter(std::string text);
+ void setFilter(const std::string& text, FilterOptions options);
const SharedCacheAPI::CacheSymbol& symbolAt(int row) const;
};
@@ -98,7 +99,7 @@ public:
return m_model->symbolAt(row);
}
- void setFilter(const std::string& filter) override;
+ void setFilter(const std::string& filter, FilterOptions options) override;
};