Commit f5360795 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger: Streamline watch editing code.

Implement WatchModel::data() to return the right values
for Qt::EditRole, obsoleting the role matching in the delegate.
Similarly, handle Qt::EditRole in setData(), leaving only
'Change watch expression' in the delegate, which removes
and recreates a row, causing crashes when done in setData().
parent b87edd82
......@@ -240,8 +240,6 @@ enum ModelRoles
RequestToggleWatchRole,
RequestToolTipByExpressionRole,
RequestClearCppCodeModelSnapshotRole,
RequestAssignValueRole,
RequestAssignTypeRole,
RequestWatchExpressionRole,
RequestRemoveWatchExpressionRole,
......
......@@ -279,10 +279,11 @@ static inline QRegExp stdStringRegExp(const QString &charType)
return re;
}
static QByteArray niceTypeHelper(const QByteArray typeIn)
static QString niceTypeHelper(const QByteArray &typeIn)
{
static QMap<QByteArray, QByteArray> cache;
const QMap<QByteArray, QByteArray>::const_iterator it = cache.constFind(typeIn);
typedef QMap<QByteArray, QString> Cache;
static Cache cache;
const Cache::const_iterator it = cache.constFind(typeIn);
if (it != cache.constEnd())
return it.value();
......@@ -375,20 +376,24 @@ static QByteArray niceTypeHelper(const QByteArray typeIn)
}
}
}
QByteArray typeOut = type.toUtf8();
typeOut.replace('@', '*');
typeOut.replace(" >", ">");
cache.insert(typeIn, typeOut); // For simplicity, also cache unmodified types
return typeOut;
type.replace(QLatin1Char('@'), QLatin1Char('*'));
type.replace(QLatin1String(" >"), QLatin1String(">"));
cache.insert(typeIn, type); // For simplicity, also cache unmodified types
return type;
}
QByteArray WatchModel::niceType(const QByteArray &typeIn) const
QString WatchModel::displayType(const WatchData &data) const
{
QByteArray type = niceTypeHelper(typeIn);
if (!data.displayedType.isEmpty())
return data.displayedType;
QString type = niceTypeHelper(data.type);
if (!theDebuggerBoolSetting(ShowStdNamespace))
type.replace("std::", "");
if (!theDebuggerBoolSetting(ShowQtNamespace))
type.replace(engine()->qtNamespace(), "");
type.remove(QLatin1String("std::"));
if (!theDebuggerBoolSetting(ShowQtNamespace)) {
const QString qtNamespace = QString::fromLatin1(engine()->qtNamespace());
if (!qtNamespace.isEmpty())
type.remove(qtNamespace);
}
return type;
}
......@@ -712,30 +717,31 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
return QVariant(16);
return QVariant(formatToIntegerBase(itemFormat(data)));
case Qt::EditRole:
case Qt::DisplayRole: {
switch (idx.column()) {
case 0:
return QVariant(expression(item));
case 1:
return editValue(data);
case 2:
if (!data.displayedType.isEmpty()) // To be tested: Can debuggers handle those?
return data.displayedType;
return QString::fromUtf8(data.type);
default: break;
} // switch editrole column
case Qt::DisplayRole:
switch (idx.column()) {
case 0:
if (data.name.isEmpty() && role == Qt::DisplayRole)
if (data.name.isEmpty())
return tr("<Edit>");
if (data.name == QLatin1String("*") && item->parent)
return QVariant(QLatin1Char('*') + item->parent->name);
return data.name;
case 1:
if (role == Qt::DisplayRole) {
return truncateValue(formattedValue(data, itemFormat(data)));
} else {
return editValue(data);
}
case 2: {
if (!data.displayedType.isEmpty())
return data.displayedType;
return QString::fromUtf8(niceType(data.type));
}
return truncateValue(formattedValue(data, itemFormat(data)));
case 2:
return displayType(data);
default: break;
}
break;
}
} // switch editrole column
case Qt::ToolTipRole:
return theDebuggerBoolSetting(UseToolTipsInLocalsView)
? data.toToolTip() : QVariant();
......@@ -855,6 +861,17 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro
WatchItem &data = *watchItem(index);
switch (role) {
case Qt::EditRole:
switch (index.column()) {
case 0: // Watch expression: See delegate.
break;
case 1: // Change value
engine()->assignValueInDebugger(&data, expression(&data), value);
break;
case 2: // TODO: Implement change type.
engine()->assignValueInDebugger(&data, expression(&data), value);
break;
}
case LocalsExpandedRole:
if (value.toBool()) {
// Should already have been triggered by fetchMore()
......@@ -888,13 +905,6 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro
case RequestWatchExpressionRole:
m_handler->watchExpression(value.toString());
break;
case RequestAssignValueRole:
engine()->assignValueInDebugger(&data, expression(&data), value);
return true;
case RequestAssignTypeRole: // TODO: Implement.
engine()->assignValueInDebugger(&data, expression(&data), value);
return true;
}
emit dataChanged(index, index);
......
......@@ -119,7 +119,7 @@ signals:
void enableUpdates(bool);
private:
QByteArray niceType(const QByteArray &typeIn) const;
QString displayType(const WatchData &typeIn) const;
void formatRequests(QByteArray *out, const WatchItem *item) const;
DebuggerEngine *engine() const;
int itemFormat(const WatchData &data) const;
......
......@@ -40,17 +40,13 @@
#include <utils/savedaction.h>
#include <QtCore/QDebug>
#include <QtCore/QTimer>
#include <QtCore/QVariant>
#include <QtCore/QMetaProperty>
#include <QtCore/QMetaObject>
#include <QtGui/QAction>
#include <QtGui/QContextMenuEvent>
#include <QtGui/QDialog>
#include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QItemDelegate>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QMenu>
#include <QtGui/QResizeEvent>
......@@ -66,7 +62,7 @@ using namespace Debugger::Internal;
class WatchDelegate : public QItemDelegate
{
public:
WatchDelegate(QObject *parent) : QItemDelegate(parent) {}
explicit WatchDelegate(QObject *parent) : QItemDelegate(parent) {}
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
const QModelIndex &index) const
......@@ -89,46 +85,23 @@ public:
return new QLineEdit(parent);
}
void setEditorData(QWidget *editor, const QModelIndex &index) const
{
if (index.column() == 1) {
editor->setProperty("modelData", index.data(Qt::EditRole));
return;
}
QLineEdit *lineEdit = qobject_cast<QLineEdit *>(editor);
QTC_ASSERT(lineEdit, return);
if (index.column() == 0) {
// Watch window: Edit expression in name column.
lineEdit->setText(index.data(LocalsExpressionRole).toString());
} else {
// To be implemented: Edit type (of a pointer, say).
lineEdit->setText(index.data(Qt::EditRole).toString());
}
}
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
const QModelIndex &index) const
{
if (index.column() == 1) { // The value column.
const QVariant value = editor->property("modelData");
QTC_ASSERT(value.isValid(), return);
model->setData(index, value, RequestAssignValueRole);
// Standard handling for anything but the watcher name column (change
// expression), which removes/recreates a row, which cannot be done
// in model->setData().
if (index.column() != 0) {
QItemDelegate::setModelData(editor, model, index);
return;
}
//qDebug() << "SET MODEL DATA";
const QLineEdit *lineEdit = qobject_cast<const QLineEdit*>(editor);
QTC_ASSERT(lineEdit, return);
const QString value = lineEdit->text();
if (index.column() == 2) {
// The type column.
model->setData(index, QVariant(value), RequestAssignTypeRole);
} else if (index.column() == 0) {
// The watcher name column: Change the expression.
const QString exp = index.data(LocalsExpressionRole).toString();
if (exp != value ) {
model->setData(index, exp, RequestRemoveWatchExpressionRole);
model->setData(index, value, RequestWatchExpressionRole);
}
const QMetaProperty userProperty = editor->metaObject()->userProperty();
QTC_ASSERT(userProperty.isValid(), return);
const QVariant value = editor->property(userProperty.name());
const QString exp = index.data(LocalsExpressionRole).toString();
if (exp != value.toString()) {
model->setData(index, exp, RequestRemoveWatchExpressionRole);
model->setData(index, value, RequestWatchExpressionRole);
}
}
......@@ -139,7 +112,6 @@ public:
}
};
/////////////////////////////////////////////////////////////////////
//
// WatchWindow
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment