mirror of
https://github.com/rizinorg/cutter
synced 2026-08-11 16:23:06 -04:00
Added support for search in XRef dialogue (#3579)
* Updated using given instructions new class XrefFilterProxyModel * Updated using given instructions new class XrefFilterProxyModel clang formatted * Added shortcuts for clear and show and added sorting functionality to XrefProxyModel * fixed clear shortcut not working * clang formatted
This commit is contained in:
parent
41b91515d3
commit
9ac6c75c1a
3 changed files with 127 additions and 14 deletions
|
|
@ -7,9 +7,18 @@
|
|||
#include "core/MainWindow.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QShortcut>
|
||||
#include "shortcuts/ShortcutManager.h"
|
||||
#include <QApplication>
|
||||
|
||||
XrefsDialog::XrefsDialog(MainWindow *parent, bool hideXrefFrom)
|
||||
: QDialog(parent), addr(0), toModel(this), fromModel(this), ui(new Ui::XrefsDialog)
|
||||
: QDialog(parent),
|
||||
addr(0),
|
||||
toModel(this),
|
||||
toProxyModel(&toModel),
|
||||
fromModel(this),
|
||||
fromProxyModel(&fromModel),
|
||||
ui(new Ui::XrefsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
|
||||
|
|
@ -17,8 +26,8 @@ XrefsDialog::XrefsDialog(MainWindow *parent, bool hideXrefFrom)
|
|||
ui->toTreeWidget->setMainWindow(parent);
|
||||
ui->fromTreeWidget->setMainWindow(parent);
|
||||
|
||||
ui->toTreeWidget->setModel(&toModel);
|
||||
ui->fromTreeWidget->setModel(&fromModel);
|
||||
ui->toTreeWidget->setModel(&toProxyModel);
|
||||
ui->fromTreeWidget->setModel(&fromProxyModel);
|
||||
|
||||
ui->toTreeWidget->getItemContextMenu()->toggleBreakpointAction(true);
|
||||
ui->fromTreeWidget->getItemContextMenu()->toggleBreakpointAction(true);
|
||||
|
|
@ -44,6 +53,34 @@ XrefsDialog::XrefsDialog(MainWindow *parent, bool hideXrefFrom)
|
|||
&XrefsDialog::onToTreeWidgetItemSelectionChanged);
|
||||
connect(ui->fromTreeWidget->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&XrefsDialog::onFromTreeWidgetItemSelectionChanged);
|
||||
connect(ui->fromQuickFilter, &QuickFilterView::filterTextChanged, &fromProxyModel,
|
||||
&QSortFilterProxyModel::setFilterWildcard);
|
||||
connect(ui->toQuickFilter, &QuickFilterView::filterTextChanged, &toProxyModel,
|
||||
&QSortFilterProxyModel::setFilterWildcard);
|
||||
|
||||
// SearchWidget shortcuts
|
||||
|
||||
QShortcut *searchShortcut = Shortcuts()->makeQShortcut("General.showFilter", ui->toTreeWidget);
|
||||
QShortcut *clearShortcut =
|
||||
Shortcuts()->makeQShortcut("General.clearFilter", ui->fromQuickFilter);
|
||||
|
||||
connect(searchShortcut, &QShortcut::activated, this, [this]() {
|
||||
QWidget *fw = QApplication::focusWidget();
|
||||
if (ui->toTreeWidget->isAncestorOf(fw)) {
|
||||
ui->toQuickFilter->showFilter();
|
||||
} else if (ui->fromTreeWidget->isAncestorOf(fw)) {
|
||||
ui->fromQuickFilter->showFilter();
|
||||
}
|
||||
});
|
||||
|
||||
connect(clearShortcut, &QShortcut::activated, [this]() {
|
||||
QWidget *fw = QApplication::focusWidget();
|
||||
if (ui->toQuickFilter->isAncestorOf(fw)) {
|
||||
ui->toQuickFilter->clearFilter();
|
||||
} else if (ui->fromQuickFilter->isAncestorOf(fw)) {
|
||||
ui->fromQuickFilter->clearFilter();
|
||||
}
|
||||
});
|
||||
|
||||
// Don't create recursive xref dialogs
|
||||
auto toContextMenu = ui->toTreeWidget->getItemContextMenu();
|
||||
|
|
@ -317,3 +354,46 @@ RVA XrefModel::address(const QModelIndex &index) const
|
|||
const auto &xref = xrefs.at(index.row());
|
||||
return to ? xref.from : xref.to;
|
||||
}
|
||||
|
||||
bool XrefModel::getTo() const
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
const XrefDescription *XrefModel::description(const QModelIndex &index) const
|
||||
{
|
||||
if (index.row() < xrefs.size()) {
|
||||
return &xrefs.at(index.row());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
XrefFilterProxyModel::XrefFilterProxyModel(XrefModel *source_model, QObject *parent)
|
||||
: AddressableFilterProxyModel(source_model, parent), to(source_model->getTo())
|
||||
{
|
||||
}
|
||||
|
||||
bool XrefFilterProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(row, 0, parent);
|
||||
XrefDescription xref = index.data(XrefModel::FlagDescriptionRole).value<XrefDescription>();
|
||||
return qhelpers::filterStringContains(to ? xref.to_str : xref.from_str, this);
|
||||
}
|
||||
|
||||
bool XrefFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
auto source = static_cast<XrefModel *>(sourceModel());
|
||||
auto left_item = source->description(left);
|
||||
auto right_item = source->description(right);
|
||||
|
||||
switch (left.column()) {
|
||||
case XrefModel::OFFSET:
|
||||
return to ? left_item->to < right_item->to : left_item->from < right_item->from;
|
||||
|
||||
case XrefModel::TYPE:
|
||||
return left_item->type < right_item->type;
|
||||
default:
|
||||
return sourceModel()->data(left, Qt::DisplayRole).toString()
|
||||
< sourceModel()->data(right, Qt::DisplayRole).toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "common/Highlighter.h"
|
||||
#include "core/Cutter.h"
|
||||
#include "common/AddressableItemModel.h"
|
||||
#include "QuickFilterView.h"
|
||||
|
||||
class XrefModel : public AddressableItemModel<QAbstractListModel>
|
||||
{
|
||||
|
|
@ -32,6 +33,23 @@ public:
|
|||
RVA address(const QModelIndex &index) const override;
|
||||
|
||||
static QString xrefTypeString(const QString &type);
|
||||
bool getTo() const;
|
||||
|
||||
const XrefDescription *description(const QModelIndex &index) const;
|
||||
};
|
||||
|
||||
class XrefFilterProxyModel : public AddressableFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XrefFilterProxyModel(XrefModel *source_model, QObject *parent = nullptr);
|
||||
|
||||
private:
|
||||
bool to;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int row, const QModelIndex &parent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
};
|
||||
|
||||
class MainWindow;
|
||||
|
|
@ -73,7 +91,9 @@ private:
|
|||
RVA addr;
|
||||
QString func_name;
|
||||
XrefModel toModel;
|
||||
XrefFilterProxyModel toProxyModel;
|
||||
XrefModel fromModel;
|
||||
XrefFilterProxyModel fromProxyModel;
|
||||
|
||||
std::unique_ptr<Ui::XrefsDialog> ui;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="handleWidth">
|
||||
<number>5</number>
|
||||
|
|
@ -49,13 +49,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QuickFilterView" name="toQuickFilter" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AddressableItemList<>" name="toTreeWidget">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
<enum>QFrame::Shape::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
<enum>QFrame::Shadow::Plain</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>5</number>
|
||||
|
|
@ -72,13 +75,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QuickFilterView" name="fromQuickFilter" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AddressableItemList<>" name="fromTreeWidget">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
<enum>QFrame::Shape::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
<enum>QFrame::Shadow::Plain</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>5</number>
|
||||
|
|
@ -102,16 +108,16 @@
|
|||
<item>
|
||||
<widget class="QPlainTextEdit" name="previewTextEdit">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
<enum>QFrame::Shape::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
<enum>QFrame::Shadow::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QPlainTextEdit::NoWrap</enum>
|
||||
<enum>QPlainTextEdit::LineWrapMode::NoWrap</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
|
|
@ -120,7 +126,7 @@
|
|||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
|
||||
<set>Qt::TextInteractionFlag::TextSelectableByKeyboard|Qt::TextInteractionFlag::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -131,10 +137,10 @@
|
|||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
<set>QDialogButtonBox::StandardButton::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -145,6 +151,13 @@
|
|||
<class>AddressableItemList<></class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>widgets/AddressableItemList.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QuickFilterView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>widgets/QuickFilterView.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue