forked from qt-creator/qt-creator
Debugger: Make (sub-)registers editable
Change-Id: Ibca2808513b6784b65d5c7223717a8b1d930c381 Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com> Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
@@ -1278,6 +1278,19 @@ class Dumper(DumperBase):
|
|||||||
result += ']'
|
result += ']'
|
||||||
self.report(result)
|
self.report(result)
|
||||||
|
|
||||||
|
def setRegister(self, args):
|
||||||
|
self.reportToken(args)
|
||||||
|
name = args["name"]
|
||||||
|
value = args["value"]
|
||||||
|
result = lldb.SBCommandReturnObject()
|
||||||
|
self.debugger.GetCommandInterpreter().HandleCommand(
|
||||||
|
"register write %s %s" % (name, value), result)
|
||||||
|
success = result.Succeeded()
|
||||||
|
if success:
|
||||||
|
self.report('output="%s"' % result.GetOutput())
|
||||||
|
else:
|
||||||
|
self.report('error="%s"' % result.GetError())
|
||||||
|
|
||||||
def report(self, stuff):
|
def report(self, stuff):
|
||||||
with self.outputLock:
|
with self.outputLock:
|
||||||
sys.stdout.write("@\n" + stuff + "@\n")
|
sys.stdout.write("@\n" + stuff + "@\n")
|
||||||
|
|||||||
@@ -1672,7 +1672,7 @@ void CdbEngine::handleRegistersExt(const DebuggerResponse &response)
|
|||||||
reg.name = item["name"].data();
|
reg.name = item["name"].data();
|
||||||
reg.description = item["description"].data();
|
reg.description = item["description"].data();
|
||||||
reg.reportedType = item["type"].data();
|
reg.reportedType = item["type"].data();
|
||||||
reg.value = item["value"].data();
|
reg.value.fromByteArray(item["value"].data(), HexadecimalFormat);
|
||||||
reg.size = item["size"].data().toInt();
|
reg.size = item["size"].data().toInt();
|
||||||
handler->updateRegister(reg);
|
handler->updateRegister(reg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ public:
|
|||||||
m_remoteSetupState(RemoteSetupNone),
|
m_remoteSetupState(RemoteSetupNone),
|
||||||
m_inferiorPid(0),
|
m_inferiorPid(0),
|
||||||
m_modulesHandler(engine),
|
m_modulesHandler(engine),
|
||||||
m_registerHandler(),
|
m_registerHandler(engine),
|
||||||
m_sourceFilesHandler(),
|
m_sourceFilesHandler(),
|
||||||
m_stackHandler(),
|
m_stackHandler(),
|
||||||
m_threadsHandler(),
|
m_threadsHandler(),
|
||||||
|
|||||||
@@ -3632,14 +3632,18 @@ void GdbEngine::handleMaintPrintRegisters(const DebuggerResponse &response)
|
|||||||
readWord(ba, &pos); // Offset
|
readWord(ba, &pos); // Offset
|
||||||
reg.size = readWord(ba, &pos).toInt();
|
reg.size = readWord(ba, &pos).toInt();
|
||||||
reg.reportedType = readWord(ba, &pos);
|
reg.reportedType = readWord(ba, &pos);
|
||||||
reg.value = readWord(ba, &pos);
|
reg.value.fromByteArray(readWord(ba, &pos), HexadecimalFormat);
|
||||||
handler->updateRegister(reg);
|
handler->updateRegister(reg);
|
||||||
}
|
}
|
||||||
handler->commitUpdates();
|
handler->commitUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::setRegisterValue(const QByteArray &name, const QString &value)
|
void GdbEngine::setRegisterValue(const QByteArray &name, const QString &value)
|
||||||
{
|
{
|
||||||
postCommand("set $" + name + "=" + value.toLatin1());
|
QByteArray fullName = name;
|
||||||
|
if (name.startsWith("xmm"))
|
||||||
|
fullName += ".uint128";
|
||||||
|
postCommand("set $" + fullName + "=" + value.toLatin1());
|
||||||
reloadRegisters();
|
reloadRegisters();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3705,7 +3709,7 @@ void GdbEngine::handleRegisterListValues(const DebuggerResponse &response)
|
|||||||
Register reg = m_registers[number];
|
Register reg = m_registers[number];
|
||||||
QByteArray data = item["value"].data();
|
QByteArray data = item["value"].data();
|
||||||
if (data.startsWith("0x")) {
|
if (data.startsWith("0x")) {
|
||||||
reg.value = data;
|
reg.value.fromByteArray(data, HexadecimalFormat);
|
||||||
} else if (data == "<error reading variable>") {
|
} else if (data == "<error reading variable>") {
|
||||||
// Nothing. See QTCREATORBUG-14029.
|
// Nothing. See QTCREATORBUG-14029.
|
||||||
} else {
|
} else {
|
||||||
@@ -3718,7 +3722,7 @@ void GdbEngine::handleRegisterListValues(const DebuggerResponse &response)
|
|||||||
// v2_int64 = {0x0000000000000000, 0x0000000000000000},
|
// v2_int64 = {0x0000000000000000, 0x0000000000000000},
|
||||||
// uint128 = <error reading variable>}"}
|
// uint128 = <error reading variable>}"}
|
||||||
// Try to make sense of it using the int32 chunks:
|
// Try to make sense of it using the int32 chunks:
|
||||||
QByteArray result = "0x";
|
QByteArray result;
|
||||||
const int pos1 = data.indexOf("_int32");
|
const int pos1 = data.indexOf("_int32");
|
||||||
const int pos2 = data.indexOf('{', pos1) + 1;
|
const int pos2 = data.indexOf('{', pos1) + 1;
|
||||||
const int pos3 = data.indexOf('}', pos2);
|
const int pos3 = data.indexOf('}', pos2);
|
||||||
@@ -3733,7 +3737,7 @@ void GdbEngine::handleRegisterListValues(const DebuggerResponse &response)
|
|||||||
QTC_ASSERT(chunk.size() == 8, continue);
|
QTC_ASSERT(chunk.size() == 8, continue);
|
||||||
result.append(chunk);
|
result.append(chunk);
|
||||||
}
|
}
|
||||||
reg.value = result;
|
reg.value.fromByteArray(result, HexadecimalFormat);
|
||||||
}
|
}
|
||||||
handler->updateRegister(reg);
|
handler->updateRegister(reg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1033,9 +1033,11 @@ void LldbEngine::refreshRegisters(const GdbMi ®isters)
|
|||||||
foreach (const GdbMi &item, registers.children()) {
|
foreach (const GdbMi &item, registers.children()) {
|
||||||
Register reg;
|
Register reg;
|
||||||
reg.name = item["name"].data();
|
reg.name = item["name"].data();
|
||||||
reg.value = item["value"].data();
|
reg.value.fromByteArray(item["value"].data(), HexadecimalFormat);
|
||||||
reg.size = item["size"].data().toInt();
|
reg.size = item["size"].data().toInt();
|
||||||
reg.reportedType = item["type"].data();
|
reg.reportedType = item["type"].data();
|
||||||
|
if (reg.reportedType.startsWith("unsigned"))
|
||||||
|
reg.kind = IntegerRegister;
|
||||||
handler->updateRegister(reg);
|
handler->updateRegister(reg);
|
||||||
}
|
}
|
||||||
handler->commitUpdates();
|
handler->commitUpdates();
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "registerhandler.h"
|
#include "registerhandler.h"
|
||||||
|
|
||||||
|
#include "debuggerengine.h"
|
||||||
#include "watchdelegatewidgets.h"
|
#include "watchdelegatewidgets.h"
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -100,27 +102,37 @@ static uint decodeHexChar(unsigned char c)
|
|||||||
return uint(-1);
|
return uint(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterValue::operator=(const QByteArray &ba)
|
void RegisterValue::fromByteArray(const QByteArray &ba, RegisterFormat format)
|
||||||
{
|
{
|
||||||
known = !ba.isEmpty();
|
known = !ba.isEmpty();
|
||||||
uint shift = 0;
|
|
||||||
int j = 0;
|
|
||||||
v.u64[1] = v.u64[0] = 0;
|
v.u64[1] = v.u64[0] = 0;
|
||||||
for (int i = ba.size(); --i >= 0 && j < 16; ++j) {
|
|
||||||
quint64 d = decodeHexChar(ba.at(i));
|
const int n = ba.size();
|
||||||
if (d == uint(-1))
|
int pos = 0;
|
||||||
return;
|
if (ba.startsWith("0x"))
|
||||||
v.u64[0] |= (d << shift);
|
pos += 2;
|
||||||
shift += 4;
|
|
||||||
|
bool negative = pos < n && ba.at(pos) == '-';
|
||||||
|
if (negative)
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
while (pos < n) {
|
||||||
|
uint c = ba.at(pos);
|
||||||
|
if (format != CharacterFormat) {
|
||||||
|
c = decodeHexChar(c);
|
||||||
|
if (c == uint(-1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
shiftOneDigit(c, format);
|
||||||
|
++pos;
|
||||||
}
|
}
|
||||||
j = 0;
|
|
||||||
shift = 0;
|
if (negative) {
|
||||||
for (int i = ba.size() - 16; --i >= 0 && j < 16; ++j) {
|
v.u64[1] = ~v.u64[1];
|
||||||
quint64 d = decodeHexChar(ba.at(i));
|
v.u64[0] = ~v.u64[0];
|
||||||
if (d == uint(-1))
|
++v.u64[0];
|
||||||
return;
|
if (v.u64[0] == 0)
|
||||||
v.u64[1] |= (d << shift);
|
++v.u64[1];
|
||||||
shift += 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,18 +217,102 @@ RegisterValue RegisterValue::subValue(int size, int index) const
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterValue::setSubValue(int size, int index, RegisterValue subValue)
|
||||||
|
{
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
v.u8[index] = subValue.v.u8[0];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
v.u16[index] = subValue.v.u16[0];
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
v.u32[index] = subValue.v.u32[0];
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
v.u64[index] = subValue.v.u64[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void shiftBitsLeft(RegisterValue *val, int amount)
|
||||||
|
{
|
||||||
|
val->v.u64[1] <<= amount;
|
||||||
|
val->v.u64[1] |= val->v.u64[0] >> (64 - amount);
|
||||||
|
val->v.u64[0] <<= amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterValue::shiftOneDigit(uint digit, RegisterFormat format)
|
||||||
|
{
|
||||||
|
switch (format) {
|
||||||
|
case HexadecimalFormat:
|
||||||
|
shiftBitsLeft(this, 4);
|
||||||
|
v.u64[0] |= digit;
|
||||||
|
break;
|
||||||
|
case OctalFormat:
|
||||||
|
shiftBitsLeft(this, 3);
|
||||||
|
v.u64[0] |= digit;
|
||||||
|
break;
|
||||||
|
case BinaryFormat:
|
||||||
|
shiftBitsLeft(this, 1);
|
||||||
|
v.u64[0] |= digit;
|
||||||
|
break;
|
||||||
|
case DecimalFormat:
|
||||||
|
case SignedDecimalFormat: {
|
||||||
|
shiftBitsLeft(this, 1);
|
||||||
|
quint64 tmp0 = v.u64[0];
|
||||||
|
quint64 tmp1 = v.u64[1];
|
||||||
|
shiftBitsLeft(this, 2);
|
||||||
|
v.u64[1] += tmp1;
|
||||||
|
v.u64[0] += tmp0;
|
||||||
|
if (v.u64[0] < tmp0)
|
||||||
|
++v.u64[1];
|
||||||
|
v.u64[0] += digit;
|
||||||
|
if (v.u64[0] < digit)
|
||||||
|
++v.u64[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CharacterFormat:
|
||||||
|
shiftBitsLeft(this, 8);
|
||||||
|
v.u64[0] |= digit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// RegisterSubItem and RegisterItem
|
// RegisterSubItem and RegisterItem
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class RegisterSubItem;
|
||||||
|
|
||||||
|
class RegisterEditItem : public Utils::TreeItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RegisterEditItem(int pos, RegisterKind subKind, int subSize, RegisterFormat format)
|
||||||
|
: m_index(pos), m_subKind(subKind), m_subSize(subSize), m_subFormat(format)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QVariant data(int column, int role) const override;
|
||||||
|
bool setData(int column, const QVariant &value, int role) override;
|
||||||
|
Qt::ItemFlags flags(int column) const override;
|
||||||
|
|
||||||
|
int m_index;
|
||||||
|
RegisterKind m_subKind;
|
||||||
|
int m_subSize;
|
||||||
|
RegisterFormat m_subFormat;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class RegisterSubItem : public Utils::TreeItem
|
class RegisterSubItem : public Utils::TreeItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RegisterSubItem(RegisterKind subKind, int subSize, int count, RegisterFormat format)
|
RegisterSubItem(RegisterKind subKind, int subSize, int count, RegisterFormat format)
|
||||||
: m_subKind(subKind), m_subFormat(format), m_subSize(subSize), m_count(count), m_changed(false)
|
: m_subKind(subKind), m_subFormat(format), m_subSize(subSize), m_count(count), m_changed(false)
|
||||||
{}
|
{
|
||||||
|
for (int i = 0; i != count; ++i)
|
||||||
|
appendChild(new RegisterEditItem(i, subKind, subSize, format));
|
||||||
|
}
|
||||||
|
|
||||||
QVariant data(int column, int role) const;
|
QVariant data(int column, int role) const;
|
||||||
|
|
||||||
@@ -240,10 +336,12 @@ class RegisterItem : public Utils::TreeItem
|
|||||||
public:
|
public:
|
||||||
explicit RegisterItem(const Register ®);
|
explicit RegisterItem(const Register ®);
|
||||||
|
|
||||||
QVariant data(int column, int role) const;
|
QVariant data(int column, int role) const override;
|
||||||
Qt::ItemFlags flags(int column) const;
|
bool setData(int column, const QVariant &value, int role) override;
|
||||||
|
Qt::ItemFlags flags(int column) const override;
|
||||||
|
|
||||||
quint64 addressValue() const;
|
quint64 addressValue() const;
|
||||||
|
void triggerChange();
|
||||||
|
|
||||||
Register m_reg;
|
Register m_reg;
|
||||||
RegisterFormat m_format;
|
RegisterFormat m_format;
|
||||||
@@ -289,6 +387,13 @@ quint64 RegisterItem::addressValue() const
|
|||||||
return m_reg.value.v.u64[0];
|
return m_reg.value.v.u64[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterItem::triggerChange()
|
||||||
|
{
|
||||||
|
QByteArray ba = "0x" + m_reg.value.toByteArray(m_reg.kind, m_reg.size, HexadecimalFormat);
|
||||||
|
DebuggerEngine *engine = static_cast<RegisterHandler *>(model())->engine();
|
||||||
|
engine->setRegisterValue(m_reg.name, QString::fromLatin1(ba));
|
||||||
|
}
|
||||||
|
|
||||||
QVariant RegisterItem::data(int column, int role) const
|
QVariant RegisterItem::data(int column, int role) const
|
||||||
{
|
{
|
||||||
switch (role) {
|
switch (role) {
|
||||||
@@ -326,7 +431,7 @@ QVariant RegisterItem::data(int column, int role) const
|
|||||||
.arg(QString::fromLatin1(m_reg.previousValue.toByteArray(m_reg.kind, m_reg.size, m_format)));
|
.arg(QString::fromLatin1(m_reg.previousValue.toByteArray(m_reg.kind, m_reg.size, m_format)));
|
||||||
|
|
||||||
case Qt::EditRole: // Edit: Unpadded for editing
|
case Qt::EditRole: // Edit: Unpadded for editing
|
||||||
return m_reg.value.toByteArray(m_reg.kind, m_reg.size, m_format);
|
return QString::fromLatin1(m_reg.value.toByteArray(m_reg.kind, m_reg.size, m_format));
|
||||||
|
|
||||||
case Qt::TextAlignmentRole:
|
case Qt::TextAlignmentRole:
|
||||||
return column == RegisterValueColumn ? QVariant(Qt::AlignRight) : QVariant();
|
return column == RegisterValueColumn ? QVariant(Qt::AlignRight) : QVariant();
|
||||||
@@ -337,6 +442,16 @@ QVariant RegisterItem::data(int column, int role) const
|
|||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RegisterItem::setData(int column, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (column == RegisterValueColumn && role == Qt::EditRole) {
|
||||||
|
m_reg.value.fromByteArray(value.toString().toLatin1(), m_format);
|
||||||
|
triggerChange();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QVariant RegisterSubItem::data(int column, int role) const
|
QVariant RegisterSubItem::data(int column, int role) const
|
||||||
{
|
{
|
||||||
switch (role) {
|
switch (role) {
|
||||||
@@ -401,10 +516,11 @@ QVariant RegisterSubItem::data(int column, int role) const
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
RegisterHandler::RegisterHandler()
|
RegisterHandler::RegisterHandler(DebuggerEngine *engine)
|
||||||
|
: m_engine(engine)
|
||||||
{
|
{
|
||||||
setObjectName(QLatin1String("RegisterModel"));
|
setObjectName(QLatin1String("RegisterModel"));
|
||||||
setHeader(QStringList() << tr("Name") << tr("Value"));
|
setHeader({tr("Name"), tr("Value")});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterHandler::updateRegister(const Register &r)
|
void RegisterHandler::updateRegister(const Register &r)
|
||||||
@@ -454,5 +570,58 @@ RegisterMap RegisterHandler::registerMap() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant RegisterEditItem::data(int column, int role) const
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
case Qt::EditRole:
|
||||||
|
switch (column) {
|
||||||
|
case RegisterNameColumn: {
|
||||||
|
return QString::fromLatin1("[%1]").arg(m_index);
|
||||||
|
}
|
||||||
|
case RegisterValueColumn: {
|
||||||
|
RegisterItem *registerItem = static_cast<RegisterItem *>(parent()->parent());
|
||||||
|
RegisterValue value = registerItem->m_reg.value;
|
||||||
|
return value.subValue(m_subSize, m_index).toByteArray(m_subKind, m_subSize, m_subFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Qt::ToolTipRole: {
|
||||||
|
RegisterItem *registerItem = static_cast<RegisterItem *>(parent()->parent());
|
||||||
|
return RegisterHandler::tr("Edit bits %1...%2 of register %3")
|
||||||
|
.arg(m_index * 8).arg(m_index * 8 + 8)
|
||||||
|
.arg(QString::fromLatin1(registerItem->m_reg.name));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RegisterEditItem::setData(int column, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (column == RegisterValueColumn && role == Qt::EditRole) {
|
||||||
|
QTC_ASSERT(parent(), return false);
|
||||||
|
QTC_ASSERT(parent()->parent(), return false);
|
||||||
|
RegisterItem *registerItem = static_cast<RegisterItem *>(parent()->parent());
|
||||||
|
Register ® = registerItem->m_reg;
|
||||||
|
RegisterValue vv;
|
||||||
|
vv.fromByteArray(value.toString().toLatin1(), m_subFormat);
|
||||||
|
reg.value.setSubValue(m_subSize, m_index, vv);
|
||||||
|
registerItem->triggerChange();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags RegisterEditItem::flags(int column) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(parent(), return Qt::ItemFlags());
|
||||||
|
RegisterSubItem *registerSubItem = static_cast<RegisterSubItem *>(parent());
|
||||||
|
Qt::ItemFlags f = registerSubItem->flags(column);
|
||||||
|
if (column == RegisterValueColumn)
|
||||||
|
f |= Qt::ItemIsEditable;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -40,6 +40,8 @@
|
|||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class DebuggerEngine;
|
||||||
|
|
||||||
enum RegisterColumns
|
enum RegisterColumns
|
||||||
{
|
{
|
||||||
RegisterNameColumn,
|
RegisterNameColumn,
|
||||||
@@ -80,11 +82,16 @@ class RegisterValue
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RegisterValue() { known = false; v.u64[1] = v.u64[0] = 0; }
|
RegisterValue() { known = false; v.u64[1] = v.u64[0] = 0; }
|
||||||
void operator=(const QByteArray &ba);
|
|
||||||
bool operator==(const RegisterValue &other);
|
bool operator==(const RegisterValue &other);
|
||||||
bool operator!=(const RegisterValue &other) { return !operator==(other); }
|
bool operator!=(const RegisterValue &other) { return !operator==(other); }
|
||||||
|
|
||||||
|
void fromByteArray(const QByteArray &ba, RegisterFormat format);
|
||||||
QByteArray toByteArray(RegisterKind kind, int size, RegisterFormat format) const;
|
QByteArray toByteArray(RegisterKind kind, int size, RegisterFormat format) const;
|
||||||
|
|
||||||
RegisterValue subValue(int size, int index) const;
|
RegisterValue subValue(int size, int index) const;
|
||||||
|
void setSubValue(int size, int index, RegisterValue subValue);
|
||||||
|
|
||||||
|
void shiftOneDigit(uint digit, RegisterFormat format);
|
||||||
|
|
||||||
union {
|
union {
|
||||||
quint8 u8[16];
|
quint8 u8[16];
|
||||||
@@ -120,9 +127,10 @@ class RegisterHandler : public Utils::TreeModel
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegisterHandler();
|
explicit RegisterHandler(DebuggerEngine *engine);
|
||||||
|
|
||||||
QAbstractItemModel *model() { return this; }
|
QAbstractItemModel *model() { return this; }
|
||||||
|
DebuggerEngine *engine() const { return m_engine; }
|
||||||
|
|
||||||
void updateRegister(const Register ®);
|
void updateRegister(const Register ®);
|
||||||
|
|
||||||
@@ -135,6 +143,7 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QHash<QByteArray, RegisterItem *> m_registerByName;
|
QHash<QByteArray, RegisterItem *> m_registerByName;
|
||||||
|
DebuggerEngine * const m_engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -63,58 +63,42 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
|
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
|
||||||
const QModelIndex &index) const
|
const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
IntegerWatchLineEdit *lineEdit = new IntegerWatchLineEdit(parent);
|
if (index.column() == RegisterValueColumn) {
|
||||||
const RegisterFormat format = RegisterFormat(index.data(RegisterFormatRole).toInt());
|
auto lineEdit = new QLineEdit(parent);
|
||||||
const bool big = index.data(RegisterIsBigRole).toBool();
|
lineEdit->setAlignment(Qt::AlignLeft);
|
||||||
// Big integers are assumed to be hexadecimal.
|
lineEdit->setFrame(false);
|
||||||
int base = 16;
|
return lineEdit;
|
||||||
if (!big) {
|
|
||||||
if (format == DecimalFormat || format == SignedDecimalFormat)
|
|
||||||
base = 10;
|
|
||||||
else if (format == OctalFormat)
|
|
||||||
base = 8;
|
|
||||||
else if (format == BinaryFormat)
|
|
||||||
base = 2;
|
|
||||||
}
|
}
|
||||||
lineEdit->setBigInt(big);
|
return 0;
|
||||||
lineEdit->setBase(base);
|
|
||||||
lineEdit->setSigned(false);
|
|
||||||
lineEdit->setAlignment(Qt::AlignRight);
|
|
||||||
lineEdit->setFrame(false);
|
|
||||||
return lineEdit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEditorData(QWidget *editor, const QModelIndex &index) const
|
void setEditorData(QWidget *editor, const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
IntegerWatchLineEdit *lineEdit = qobject_cast<IntegerWatchLineEdit *>(editor);
|
auto lineEdit = qobject_cast<QLineEdit *>(editor);
|
||||||
QTC_ASSERT(lineEdit, return);
|
QTC_ASSERT(lineEdit, return);
|
||||||
lineEdit->setModelData(index.data(Qt::EditRole));
|
lineEdit->setText(index.data(Qt::EditRole).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setModelData(QWidget *editor, QAbstractItemModel *,
|
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||||
const QModelIndex &index) const
|
const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
if (index.column() != 1)
|
if (index.column() == RegisterValueColumn) {
|
||||||
return;
|
auto lineEdit = qobject_cast<QLineEdit *>(editor);
|
||||||
IntegerWatchLineEdit *lineEdit = qobject_cast<IntegerWatchLineEdit*>(editor);
|
QTC_ASSERT(lineEdit, return);
|
||||||
QTC_ASSERT(lineEdit, return);
|
model->setData(index, lineEdit->text(), Qt::EditRole);
|
||||||
const RegisterFormat format = RegisterFormat(index.data(RegisterFormatRole).toInt());
|
}
|
||||||
QString value = lineEdit->text();
|
|
||||||
if (format == HexadecimalFormat && !value.startsWith(QLatin1String("0x")))
|
|
||||||
value.insert(0, QLatin1String("0x"));
|
|
||||||
currentEngine()->setRegisterValue(index.data(RegisterNameRole).toByteArray(), value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
|
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &) const
|
const QModelIndex &) const override
|
||||||
{
|
{
|
||||||
editor->setGeometry(option.rect);
|
editor->setGeometry(option.rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index) const
|
const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
if (index.column() == RegisterValueColumn) {
|
if (index.column() == RegisterValueColumn) {
|
||||||
const bool paintRed = index.data(RegisterChangedRole).toBool();
|
const bool paintRed = index.data(RegisterChangedRole).toBool();
|
||||||
|
|||||||
Reference in New Issue
Block a user