summaryrefslogtreecommitdiff
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
parent9b7604d13e8bd98c6998facb9326926ed96281b5 (diff)
Add regex and case sensitivity options to FilterEdit
-rw-r--r--examples/triage/entry.cpp9
-rw-r--r--examples/triage/entry.h4
-rw-r--r--examples/triage/exports.cpp17
-rw-r--r--examples/triage/exports.h5
-rw-r--r--examples/triage/imports.cpp15
-rw-r--r--examples/triage/imports.h4
-rw-r--r--examples/triage/strings.cpp31
-rw-r--r--examples/triage/strings.h10
-rw-r--r--plugins/warp/ui/matches.cpp2
-rw-r--r--plugins/warp/ui/shared/constraint.cpp4
-rw-r--r--plugins/warp/ui/shared/constraint.h2
-rw-r--r--plugins/warp/ui/shared/function.cpp4
-rw-r--r--plugins/warp/ui/shared/function.h2
-rw-r--r--ui/bndbimportdialog.h2
-rw-r--r--ui/filter.h34
-rw-r--r--ui/logview.h2
-rw-r--r--ui/metadatachoicedialog.h5
-rw-r--r--ui/projectbrowser.h15
-rw-r--r--ui/searchresult.h5
-rw-r--r--ui/stringsview.h15
-rw-r--r--ui/symbollist.h6
-rw-r--r--ui/taglist.h12
-rw-r--r--ui/typebrowser.h18
-rw-r--r--ui/variablelist.h2
-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
32 files changed, 252 insertions, 114 deletions
diff --git a/examples/triage/entry.cpp b/examples/triage/entry.cpp
index addb5960..dfee4a2f 100644
--- a/examples/triage/entry.cpp
+++ b/examples/triage/entry.cpp
@@ -141,13 +141,14 @@ void GenericEntryModel::sort(int col, Qt::SortOrder order)
}
-void GenericEntryModel::setFilter(const std::string& filterText)
+void GenericEntryModel::setFilter(const std::string& filterText, FilterOptions options)
{
beginResetModel();
m_entries.clear();
+ bool caseSensitive = options.testFlag(FilterOption::CaseSensitiveOption);
for (auto& entry : m_allEntries)
{
- if (FilteredView::match(entry->GetSymbol()->GetFullName(), filterText))
+ if (FilteredView::match(entry->GetSymbol()->GetFullName(), filterText, caseSensitive))
m_entries.push_back(entry);
}
performSort(m_sortCol, m_sortOrder);
@@ -250,9 +251,9 @@ void EntryTreeView::entryDoubleClicked(const QModelIndex& cur)
}
-void EntryTreeView::setFilter(const std::string& filterText)
+void EntryTreeView::setFilter(const std::string& filterText, FilterOptions options)
{
- m_model->setFilter(filterText);
+ m_model->setFilter(filterText, options);
}
diff --git a/examples/triage/entry.h b/examples/triage/entry.h
index a1396741..013e6793 100644
--- a/examples/triage/entry.h
+++ b/examples/triage/entry.h
@@ -24,7 +24,7 @@ class GenericEntryModel : public QAbstractItemModel
virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
virtual QModelIndex parent(const QModelIndex& index) const override;
virtual void sort(int col, Qt::SortOrder order) override;
- void setFilter(const std::string& filterText);
+ void setFilter(const std::string& filterText, FilterOptions options);
FunctionRef getEntry(const QModelIndex& index);
};
@@ -46,7 +46,7 @@ class EntryTreeView : public QTreeView, public FilterTarget
void copySelection();
bool canCopySelection() const;
- virtual void setFilter(const std::string& filterText) override;
+ virtual void setFilter(const std::string& filterText, FilterOptions options) override;
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
diff --git a/examples/triage/exports.cpp b/examples/triage/exports.cpp
index 776044c5..976be45e 100644
--- a/examples/triage/exports.cpp
+++ b/examples/triage/exports.cpp
@@ -67,7 +67,7 @@ void GenericExportsModel::updateModel()
}
endResetModel();
- setFilter(m_filter);
+ setFilter(m_filter, m_filterOptions);
}
@@ -225,22 +225,26 @@ void GenericExportsModel::sort(int col, Qt::SortOrder order)
}
-void GenericExportsModel::setFilter(const std::string& filterText)
+void GenericExportsModel::setFilter(const std::string& filterText, FilterOptions options)
{
m_filter = filterText;
+ m_filterOptions = options;
beginResetModel();
m_entries.clear();
+
+ bool caseSensitive = options.testFlag(FilterOption::CaseSensitiveOption);
for (auto& entry : m_allEntries)
{
- if (FilteredView::match(entry->GetFullName(), filterText))
+ if (FilteredView::match(entry->GetFullName(), filterText, caseSensitive))
m_entries.push_back(entry);
- else if (FilteredView::match(std::to_string(entry->GetOrdinal()), filterText))
+ else if (FilteredView::match(std::to_string(entry->GetOrdinal()), filterText, caseSensitive))
m_entries.push_back(entry);
}
performSort(m_sortCol, m_sortOrder);
endResetModel();
}
+
void GenericExportsModel::setNeedsUpdate(bool needed)
{
if (m_needsUpdate.exchange(needed) == needed)
@@ -249,6 +253,7 @@ void GenericExportsModel::setNeedsUpdate(bool needed)
updateTimer(needed);
}
+
void GenericExportsModel::updateTimer(bool needsUpdate)
{
if (needsUpdate && !m_updateTimer->isActive())
@@ -427,9 +432,9 @@ void ExportsTreeView::exportDoubleClicked(const QModelIndex& cur)
}
-void ExportsTreeView::setFilter(const std::string& filterText)
+void ExportsTreeView::setFilter(const std::string& filterText, FilterOptions options)
{
- m_model->setFilter(filterText);
+ m_model->setFilter(filterText, options);
}
diff --git a/examples/triage/exports.h b/examples/triage/exports.h
index af0f4613..28c9d53a 100644
--- a/examples/triage/exports.h
+++ b/examples/triage/exports.h
@@ -13,6 +13,7 @@ class GenericExportsModel : public QAbstractItemModel, public BinaryNinja::Binar
BinaryViewRef m_data;
std::vector<SymbolRef> m_allEntries, m_entries;
std::string m_filter;
+ FilterOptions m_filterOptions;
QTimer* m_updateTimer;
Qt::SortOrder m_sortOrder;
int m_sortCol;
@@ -46,7 +47,7 @@ signals:
virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
virtual QModelIndex parent(const QModelIndex& index) const override;
virtual void sort(int col, Qt::SortOrder order) override;
- void setFilter(const std::string& filterText);
+ void setFilter(const std::string& filterText, FilterOptions options);
void pauseUpdates();
void resumeUpdates();
@@ -79,7 +80,7 @@ class ExportsTreeView : public QTreeView, public FilterTarget
void copySelection();
bool canCopySelection() const;
- virtual void setFilter(const std::string& filterText) override;
+ virtual void setFilter(const std::string& filterText, FilterOptions options) override;
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
diff --git a/examples/triage/imports.cpp b/examples/triage/imports.cpp
index 19c6a62b..54b20bd2 100644
--- a/examples/triage/imports.cpp
+++ b/examples/triage/imports.cpp
@@ -205,19 +205,20 @@ void GenericImportsModel::sort(int col, Qt::SortOrder order)
}
-void GenericImportsModel::setFilter(const std::string& filterText)
+void GenericImportsModel::setFilter(const std::string& filterText, FilterOptions options)
{
beginResetModel();
m_entries.clear();
+ bool caseSensitive = options.testFlag(FilterOption::CaseSensitiveOption);
for (auto& entry : m_allEntries)
{
- if (FilteredView::match(entry->GetFullName(), filterText))
+ if (FilteredView::match(entry->GetFullName(), filterText, caseSensitive))
m_entries.push_back(entry);
- else if (FilteredView::match(getNamespace(entry).toStdString(), filterText))
+ else if (FilteredView::match(getNamespace(entry).toStdString(), filterText, caseSensitive))
m_entries.push_back(entry);
- else if (FilteredView::match(std::to_string(entry->GetOrdinal()), filterText))
+ else if (FilteredView::match(std::to_string(entry->GetOrdinal()), filterText, caseSensitive))
m_entries.push_back(entry);
- else if (FilteredView::match(getLibrarySource(entry).toStdString(), filterText))
+ else if (FilteredView::match(getLibrarySource(entry).toStdString(), filterText, caseSensitive))
m_entries.push_back(entry);
}
performSort(m_sortCol, m_sortOrder);
@@ -325,9 +326,9 @@ void ImportsTreeView::importDoubleClicked(const QModelIndex& cur)
}
-void ImportsTreeView::setFilter(const std::string& filterText)
+void ImportsTreeView::setFilter(const std::string& filterText, FilterOptions options)
{
- m_model->setFilter(filterText);
+ m_model->setFilter(filterText, options);
}
diff --git a/examples/triage/imports.h b/examples/triage/imports.h
index 8a2441f7..dde9b06d 100644
--- a/examples/triage/imports.h
+++ b/examples/triage/imports.h
@@ -28,7 +28,7 @@ class GenericImportsModel : public QAbstractItemModel
virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
virtual QModelIndex parent(const QModelIndex& index) const override;
virtual void sort(int col, Qt::SortOrder order) override;
- void setFilter(const std::string& filterText);
+ void setFilter(const std::string& filterText, FilterOptions options);
SymbolRef getSymbol(const QModelIndex& index);
@@ -55,7 +55,7 @@ class ImportsTreeView : public QTreeView, public FilterTarget
void copySelection();
bool canCopySelection() const;
- virtual void setFilter(const std::string& filterText) override;
+ virtual void setFilter(const std::string& filterText, FilterOptions options) override;
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
diff --git a/examples/triage/strings.cpp b/examples/triage/strings.cpp
index 32d9ff97..9ae176a0 100644
--- a/examples/triage/strings.cpp
+++ b/examples/triage/strings.cpp
@@ -115,16 +115,16 @@ QString GenericStringsModel::stringRefToQString(const BNStringReference& stringR
BinaryNinja::DataBuffer stringBuffer = m_data->ReadBuffer(stringRef.start, stringRef.length);
if (stringRef.type == BNStringType::Utf32String)
- {
+ {
char32_t* data = (char32_t*)stringBuffer.GetData();
qstr = QString::fromUcs4(data, stringRef.length / 4);
- }
+ }
else if (stringRef.type == BNStringType::Utf16String)
{
char16_t* data = (char16_t*)stringBuffer.GetData();
qstr = QString::fromUtf16(data, stringRef.length / 2);
}
- else
+ else
{
char* data = (char*)stringBuffer.GetData();
qstr = QString::fromUtf8(data, stringBuffer.GetLength());
@@ -159,7 +159,7 @@ void GenericStringsModel::performSort(int col, Qt::SortOrder order)
return a.length > b.length;
}
else if (col == 2)
- {
+ {
QString s = stringRefToQString(a);
QString s2 = stringRefToQString(b);
@@ -188,18 +188,31 @@ void GenericStringsModel::applyFilter()
m_entries.clear();
for (auto& entry : m_allEntries)
{
- auto s = stringRefToQString(entry).toStdString();
+ auto s = stringRefToQString(entry);
+
+ bool match;
+ if (m_filterOptions.testFlag(UseRegexOption))
+ {
+ match = m_filterRegex.match(s).hasMatch();
+ }
+ else
+ {
+ match = s.contains(m_filter, m_filterOptions.testFlag(CaseSensitiveOption) ? Qt::CaseSensitive : Qt::CaseInsensitive);
+ }
- if (FilteredView::match(s, m_filter))
+ if (match)
m_entries.push_back(entry);
}
performSort(m_sortCol, m_sortOrder);
}
-void GenericStringsModel::setFilter(const std::string& filterText)
+void GenericStringsModel::setFilter(const QString& filterText, FilterOptions options)
{
m_filter = filterText;
+ m_filterOptions = options;
+ bool caseSensitive = options.testFlag(CaseSensitiveOption);
+ m_filterRegex = QRegularExpression(filterText, caseSensitive ? QRegularExpression::NoPatternOption : QRegularExpression::CaseInsensitiveOption);
beginResetModel();
applyFilter();
endResetModel();
@@ -412,9 +425,9 @@ void StringsTreeView::stringDoubleClicked(const QModelIndex& cur)
}
-void StringsTreeView::setFilter(const std::string& filterText)
+void StringsTreeView::setFilter(const std::string& filterText, FilterOptions options)
{
- m_model->setFilter(filterText);
+ m_model->setFilter(QString::fromStdString(filterText), options);
}
diff --git a/examples/triage/strings.h b/examples/triage/strings.h
index 31617f08..2a28c4f1 100644
--- a/examples/triage/strings.h
+++ b/examples/triage/strings.h
@@ -14,9 +14,12 @@ class GenericStringsModel : public QAbstractItemModel, public BinaryNinja::Binar
std::vector<BNStringReference> m_allEntries, m_entries;
int m_totalCols, m_sortCol;
Qt::SortOrder m_sortOrder;
- std::string m_filter;
QTimer* m_updateTimer;
+ QString m_filter;
+ FilterOptions m_filterOptions;
+ QRegularExpression m_filterRegex;
+
// Read from arbitrary threads while processing notifications.
std::atomic<bool> m_updatesPaused = false;
// Read/written from arbitrary threads while processing notifications.
@@ -46,7 +49,8 @@ signals:
virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
virtual QModelIndex parent(const QModelIndex& index) const override;
virtual void sort(int col, Qt::SortOrder order) override;
- void setFilter(const std::string& filterText);
+
+ void setFilter(const QString& filterText, FilterOptions options);
void pauseUpdates();
void resumeUpdates();
@@ -81,7 +85,7 @@ class StringsTreeView : public QTreeView, public FilterTarget
void copySelection();
bool canCopySelection() const;
- virtual void setFilter(const std::string& filterText) override;
+ virtual void setFilter(const std::string& filterText, FilterOptions options) override;
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
diff --git a/plugins/warp/ui/matches.cpp b/plugins/warp/ui/matches.cpp
index 4b8f0495..289c1102 100644
--- a/plugins/warp/ui/matches.cpp
+++ b/plugins/warp/ui/matches.cpp
@@ -78,7 +78,7 @@ WarpCurrentFunctionWidget::WarpCurrentFunctionWidget()
"Search for Source", [this](WarpFunctionItem* item, std::optional<uint64_t>) {
// Apply the source as the filter.
if (const auto source = item->GetSource(); source)
- m_tableWidget->setFilter(source->ToString());
+ m_tableWidget->setFilter(source->ToString(), NoFilterOption);
});
connect(m_tableWidget->GetTableView(), &QTableView::clicked, this, [this](const QModelIndex& index) {
diff --git a/plugins/warp/ui/shared/constraint.cpp b/plugins/warp/ui/shared/constraint.cpp
index 39c9c7d3..fcebbfb0 100644
--- a/plugins/warp/ui/shared/constraint.cpp
+++ b/plugins/warp/ui/shared/constraint.cpp
@@ -124,8 +124,10 @@ void WarpConstraintTableWidget::SetMatchedConstraints(const std::vector<Warp::Co
m_model->SetMatchedConstraints(analysisConstraints);
}
-void WarpConstraintTableWidget::setFilter(const std::string& filter)
+void WarpConstraintTableWidget::setFilter(const std::string& filter, FilterOptions options)
{
m_proxyModel->setFilterFixedString(QString::fromStdString(filter));
+ m_proxyModel->setFilterCaseSensitivity(
+ options.testFlag(CaseSensitiveOption) ? Qt::CaseSensitive : Qt::CaseInsensitive);
m_filterView->showFilter(QString::fromStdString(filter));
}
diff --git a/plugins/warp/ui/shared/constraint.h b/plugins/warp/ui/shared/constraint.h
index 02702144..632c39ce 100644
--- a/plugins/warp/ui/shared/constraint.h
+++ b/plugins/warp/ui/shared/constraint.h
@@ -58,7 +58,7 @@ public:
void SetMatchedConstraints(const std::vector<Warp::Constraint>& analysisConstraints);
- void setFilter(const std::string&) override;
+ void setFilter(const std::string&, FilterOptions options) override;
void scrollToFirstItem() override {}
diff --git a/plugins/warp/ui/shared/function.cpp b/plugins/warp/ui/shared/function.cpp
index 06d4cbcf..3b2451ab 100644
--- a/plugins/warp/ui/shared/function.cpp
+++ b/plugins/warp/ui/shared/function.cpp
@@ -299,9 +299,11 @@ void WarpFunctionTableWidget::RemoveFunction(uint64_t address)
m_model->RemoveFunction(address);
}
-void WarpFunctionTableWidget::setFilter(const std::string& filter)
+void WarpFunctionTableWidget::setFilter(const std::string& filter, FilterOptions options)
{
m_proxyModel->setFilterFixedString(QString::fromStdString(filter));
+ m_proxyModel->setFilterCaseSensitivity(
+ options.testFlag(CaseSensitiveOption) ? Qt::CaseSensitive : Qt::CaseInsensitive);
m_filterView->showFilter(QString::fromStdString(filter));
}
diff --git a/plugins/warp/ui/shared/function.h b/plugins/warp/ui/shared/function.h
index 23b2bd3b..c6e5ba63 100644
--- a/plugins/warp/ui/shared/function.h
+++ b/plugins/warp/ui/shared/function.h
@@ -123,7 +123,7 @@ public:
void RemoveFunction(uint64_t address);
- void setFilter(const std::string&) override;
+ void setFilter(const std::string&, FilterOptions options) override;
void scrollToFirstItem() override {}
diff --git a/ui/bndbimportdialog.h b/ui/bndbimportdialog.h
index eb8f0dfd..4578b76c 100644
--- a/ui/bndbimportdialog.h
+++ b/ui/bndbimportdialog.h
@@ -117,7 +117,7 @@ public:
BndbImportDialog(QWidget* parent, BinaryViewRef view);
~BndbImportDialog() = default;
- void setFilter(const std::string& filter) override;
+ void setFilter(const std::string& filter, FilterOptions options) override;
void scrollToFirstItem() override;
void scrollToCurrentItem() override;
void ensureSelection() override;
diff --git a/ui/filter.h b/ui/filter.h
index 98417f65..3178d4b8 100644
--- a/ui/filter.h
+++ b/ui/filter.h
@@ -14,12 +14,25 @@
\ingroup filter
*/
+enum BINARYNINJAUIAPI FilterOption {
+ NoFilterOption = 0,
+ CaseSensitiveOption = 1,
+ UseRegexOption = 2,
+};
+
+Q_DECLARE_FLAGS(FilterOptions, FilterOption)
+
+
+/*!
+
+ \ingroup filter
+*/
class BINARYNINJAUIAPI FilterTarget
{
public:
virtual ~FilterTarget() {}
- virtual void setFilter(const std::string& filter) = 0;
+ virtual void setFilter(const std::string& filter, FilterOptions options) = 0;
virtual void scrollToFirstItem() = 0;
virtual void scrollToCurrentItem() = 0;
@@ -44,10 +57,27 @@ class BINARYNINJAUIAPI FilterEdit : public QLineEdit
Q_OBJECT
FilterTarget* m_target;
+ FilterOptions m_filterOptions;
+
+ QAction* m_clearAction;
+ QAction* m_regexAction;
+ QAction* m_regexWarningAction;
+ QAction* m_caseSensitivityAction;
+
+ QIcon getActionIcon(const QString& iconName, bool enabled) const;
public:
FilterEdit(FilterTarget* target);
+ void showRegexToggle(bool enabled);
+
+ void setRegexValidationError(const QString& error);
+
+ FilterOptions getFilterOptions() const { return m_filterOptions; }
+
+ Q_SIGNALS:
+ void optionsChanged(FilterOptions options);
+
protected:
virtual void paintEvent(QPaintEvent* event) override;
virtual void keyPressEvent(QKeyEvent* event) override;
@@ -76,7 +106,7 @@ class BINARYNINJAUIAPI FilteredView : public QWidget
void focusAndSelectFilter();
bool hasFilterText() const;
- static bool match(const std::string& name, const std::string& filter);
+ static bool match(const std::string& name, const std::string& filter, bool caseSensitive = false);
private Q_SLOTS:
void timerStart();
diff --git a/ui/logview.h b/ui/logview.h
index 0aaf9372..c2488ed5 100644
--- a/ui/logview.h
+++ b/ui/logview.h
@@ -268,7 +268,7 @@ class BINARYNINJAUIAPI LogView : public SidebarWidget, public FilterTarget
void focus() override;
LogListModel* model() { return m_listModel; }
- void setFilter(const std::string& filter) override;
+ void setFilter(const std::string& filter, FilterOptions options) override;
LoggingScope getScope() const { return m_model->getScope(); }
void setScope(LoggingScope scope) { m_model->setScope(scope); }
diff --git a/ui/metadatachoicedialog.h b/ui/metadatachoicedialog.h
index 12de4a55..79cf662f 100644
--- a/ui/metadatachoicedialog.h
+++ b/ui/metadatachoicedialog.h
@@ -67,6 +67,7 @@ class BINARYNINJAUIAPI ManagedTableView : public QTableView, public FilterTarget
ManagedTableModel* m_model;
std::string m_filter;
+ FilterOptions m_filterOptions;
ManagedTableDelegate* m_delegate;
@@ -78,7 +79,7 @@ public:
int getCurrentSelection();
void forceFilterUpdate() {
- setFilter(m_filter);
+ setFilter(m_filter, m_filterOptions);
};
void resetModel();
@@ -88,7 +89,7 @@ public:
virtual void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) override;
- virtual void setFilter(const std::string& filter) override;
+ virtual void setFilter(const std::string& filter, FilterOptions options) override;
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
diff --git a/ui/projectbrowser.h b/ui/projectbrowser.h
index 11e14058..348d5ff0 100644
--- a/ui/projectbrowser.h
+++ b/ui/projectbrowser.h
@@ -173,11 +173,14 @@ class BINARYNINJAUIAPI ProjectTree: public QTreeView, public FilterTarget
QSet<QString> m_expandedIds;
+ FilterOptions m_filterOptions;
+ std::string m_filter;
+
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
virtual void activateSelection() override;
- virtual void setFilter(const std::string& filter) override;
+ virtual void setFilter(const std::string& filter, FilterOptions options) override;
protected:
void mousePressEvent(QMouseEvent* event) override;
@@ -188,7 +191,7 @@ public:
ProjectTree(QWidget* parent = nullptr);
Q_SIGNALS:
- void filterChanged(const QString& filter);
+ void filterChanged(const QString& filter, FilterOptions options);
};
@@ -196,11 +199,15 @@ class BINARYNINJAUIAPI RecentsList: public QListWidget, public FilterTarget
{
Q_OBJECT
+ QString m_filter;
+ FilterOptions m_filterOptions;
+
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
virtual void activateSelection() override;
- virtual void setFilter(const std::string& filter) override;
+ void applyFilter();
+ virtual void setFilter(const std::string& filter, FilterOptions options) override;
public:
@@ -333,7 +340,7 @@ private slots:
void itemSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
void itemChanged(QStandardItem* item);
void handleItemsDropped(Qt::DropAction action, const QList<QString> fileIds, const QList<QString> folderIds, const QList<QUrl> newUrls, ProjectFolderRef newParentFolder);
- void onTreeFilterChanged(const QString& filter);
+ void onTreeFilterChanged(const QString& filter, FilterOptions options);
protected:
void SelectItems(std::vector<ProjectFileRef> files, std::vector<ProjectFolderRef> folders);
diff --git a/ui/searchresult.h b/ui/searchresult.h
index 13fa77f9..42b79252 100644
--- a/ui/searchresult.h
+++ b/ui/searchresult.h
@@ -313,15 +313,14 @@ class BINARYNINJAUIAPI SearchResultHeaderWidget : public QWidget, public FilterT
{
Q_OBJECT
- QLineEdit* m_search;
+ FilterEdit* m_search;
QComboBox* m_mode;
- ClickableIcon* m_caseSensitive;
ClickableIcon* m_ignoreWhitespace;
public:
SearchResultHeaderWidget();
- virtual void setFilter(const std::string&) override {}
+ virtual void setFilter(const std::string&, FilterOptions) override {}
virtual void scrollToFirstItem() override {}
virtual void scrollToCurrentItem() override {}
virtual void ensureSelection() override {}
diff --git a/ui/stringsview.h b/ui/stringsview.h
index 4be86d60..b3ced9ec 100644
--- a/ui/stringsview.h
+++ b/ui/stringsview.h
@@ -68,7 +68,10 @@ class BINARYNINJAUIAPI StringsListModel : public QAbstractItemModel, public Bina
std::vector<StringsListItem> m_strings;
std::map<uint64_t, uint64_t> m_refCounts;
std::map<BinaryNinja::DerivedString, uint64_t> m_derivedRefCounts;
- std::string m_filter;
+
+ QString m_filter;
+ FilterOptions m_filterOptions;
+ QRegularExpression m_filterRegex; // This holds a compiled regex for m_filter
size_t m_filteredByOptions;
@@ -116,9 +119,9 @@ class BINARYNINJAUIAPI StringsListModel : public QAbstractItemModel, public Bina
virtual void sort(int col, Qt::SortOrder order) override;
- void setFilter(const std::string& filter);
+ void setFilter(const QString& filter, FilterOptions options);
- void updateFilter() { setFilter(m_filter); };
+ void updateFilter() { setFilter(m_filter, m_filterOptions); };
size_t getFilteredStringCount() const { return m_filteredByOptions; }
size_t getStringCount() const { return m_strings.size(); }
@@ -199,7 +202,7 @@ class BINARYNINJAUIAPI StringsView : public QTableView, public View, public Filt
virtual void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) override;
- virtual void setFilter(const std::string& filter) override;
+ virtual void setFilter(const std::string& filter, FilterOptions options) override;
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
@@ -242,7 +245,7 @@ class BINARYNINJAUIAPI StringsContainer : public QWidget, public ViewContainer
friend class StringsView;
StringsView* m_strings;
- FilteredView* m_filter;
+ FilteredView* m_filteredView;
FilterEdit* m_separateEdit = nullptr;
StringsViewSidebarWidget* m_widget;
UIActionHandler m_actionHandler;
@@ -252,7 +255,7 @@ class BINARYNINJAUIAPI StringsContainer : public QWidget, public ViewContainer
virtual View* getView() override { return m_strings; }
StringsView* getStringsView() { return m_strings; }
- FilteredView* getFilter() { return m_filter; }
+ FilteredView* getFilter() { return m_filteredView; }
FilterEdit* getSeparateFilterEdit() { return m_separateEdit; }
protected:
diff --git a/ui/symbollist.h b/ui/symbollist.h
index 1bc4a6dd..6f196ddf 100644
--- a/ui/symbollist.h
+++ b/ui/symbollist.h
@@ -229,6 +229,7 @@ class BINARYNINJAUIAPI SymbolListModel : public QAbstractItemModel, public Binar
std::unique_ptr<std::deque<NamedObject>> m_oldCurSyms;
NamedObject m_currentSym;
std::string m_filter;
+ FilterOptions m_filterOptions;
int m_maxWidth = 32;
std::mutex m_updateMutex;
@@ -290,7 +291,7 @@ class BINARYNINJAUIAPI SymbolListModel : public QAbstractItemModel, public Binar
bool hasSymbols() const;
int getMaximumWidth() const { return m_maxWidth; }
- void setFilter(const std::string& filter);
+ void setFilter(const std::string& filter, FilterOptions options);
void showExportedDataVars(bool show) { m_showExportedDataVars = show; }
void showExportedFunctions(bool show) { m_showExportedFunctions = show; }
void showLocalFunctions(bool show) { m_showLocalFunctions = show; }
@@ -348,6 +349,7 @@ class BINARYNINJAUIAPI SymbolList : public QListView, public FilterTarget
bool m_showLocalDataVars;
bool m_showImports;
std::string m_filter;
+ FilterOptions m_filterOptions;
SymbolListModel::NamedObject m_index;
SymbolListModel::NamedObject m_topIndex;
@@ -361,7 +363,7 @@ class BINARYNINJAUIAPI SymbolList : public QListView, public FilterTarget
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
virtual void activateSelection() override;
- virtual void setFilter(const std::string& filter) override;
+ virtual void setFilter(const std::string& filter, FilterOptions options) override;
bool hasSymbols();
diff --git a/ui/taglist.h b/ui/taglist.h
index 1f1e09cb..e19d899a 100644
--- a/ui/taglist.h
+++ b/ui/taglist.h
@@ -143,8 +143,9 @@ class BINARYNINJAUIAPI TagList : public QTreeView, public FilterTarget
typedef std::function<bool(const BinaryNinja::TagReference&)> FilterFn;
private:
- bool m_hasFilter;
- FilterFn m_filter;
+ std::optional<FilterFn> m_filterFn;
+
+ FilterOptions m_searchFilterOptions;
std::string m_searchFilter;
QTimer* m_hoverTimer;
@@ -161,7 +162,7 @@ class BINARYNINJAUIAPI TagList : public QTreeView, public FilterTarget
virtual void resizeEvent(QResizeEvent* event) override;
void goToReference(const QModelIndex& idx);
- void setFilter(const std::string& filter) override;
+ void setFilter(const std::string& filter, FilterOptions options) override;
private Q_SLOTS:
void hoverTimerEvent();
@@ -186,7 +187,7 @@ class BINARYNINJAUIAPI TagList : public QTreeView, public FilterTarget
void filterTagReferences(std::vector<BinaryNinja::TagReference>& refs);
void clearFilter();
- void setFilter(FilterFn filter);
+ void setFilterFunction(FilterFn filter);
void setFilterView(FilteredView* filterView) { m_filterView = filterView; }
bool hasSelection();
@@ -255,6 +256,7 @@ class BINARYNINJAUIAPI TagListDialog : public QDialog
private:
BinaryViewRef m_data;
TagList* m_list;
+ FilterEdit* m_filterEdit;
FilteredView* m_filter;
AddFn m_addFn;
@@ -263,7 +265,7 @@ class BINARYNINJAUIAPI TagListDialog : public QDialog
public:
TagListDialog(QWidget* parent, ViewFrame* frame, BinaryViewRef data, AddFn addFn);
- void setFilter(TagList::FilterFn filter);
+ void setFilterFunction(TagList::FilterFn filter);
private Q_SLOTS:
void updateActive(const QItemSelection&, const QItemSelection&);
diff --git a/ui/typebrowser.h b/ui/typebrowser.h
index 60eb0c30..6cd2ce89 100644
--- a/ui/typebrowser.h
+++ b/ui/typebrowser.h
@@ -65,7 +65,7 @@ public:
virtual std::string text(int column) const = 0;
virtual bool lessThan(const TypeBrowserTreeNode& other, int column) const = 0;
- virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode) const = 0;
+ virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode, bool caseSensitive) const = 0;
virtual void updateChildren(bool recursive, UpdateNodeCallback update);
};
@@ -78,7 +78,7 @@ public:
virtual std::string text(int column) const override;
virtual bool lessThan(const TypeBrowserTreeNode& other, int column) const override;
- virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode) const override;
+ virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode, bool caseSensitive) const override;
protected:
virtual void generateChildren() override;
@@ -96,7 +96,7 @@ public:
virtual std::string text(int column) const override;
virtual bool lessThan(const TypeBrowserTreeNode& other, int column) const override;
- virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode) const override;
+ virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode, bool caseSensitive) const override;
protected:
virtual void generateChildren() override;
@@ -148,7 +148,7 @@ public:
virtual std::string text(int column) const override;
virtual bool lessThan(const TypeBrowserTreeNode& other, int column) const override;
- virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode) const override;
+ virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode, bool caseSensitive) const override;
protected:
virtual void generateChildren() override;
@@ -166,7 +166,7 @@ public:
virtual ~TypeContainerTreeNode();
virtual std::string text(int column) const override;
- virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode) const override;
+ virtual bool filter(const std::string& filter, TypeBrowserFilterMode mode, bool caseSensitive) const override;
virtual bool lessThan(const TypeBrowserTreeNode& other, int column) const override;
const std::string& containerId() const { return m_containerId; }
@@ -293,7 +293,7 @@ public:
std::shared_ptr<TypeBrowserTreeNode> nodeForIndex(const QModelIndex& index) const;
QModelIndex indexForNode(std::shared_ptr<TypeBrowserTreeNode> node, int column = 0) const;
- bool filter(const QModelIndex& index, const std::string& filter, TypeBrowserFilterMode mode) const;
+ bool filter(const QModelIndex& index, const std::string& filter, TypeBrowserFilterMode mode, bool caseSensitive) const;
bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
void OnTypeDefined(BinaryNinja::BinaryView* data, const BinaryNinja::QualifiedName& name, BinaryNinja::Type* type) override;
@@ -326,7 +326,9 @@ class BINARYNINJAUIAPI TypeBrowserFilterModel : public QSortFilterProxyModel
Q_OBJECT
BinaryViewRef m_data;
TypeBrowserModel* m_model;
+ std::string m_originalFilter;
std::string m_filter;
+ bool m_filterCaseSensitive = false;
TypeBrowserFilterMode m_filterMode;
bool m_exactOnTop;
@@ -337,7 +339,7 @@ protected:
public:
TypeBrowserFilterModel(BinaryViewRef data, TypeBrowserModel* model, QObject* parent);
- void setFilter(const std::string& filter);
+ void setFilter(const std::string& filter, FilterOptions options);
TypeBrowserFilterMode filterMode() const { return m_filterMode; }
void setFilterMode(TypeBrowserFilterMode newMode) { m_filterMode = newMode; }
@@ -435,7 +437,7 @@ public:
virtual StatusBarWidget* getStatusBarWidget() override;
virtual QWidget* getHeaderOptionsWidget() override;
- virtual void setFilter(const std::string& filter) override;
+ virtual void setFilter(const std::string& filter, FilterOptions options) override;
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
diff --git a/ui/variablelist.h b/ui/variablelist.h
index 43e6b65c..923919ff 100644
--- a/ui/variablelist.h
+++ b/ui/variablelist.h
@@ -254,7 +254,7 @@ class BINARYNINJAUIAPI VariableList : public SidebarWidget, public FilterTarget
//! Copy selected variables to clipboard
void copy();
- virtual void setFilter(const std::string& filter) override;
+ virtual void setFilter(const std::string& filter, FilterOptions options) override;
virtual void scrollToFirstItem() override;
virtual void scrollToCurrentItem() override;
virtual void ensureSelection() override;
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;
};