TreeView: Fix mapping to source models in case ProxyModels are involved

Visible e.g. in context menu handling of the debugger's module view.

Change-Id: I342ed262c9e3dcdf98590003a7930cb8ef4ca0d2
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2019-02-28 15:21:50 +01:00
parent 5ca9ac4777
commit f7c350d782
7 changed files with 34 additions and 9 deletions

View File

@@ -28,6 +28,7 @@
#include "progressindicator.h"
#include "treemodel.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QDebug>
@@ -39,6 +40,7 @@
#include <QMenu>
#include <QMouseEvent>
#include <QSettings>
#include <QSortFilterProxyModel>
#include <QTimer>
namespace Utils {
@@ -427,6 +429,14 @@ void BaseTreeView::mousePressEvent(QMouseEvent *ev)
// d->toggleColumnWidth(columnAt(ev->x()));
}
void BaseTreeView::mouseMoveEvent(QMouseEvent *ev)
{
ItemViewEvent ive(ev, this);
QTC_ASSERT(model(), return);
if (!model()->setData(ive.index(), QVariant::fromValue(ive), ItemViewEventRole))
TreeView::mouseMoveEvent(ev);
}
void BaseTreeView::mouseReleaseEvent(QMouseEvent *ev)
{
ItemViewEvent ive(ev, this);
@@ -587,11 +597,23 @@ ItemViewEvent::ItemViewEvent(QEvent *ev, QAbstractItemView *view)
m_selectedRows.append(current);
}
}
auto fixIndex = [view](QModelIndex idx) {
QAbstractItemModel *model = view->model();
while (auto proxy = qobject_cast<QSortFilterProxyModel *>(model)) {
idx = proxy->mapToSource(idx);
model = proxy->sourceModel();
}
return idx;
};
m_sourceModelIndex = fixIndex(m_index);
m_selectedRows = Utils::transform(m_selectedRows, fixIndex);
}
QModelIndexList ItemViewEvent::currentOrSelectedRows() const
{
return m_selectedRows.isEmpty() ? QModelIndexList() << m_index : m_selectedRows;
return m_selectedRows.isEmpty() ? QModelIndexList() << m_sourceModelIndex : m_selectedRows;
}
} // namespace Utils

View File

@@ -60,6 +60,7 @@ public:
void setModel(QAbstractItemModel *model) override;
void mousePressEvent(QMouseEvent *ev) override;
void mouseMoveEvent(QMouseEvent *ev) override;
void mouseReleaseEvent(QMouseEvent *ev) override;
void contextMenuEvent(QContextMenuEvent *ev) override;
void showEvent(QShowEvent *ev) override;
@@ -134,6 +135,7 @@ public:
QPoint pos() const { return m_pos; }
QPoint globalPos() const { return m_view->mapToGlobal(m_pos); }
QModelIndex index() const { return m_index; }
QModelIndex sourceModelIndex() const { return m_sourceModelIndex; }
QModelIndexList selectedRows() const { return m_selectedRows; }
QModelIndexList currentOrSelectedRows() const;
@@ -142,6 +144,7 @@ private:
QWidget *m_view = nullptr;
QPoint m_pos;
QModelIndex m_index;
QModelIndex m_sourceModelIndex;
QModelIndexList m_selectedRows;
};

View File

@@ -1661,8 +1661,8 @@ bool BreakHandler::contextMenuEvent(const ItemViewEvent &ev)
// Delete by file: Find indices of breakpoints of the same file.
QList<Breakpoint> breakpointsInFile;
QString file;
if (Breakpoint bp = itemForIndexAtLevel<1>(ev.index())) {
const QModelIndex index = ev.index().sibling(ev.index().row(), BreakpointFileColumn);
if (Breakpoint bp = itemForIndexAtLevel<1>(ev.sourceModelIndex())) {
const QModelIndex index = ev.sourceModelIndex().sibling(ev.sourceModelIndex().row(), BreakpointFileColumn);
if (!file.isEmpty()) {
for (int i = 0; i != rowCount(); ++i)
if (index.data().toString() == file)
@@ -2626,7 +2626,7 @@ bool BreakpointManager::contextMenuEvent(const ItemViewEvent &ev)
// Delete by file: Find indices of breakpoints of the same file.
GlobalBreakpoints breakpointsInFile;
QString file;
if (GlobalBreakpoint gbp = itemForIndexAtLevel<1>(ev.index())) {
if (GlobalBreakpoint gbp = itemForIndexAtLevel<1>(ev.sourceModelIndex())) {
if (!file.isEmpty()) {
for (int i = 0; i != rowCount(); ++i)
if (gbp->markerFileName() == file)

View File

@@ -171,7 +171,7 @@ public:
bool ModulesModel::contextMenuEvent(const ItemViewEvent &ev)
{
ModuleItem *item = itemForIndexAtLevel<1>(ev.index());
ModuleItem *item = itemForIndexAtLevel<1>(ev.sourceModelIndex());
const bool enabled = engine->debuggerActionsEnabled();
const bool canReload = engine->hasCapability(ReloadModuleCapability);

View File

@@ -679,8 +679,8 @@ bool RegisterHandler::contextMenuEvent(const ItemViewEvent &ev)
const DebuggerState state = m_engine->state();
const bool actionsEnabled = m_engine->debuggerActionsEnabled();
RegisterItem *registerItem = itemForIndexAtLevel<1>(ev.index());
RegisterSubItem *registerSubItem = itemForIndexAtLevel<2>(ev.index());
RegisterItem *registerItem = itemForIndexAtLevel<1>(ev.sourceModelIndex());
RegisterSubItem *registerSubItem = itemForIndexAtLevel<2>(ev.sourceModelIndex());
const quint64 address = registerItem ? registerItem->addressValue() : 0;
const QString registerName = registerItem ? registerItem->m_reg.name : QString();

View File

@@ -367,7 +367,7 @@ bool StackHandler::contextMenuEvent(const ItemViewEvent &ev)
{
auto menu = new QMenu;
const int row = ev.index().row();
const int row = ev.sourceModelIndex().row();
StackFrame frame;
if (row >= 0 && row < stackSize())
frame = frameAt(row);

View File

@@ -1638,7 +1638,7 @@ void WatchModel::inputNewExpression()
bool WatchModel::contextMenuEvent(const ItemViewEvent &ev)
{
WatchItem *item = itemForIndex(ev.index());
WatchItem *item = itemForIndex(ev.sourceModelIndex());
const QString exp = item ? item->expression() : QString();
const QString name = item ? item->name : QString();