mirror of
https://github.com/rizinorg/cutter.git
synced 2025-02-01 00:57:26 +00:00
1f133741ab
Adds Quick Filter and generic address-based context menu entries to the existing ClassesWidget. The original ClassesWidget.ui is not used anymore as the layout is provided by ListDockWidget and only adjusted. The AddressableItemContextMenu may now also optionally be shown when there no currently selected item by using setShowItemContextMenuWithoutAddress(). This is used e.g. to display the "Create Class" option when nothing is present in the list. Fixes #2237 Co-authored-by: Tristan Crawford <tristanthtcrawford@gmail.com>
114 lines
3.7 KiB
C++
114 lines
3.7 KiB
C++
#ifndef ADDRESSABLE_ITEM_LIST_H
|
|
#define ADDRESSABLE_ITEM_LIST_H
|
|
|
|
#include <memory>
|
|
#include <QAbstractItemModel>
|
|
#include <QSortFilterProxyModel>
|
|
#include <QAbstractItemView>
|
|
#include <QMenu>
|
|
|
|
#include "core/Cutter.h"
|
|
#include "common/AddressableItemModel.h"
|
|
#include "CutterDockWidget.h"
|
|
#include "CutterTreeWidget.h"
|
|
#include "menus/AddressableItemContextMenu.h"
|
|
#include "CutterTreeView.h"
|
|
|
|
class MainWindow;
|
|
|
|
template<class BaseListWidget = CutterTreeView>
|
|
class AddressableItemList : public BaseListWidget
|
|
{
|
|
static_assert(std::is_base_of<QAbstractItemView, BaseListWidget>::value,
|
|
"ParentModel needs to inherit from QAbstractItemModel");
|
|
|
|
public:
|
|
explicit AddressableItemList(QWidget *parent = nullptr) : BaseListWidget(parent)
|
|
{
|
|
this->connect(this, &QWidget::customContextMenuRequested, this,
|
|
&AddressableItemList<BaseListWidget>::showItemContextMenu);
|
|
this->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
this->connect(this, &QAbstractItemView::activated, this,
|
|
&AddressableItemList<BaseListWidget>::onItemActivated);
|
|
}
|
|
|
|
void setModel(AddressableItemModelI *addressableItemModel)
|
|
{
|
|
this->addressableModel = addressableItemModel;
|
|
|
|
BaseListWidget::setModel(this->addressableModel->asItemModel());
|
|
|
|
this->connect(this->selectionModel(), &QItemSelectionModel::currentChanged, this,
|
|
&AddressableItemList<BaseListWidget>::onSelectedItemChanged);
|
|
}
|
|
void setMainWindow(MainWindow *mainWindow)
|
|
{
|
|
this->mainWindow = mainWindow;
|
|
setItemContextMenu(new AddressableItemContextMenu(this, mainWindow));
|
|
this->addActions(this->getItemContextMenu()->actions());
|
|
}
|
|
|
|
AddressableItemContextMenu *getItemContextMenu() { return itemContextMenu; }
|
|
void setItemContextMenu(AddressableItemContextMenu *menu)
|
|
{
|
|
if (itemContextMenu != menu && itemContextMenu) {
|
|
itemContextMenu->deleteLater();
|
|
}
|
|
itemContextMenu = menu;
|
|
}
|
|
|
|
/**
|
|
* If this is set to true, the context menu will also be shown if no item
|
|
* is currently selected.
|
|
*/
|
|
void setShowItemContextMenuWithoutAddress(bool val) { showItemContextMenuWithoutAddress = val; }
|
|
|
|
protected:
|
|
virtual void showItemContextMenu(const QPoint &pt)
|
|
{
|
|
if (!itemContextMenu) {
|
|
return;
|
|
}
|
|
auto index = this->currentIndex();
|
|
if (index.isValid()) {
|
|
auto offset = addressableModel->address(index);
|
|
auto name = addressableModel->name(index);
|
|
itemContextMenu->setTarget(offset, name);
|
|
} else {
|
|
if (!showItemContextMenuWithoutAddress) {
|
|
return;
|
|
}
|
|
itemContextMenu->clearTarget();
|
|
}
|
|
itemContextMenu->exec(this->mapToGlobal(pt));
|
|
}
|
|
|
|
virtual void onItemActivated(const QModelIndex &index)
|
|
{
|
|
if (!index.isValid())
|
|
return;
|
|
|
|
auto offset = addressableModel->address(index);
|
|
Core()->seekAndShow(offset);
|
|
}
|
|
virtual void onSelectedItemChanged(const QModelIndex &index) { updateMenuFromItem(index); }
|
|
void updateMenuFromItem(const QModelIndex &index)
|
|
{
|
|
if (index.isValid()) {
|
|
auto offset = addressableModel->address(index);
|
|
auto name = addressableModel->name(index);
|
|
itemContextMenu->setTarget(offset, name);
|
|
} else {
|
|
itemContextMenu->clearTarget();
|
|
}
|
|
}
|
|
|
|
private:
|
|
bool showItemContextMenuWithoutAddress = false;
|
|
AddressableItemModelI *addressableModel = nullptr;
|
|
AddressableItemContextMenu *itemContextMenu = nullptr;
|
|
MainWindow *mainWindow = nullptr;
|
|
};
|
|
|
|
#endif // ADDRESSABLE_ITEM_LIST_H
|