Changeset View
Standalone View
debuggers/gdb/memviewdlg.cpp
Show All 19 Lines | |||||
20 | #include "mi/micommand.h" | 20 | #include "mi/micommand.h" | ||
21 | 21 | | |||
22 | #include <interfaces/icore.h> | 22 | #include <interfaces/icore.h> | ||
23 | #include <interfaces/idebugcontroller.h> | 23 | #include <interfaces/idebugcontroller.h> | ||
24 | 24 | | |||
25 | #include <KLocalizedString> | 25 | #include <KLocalizedString> | ||
26 | #include <KMessageBox> | 26 | #include <KMessageBox> | ||
27 | 27 | | |||
28 | #include <khexedit/byteseditinterface.h> | 28 | #include <Okteta/ByteArrayColumnView> | ||
29 | #include <khexedit/charcolumninterface.h> | 29 | #include <Okteta/ByteArrayModel> | ||
30 | #include <khexedit/valuecolumninterface.h> | | |||
31 | 30 | | |||
32 | #include <QAction> | 31 | #include <QAction> | ||
33 | #include <QContextMenuEvent> | 32 | #include <QContextMenuEvent> | ||
34 | #include <QGridLayout> | 33 | #include <QGridLayout> | ||
35 | #include <QHBoxLayout> | 34 | #include <QHBoxLayout> | ||
36 | #include <QLabel> | 35 | #include <QLabel> | ||
37 | #include <QLayout> | 36 | #include <QLayout> | ||
38 | #include <QLineEdit> | 37 | #include <QLineEdit> | ||
39 | #include <QMenu> | 38 | #include <QMenu> | ||
40 | #include <QPushButton> | 39 | #include <QPushButton> | ||
41 | #include <QTextEdit> | 40 | #include <QTextEdit> | ||
42 | #include <QToolBox> | 41 | #include <QToolBox> | ||
43 | #include <QVariant> | 42 | #include <QVariant> | ||
44 | #include <QVBoxLayout> | 43 | #include <QVBoxLayout> | ||
45 | 44 | | |||
46 | #include <cctype> | 45 | #include <cctype> | ||
47 | 46 | | |||
48 | using namespace KDevMI::GDB; | | |||
49 | using KDevMI::MI::CommandType; | 47 | using KDevMI::MI::CommandType; | ||
50 | 48 | | |||
51 | /** Container for controls that select memory range. | 49 | namespace KDevMI | ||
50 | { | ||||
51 | namespace GDB | ||||
52 | { | ||||
52 | 53 | | |||
54 | /** Container for controls that select memory range. | ||||
55 | * | ||||
53 | The memory range selection is embedded into memory view widget, | 56 | The memory range selection is embedded into memory view widget, | ||
54 | it's not a standalone dialog. However, we want to have easy way | 57 | it's not a standalone dialog. However, we want to have easy way | ||
55 | to hide/show all controls, so we group them in this class. | 58 | to hide/show all controls, so we group them in this class. | ||
56 | */ | 59 | */ | ||
57 | class MemoryRangeSelector : public QWidget | 60 | class MemoryRangeSelector : public QWidget | ||
58 | { | 61 | { | ||
59 | public: | 62 | public: | ||
60 | QLineEdit* startAddressLineEdit; | 63 | QLineEdit* startAddressLineEdit; | ||
61 | QLineEdit* amountLineEdit; | 64 | QLineEdit* amountLineEdit; | ||
62 | QPushButton* okButton; | 65 | QPushButton* okButton; | ||
63 | QPushButton* cancelButton; | 66 | QPushButton* cancelButton; | ||
64 | 67 | | |||
65 | MemoryRangeSelector(QWidget* parent) | 68 | MemoryRangeSelector(QWidget* parent) | ||
66 | : QWidget(parent) | 69 | : QWidget(parent) | ||
67 | { | 70 | { | ||
68 | QVBoxLayout* l = new QVBoxLayout(this); | 71 | QVBoxLayout* l = new QVBoxLayout(this); | ||
mwolff: why did you remove the this parameter everywhere? | |||||
Good question. I started getting these in the log: kdevelop(13251)/default unknown: QLayout: Attempting to add QLayout "" to KDevMI::GDB::MemoryRangeSelector "", which already has a layout Which I gather are a result of QGridLayout* gl = new QGridLayout(this); and QHBoxLayout* hb = new QHBoxLayout(this); and the subsequent calls to addLayout() and the call to setLayout(l) . I will leave remove the this pointer from the two layouts and leave the rest as is. volden: Good question. I started getting these in the log:
kdevelop(13251)/default unknown: QLayout… | |||||
Removing the this parameter is correct though for Qt5, when it comes to non-top-level layout instances. This seems a change vs. Qt4 where the this was only used for memory management, while now it is also used for defining the widget on which to use the layout as top-level layout. Which in the case of these two layouts would be not what is wanted, as also hinted by the warnings in the log. So +1 from here for removing the this parameter :) kossebau: Removing the `this` parameter is correct though for Qt5, when it comes to non-top-level layout… | |||||
consider using a .ui file generated with Qt designer instead as a follow-up cleanup mwolff: consider using a .ui file generated with Qt designer instead as a follow-up cleanup | |||||
My Plan is this:
So I plan to do some more work on some of this code and I can definitely do this as well, but I think it probably belongs in a separate differential. volden: My Plan is this:
1) Bring back memory view
2) Add an autoupdate feature to the memview (either… | |||||
69 | 72 | | |||
70 | // Grid layout: labels + address field | 73 | // Grid layout: labels + address field | ||
71 | QGridLayout* gl = new QGridLayout(this); | 74 | QGridLayout* gl = new QGridLayout(); | ||
72 | l->addLayout(gl); | 75 | l->addLayout(gl); | ||
73 | 76 | | |||
74 | QLabel* l1 = new QLabel(i18n("Start"), this); | 77 | QLabel* l1 = new QLabel(i18n("Start"), this); | ||
75 | gl->addWidget(l1, 0, 1); | 78 | gl->addWidget(l1, 0, 1); | ||
76 | 79 | | |||
77 | startAddressLineEdit = new QLineEdit(this); | 80 | startAddressLineEdit = new QLineEdit(this); | ||
78 | gl->addWidget(startAddressLineEdit, 0, 3); | 81 | gl->addWidget(startAddressLineEdit, 0, 3); | ||
79 | 82 | | |||
80 | QLabel* l2 = new QLabel(i18n("Amount"), this); | 83 | QLabel* l2 = new QLabel(i18n("Amount"), this); | ||
81 | gl->addWidget(l2, 2, 1); | 84 | gl->addWidget(l2, 2, 1); | ||
82 | 85 | | |||
83 | amountLineEdit = new QLineEdit(this); | 86 | amountLineEdit = new QLineEdit(this); | ||
84 | gl->addWidget(amountLineEdit, 2, 3); | 87 | gl->addWidget(amountLineEdit, 2, 3); | ||
85 | 88 | | |||
86 | l->addSpacing(2); | 89 | l->addSpacing(2); | ||
87 | 90 | | |||
88 | QHBoxLayout* hb = new QHBoxLayout(this); | 91 | QHBoxLayout* hb = new QHBoxLayout(); | ||
89 | l->addLayout(hb); | 92 | l->addLayout(hb); | ||
90 | hb->addStretch(); | 93 | hb->addStretch(); | ||
91 | 94 | | |||
92 | okButton = new QPushButton(i18n("OK"), this); | 95 | okButton = new QPushButton(i18n("OK"), this); | ||
93 | hb->addWidget(okButton); | 96 | hb->addWidget(okButton); | ||
94 | 97 | | |||
95 | cancelButton = new QPushButton(i18n("Cancel"), this); | 98 | cancelButton = new QPushButton(i18n("Cancel"), this); | ||
96 | hb->addWidget(cancelButton); | 99 | hb->addWidget(cancelButton); | ||
97 | 100 | | |||
98 | l->addSpacing(2); | 101 | l->addSpacing(2); | ||
99 | setLayout(l); | 102 | setLayout(l); | ||
100 | 103 | | |||
101 | connect(startAddressLineEdit, SIGNAL(returnPressed()), | 104 | connect(startAddressLineEdit, &QLineEdit::returnPressed, okButton, [this]() { | ||
102 | okButton, SLOT(animateClick())); | 105 | okButton->animateClick(); | ||
103 | 106 | }); | |||
104 | connect(amountLineEdit, SIGNAL(returnPressed()), | 107 | | ||
105 | okButton, SLOT(animateClick())); | 108 | connect(amountLineEdit, &QLineEdit::returnPressed, okButton, [this]() { | ||
109 | okButton->animateClick(); | ||||
110 | }); | ||||
106 | } | 111 | } | ||
107 | }; | 112 | }; | ||
108 | 113 | | |||
109 | | ||||
110 | | ||||
111 | MemoryView::MemoryView(QWidget* parent) | 114 | MemoryView::MemoryView(QWidget* parent) | ||
please always use the 4-arg connect, i.e. pass a "this" before a lambda to make sure it gets properly unconnected when this gets deleted also, prefer explicit capture lists over the catch-all ones: =/& here, replace = with okButton mwolff: please always use the 4-arg connect, i.e. pass a "this" before a lambda to make sure it gets… | |||||
volden: Done. I assume you mean the other way around - right? | |||||
112 | : QWidget(parent), | 115 | : QWidget(parent), | ||
113 | // New memory view can be created only when debugger is active, | 116 | // New memory view can be created only when debugger is active, | ||
114 | // so don't set s_appNotStarted here. | 117 | // so don't set s_appNotStarted here. | ||
115 | khexedit2_widget(0), | 118 | m_memViewView(nullptr), | ||
116 | amount_(0), data_(0), | 119 | m_debuggerState(0) | ||
117 | debuggerState_(0) | | |||
118 | { | 120 | { | ||
kossebau: While touching the lines, nullptr for all pointers | |||||
119 | setWindowTitle(i18n("Memory view")); | 121 | setWindowTitle(i18n("Memory view")); | ||
120 | emit captionChanged(windowTitle()); | 122 | emit captionChanged(windowTitle()); | ||
121 | 123 | | |||
122 | initWidget(); | 124 | initWidget(); | ||
123 | 125 | | |||
124 | if (isOk()) | 126 | if (isOk()) | ||
125 | slotEnableOrDisable(); | 127 | slotEnableOrDisable(); | ||
126 | 128 | | |||
127 | connect(KDevelop::ICore::self()->debugController(), | 129 | auto debugController = KDevelop::ICore::self()->debugController(); | ||
128 | SIGNAL(currentSessionChanged(KDevelop::IDebugSession*)), | 130 | Q_ASSERT(debugController); | ||
129 | SLOT(currentSessionChanged(KDevelop::IDebugSession*))); | 131 | | ||
132 | connect(debugController, &KDevelop::IDebugController::currentSessionChanged, | ||||
mwolff: style:
```
connect(debugController, &...,
this, &...);
``` | |||||
133 | this, &MemoryView::currentSessionChanged); | ||||
mwolff: `auto debugController = ...` | |||||
130 | } | 134 | } | ||
131 | 135 | | |||
132 | void MemoryView::currentSessionChanged(KDevelop::IDebugSession* s) | 136 | void MemoryView::currentSessionChanged(KDevelop::IDebugSession* s) | ||
133 | { | 137 | { | ||
134 | DebugSession *session = qobject_cast<DebugSession*>(s); | 138 | DebugSession *session = qobject_cast<DebugSession*>(s); | ||
135 | if (!session) return; | 139 | if (!session) return; | ||
136 | connect(session, | 140 | | ||
137 | SIGNAL(gdbStateChanged(DBGStateFlags,DBGStateFlags)), | 141 | connect(session, &DebugSession::debuggerStateChanged, | ||
138 | SLOT(slotStateChanged(DBGStateFlags,DBGStateFlags))); | 142 | this, &MemoryView::slotStateChanged); | ||
139 | } | 143 | } | ||
140 | 144 | | |||
141 | void MemoryView::slotStateChanged(DBGStateFlags oldState, DBGStateFlags newState) | 145 | void MemoryView::slotStateChanged(DBGStateFlags oldState, DBGStateFlags newState) | ||
142 | { | 146 | { | ||
143 | Q_UNUSED(oldState); | 147 | Q_UNUSED(oldState); | ||
144 | debuggerStateChanged(newState); | 148 | debuggerStateChanged(newState); | ||
145 | } | 149 | } | ||
146 | 150 | | |||
147 | void MemoryView::initWidget() | 151 | void MemoryView::initWidget() | ||
148 | { | 152 | { | ||
149 | QVBoxLayout *l = new QVBoxLayout(this); | 153 | QVBoxLayout *l = new QVBoxLayout(this); | ||
150 | l->setContentsMargins(0, 0, 0, 0); | 154 | l->setContentsMargins(0, 0, 0, 0); | ||
151 | 155 | | |||
152 | khexedit2_widget = KHE::createBytesEditWidget(this); | 156 | m_memViewModel = new Okteta::ByteArrayModel(0, -1, this); | ||
153 | if (!khexedit2_widget) | 157 | m_memViewView = new Okteta::ByteArrayColumnView(this); | ||
154 | { | 158 | m_memViewView->setByteArrayModel(m_memViewModel); | ||
mwolff: missing parent | |||||
155 | QTextEdit* edit = new QTextEdit(this); | | |||
156 | l->addWidget(edit); | | |||
157 | 159 | | |||
158 | edit->setText( | 160 | m_memViewModel->setReadOnly(false); | ||
159 | "<h1>Not Available</h1>" | 161 | m_memViewView->setReadOnly(false); | ||
160 | "<p>Could not open a KHexEdit2 interface. " | 162 | m_memViewView->setOverwriteMode(true); | ||
161 | "Installing Okteta should provide the required components.</p>"); | 163 | m_memViewView->setOverwriteOnly(true); | ||
162 | return; | 164 | m_memViewModel->setAutoDelete(false); | ||
163 | } | | |||
164 | 165 | | |||
165 | KHE::BytesEditInterface *bytesEdit = KHE::bytesEditInterface(khexedit2_widget); | 166 | m_memViewView->setValueCoding( Okteta::ByteArrayColumnView::HexadecimalCoding ); | ||
166 | if (bytesEdit) | 167 | m_memViewView->setNoOfGroupedBytes(4); | ||
167 | { | 168 | m_memViewView->setByteSpacingWidth(2); | ||
168 | bytesEdit->setReadOnly(false); | 169 | m_memViewView->setGroupSpacingWidth(12); | ||
169 | bytesEdit->setOverwriteMode(true); | 170 | m_memViewView->setLayoutStyle(Okteta::AbstractByteArrayView::FullSizeLayoutStyle); | ||
Method is called setLayoutStylehere and defined on AbstractByteArrayView: kossebau: Method is called `setLayoutStyle`here and defined on AbstractByteArrayView:
https://api.kde. | |||||
170 | bytesEdit->setOverwriteOnly(true); | | |||
171 | bytesEdit->setAutoDelete(false); | | |||
172 | } | | |||
173 | 171 | | |||
174 | KHE::ValueColumnInterface *valueColumn = KHE::valueColumnInterface(khexedit2_widget); | | |||
175 | if (valueColumn) | | |||
176 | { | | |||
177 | valueColumn->setCoding(KHE::ValueColumnInterface::HexadecimalCoding); | | |||
178 | valueColumn->setNoOfGroupedBytes(4); | | |||
179 | valueColumn->setByteSpacingWidth(2); | | |||
180 | valueColumn->setGroupSpacingWidth(12); | | |||
181 | valueColumn->setResizeStyle(KHE::ValueColumnInterface::LockGrouping); | | |||
182 | } | | |||
183 | 172 | | |||
184 | KHE::CharColumnInterface *charColumn = KHE::charColumnInterface(khexedit2_widget); | 173 | m_memViewView->setShowsNonprinting(false); | ||
185 | if(charColumn) | 174 | m_memViewView->setSubstituteChar('*'); | ||
186 | { | | |||
187 | charColumn->setShowUnprintable(false); | | |||
188 | charColumn->setSubstituteChar('*'); | | |||
189 | } | | |||
190 | 175 | | |||
191 | rangeSelector_ = new MemoryRangeSelector(this); | 176 | m_rangeSelector = new MemoryRangeSelector(this); | ||
192 | l->addWidget(rangeSelector_); | 177 | l->addWidget(m_rangeSelector); | ||
193 | 178 | | |||
194 | connect(rangeSelector_->okButton, SIGNAL(clicked()), | 179 | connect(m_rangeSelector->okButton, &QPushButton::clicked, | ||
195 | this, SLOT(slotChangeMemoryRange())); | 180 | this, &MemoryView::slotChangeMemoryRange); | ||
196 | 181 | | |||
197 | connect(rangeSelector_->cancelButton, SIGNAL(clicked()), | 182 | connect(m_rangeSelector->cancelButton, &QPushButton::clicked, | ||
198 | this, SLOT(slotHideRangeDialog())); | 183 | this, &MemoryView::slotHideRangeDialog); | ||
199 | 184 | | |||
200 | connect(rangeSelector_->startAddressLineEdit, | 185 | connect(m_rangeSelector->startAddressLineEdit, | ||
201 | SIGNAL(textChanged(QString)), | 186 | &QLineEdit::textChanged, | ||
202 | this, | 187 | this, | ||
203 | SLOT(slotEnableOrDisable())); | 188 | &MemoryView::slotEnableOrDisable); | ||
204 | 189 | | |||
205 | connect(rangeSelector_->amountLineEdit, | 190 | connect(m_rangeSelector->amountLineEdit, | ||
206 | SIGNAL(textChanged(QString)), | 191 | &QLineEdit::textChanged, | ||
207 | this, | 192 | this, | ||
208 | SLOT(slotEnableOrDisable())); | 193 | &MemoryView::slotEnableOrDisable); | ||
209 | 194 | | |||
210 | l->addWidget(khexedit2_widget); | 195 | l->addWidget(m_memViewView); | ||
211 | } | 196 | } | ||
212 | 197 | | |||
213 | void MemoryView::debuggerStateChanged(DBGStateFlags state) | 198 | void MemoryView::debuggerStateChanged(DBGStateFlags state) | ||
214 | { | 199 | { | ||
215 | if (isOk()) | 200 | if (isOk()) | ||
216 | { | 201 | { | ||
217 | debuggerState_ = state; | 202 | m_debuggerState = state; | ||
218 | slotEnableOrDisable(); | 203 | slotEnableOrDisable(); | ||
219 | } | 204 | } | ||
220 | } | 205 | } | ||
221 | 206 | | |||
222 | 207 | | |||
223 | void MemoryView::slotHideRangeDialog() | 208 | void MemoryView::slotHideRangeDialog() | ||
224 | { | 209 | { | ||
225 | rangeSelector_->hide(); | 210 | m_rangeSelector->hide(); | ||
226 | } | 211 | } | ||
227 | 212 | | |||
228 | void MemoryView::slotChangeMemoryRange() | 213 | void MemoryView::slotChangeMemoryRange() | ||
229 | { | 214 | { | ||
230 | DebugSession *session = qobject_cast<DebugSession*>( | 215 | DebugSession *session = qobject_cast<DebugSession*>( | ||
231 | KDevelop::ICore::self()->debugController()->currentSession()); | 216 | KDevelop::ICore::self()->debugController()->currentSession()); | ||
232 | if (!session) return; | 217 | if (!session) return; | ||
233 | 218 | | |||
234 | QString amount = rangeSelector_->amountLineEdit->text(); | 219 | QString amount = m_rangeSelector->amountLineEdit->text(); | ||
235 | if(amount.isEmpty()) | 220 | if(amount.isEmpty()) | ||
236 | amount = QString("sizeof(%1)").arg(rangeSelector_->startAddressLineEdit->text()); | 221 | amount = QString("sizeof(%1)").arg(m_rangeSelector->startAddressLineEdit->text()); | ||
237 | 222 | | |||
238 | session->addCommand(new ExpressionValueCommand(amount, this, &MemoryView::sizeComputed)); | 223 | session->addCommand(new MI::ExpressionValueCommand(amount, this, &MemoryView::sizeComputed)); | ||
239 | } | 224 | } | ||
240 | 225 | | |||
241 | void MemoryView::sizeComputed(const QString& size) | 226 | void MemoryView::sizeComputed(const QString& size) | ||
242 | { | 227 | { | ||
243 | DebugSession *session = qobject_cast<DebugSession*>( | 228 | DebugSession *session = qobject_cast<DebugSession*>( | ||
244 | KDevelop::ICore::self()->debugController()->currentSession()); | 229 | KDevelop::ICore::self()->debugController()->currentSession()); | ||
245 | if (!session) return; | 230 | if (!session) return; | ||
246 | 231 | | |||
247 | session->addCommand(new GDBCommand(MI::DataReadMemory, | 232 | session->addCommand(MI::DataReadMemory, | ||
248 | QString("%1 x 1 1 %2") | 233 | QString("%1 x 1 1 %2") | ||
249 | .arg(rangeSelector_->startAddressLineEdit->text()) | 234 | .arg(m_rangeSelector->startAddressLineEdit->text()) | ||
250 | .arg(size), | 235 | .arg(size), | ||
251 | this, | 236 | this, | ||
252 | &MemoryView::memoryRead)); | 237 | &MemoryView::memoryRead); | ||
253 | } | 238 | } | ||
254 | 239 | | |||
255 | void MemoryView::memoryRead(const MI::ResultRecord& r) | 240 | void MemoryView::memoryRead(const MI::ResultRecord& r) | ||
256 | { | 241 | { | ||
257 | const MI::Value& content = r["memory"][0]["data"]; | 242 | const MI::Value& content = r["memory"][0]["data"]; | ||
258 | bool startStringConverted; | 243 | bool startStringConverted; | ||
259 | start_ = r["addr"].literal().toULongLong(&startStringConverted, 16); | 244 | m_memStart = r["addr"].literal().toULongLong(&startStringConverted, 16); | ||
260 | amount_ = content.size(); | 245 | m_memData.resize(content.size()); | ||
261 | 246 | | |||
262 | startAsString_ = rangeSelector_->startAddressLineEdit->text(); | 247 | m_memStartStr = m_rangeSelector->startAddressLineEdit->text(); | ||
263 | amountAsString_ = rangeSelector_->amountLineEdit->text(); | 248 | m_memAmountStr = m_rangeSelector->amountLineEdit->text(); | ||
264 | 249 | | |||
265 | setWindowTitle(i18np("%2 (1 byte)","%2 (%1 bytes)",amount_,startAsString_)); | 250 | setWindowTitle(i18np("%2 (1 byte)","%2 (%1 bytes)",m_memData.size(),m_memStartStr)); | ||
266 | emit captionChanged(windowTitle()); | 251 | emit captionChanged(windowTitle()); | ||
267 | 252 | | |||
268 | KHE::BytesEditInterface* bytesEditor = KHE::bytesEditInterface(khexedit2_widget); | | |||
269 | bytesEditor->setData(this->data_, 0); | | |||
270 | | ||||
271 | delete[] this->data_; | | |||
272 | this->data_ = new char[amount_]; | | |||
273 | for(int i = 0; i < content.size(); ++i) | 253 | for(int i = 0; i < content.size(); ++i) | ||
mwolff: remove this-> | |||||
274 | { | 254 | { | ||
275 | this->data_[i] = content[i].literal().toInt(0, 16); | 255 | m_memData[i] = content[i].literal().toInt(0, 16); | ||
276 | } | 256 | } | ||
277 | 257 | | |||
278 | bytesEditor->setData(this->data_, amount_); | 258 | m_memViewModel->setData(reinterpret_cast<Okteta::Byte*>(m_memData.data()), m_memData.size()); | ||
279 | 259 | | |||
This should be doable by simply resetting the data of the existing model, using ByteArrayModel::setData(), like (untested): m_memViewModel->setData(reinterpret_cast<Okteta::Byte*>(m_memData), m_memAmount); Or did you try and meet a flaw with that? kossebau: This should be doable by simply resetting the data of the existing model, using ByteArrayModel… | |||||
280 | slotHideRangeDialog(); | 260 | slotHideRangeDialog(); | ||
281 | } | 261 | } | ||
282 | 262 | | |||
283 | 263 | | |||
284 | void MemoryView::memoryEdited(int start, int end) | 264 | void MemoryView::memoryEdited(int start, int end) | ||
285 | { | 265 | { | ||
286 | DebugSession *session = qobject_cast<DebugSession*>( | 266 | DebugSession *session = qobject_cast<DebugSession*>( | ||
287 | KDevelop::ICore::self()->debugController()->currentSession()); | 267 | KDevelop::ICore::self()->debugController()->currentSession()); | ||
288 | if (!session) return; | 268 | if (!session) return; | ||
289 | 269 | | |||
290 | for(int i = start; i <= end; ++i) | 270 | for(int i = start; i <= end; ++i) | ||
291 | { | 271 | { | ||
292 | session->addCommand(new GDBCommand(MI::GdbSet, | 272 | session->addCommand(MI::GdbSet, | ||
293 | QString("*(char*)(%1 + %2) = %3") | 273 | QString("*(char*)(%1 + %2) = %3") | ||
294 | .arg(start_) | 274 | .arg(m_memStart) | ||
295 | .arg(i) | 275 | .arg(i) | ||
296 | .arg(QString::number(data_[i])))); | 276 | .arg(QString::number(m_memData[i]))); | ||
297 | } | 277 | } | ||
298 | } | 278 | } | ||
299 | 279 | | |||
300 | void MemoryView::contextMenuEvent(QContextMenuEvent *e) | 280 | void MemoryView::contextMenuEvent(QContextMenuEvent *e) | ||
301 | { | 281 | { | ||
302 | if (!isOk()) | 282 | if (!isOk()) | ||
303 | return; | 283 | return; | ||
304 | 284 | | |||
305 | KHE::BytesEditInterface *bytesEdit = KHE::bytesEditInterface(khexedit2_widget); | | |||
306 | KHE::ValueColumnInterface *valueColumn = KHE::valueColumnInterface(khexedit2_widget); | | |||
307 | | ||||
308 | QMenu menu; | 285 | QMenu menu; | ||
309 | 286 | | |||
310 | bool app_running = !(debuggerState_ & s_appNotStarted); | 287 | bool app_running = !(m_debuggerState & s_appNotStarted); | ||
311 | 288 | | |||
312 | QAction* reload = menu.addAction(i18n("&Reload")); | 289 | QAction* reload = menu.addAction(i18n("&Reload")); | ||
313 | reload->setIcon(QIcon::fromTheme("view-refresh")); | 290 | reload->setIcon(QIcon::fromTheme("view-refresh")); | ||
314 | reload->setEnabled(app_running && amount_ != 0); | 291 | reload->setEnabled(app_running && !m_memData.isEmpty() ); | ||
315 | 292 | | |||
316 | QActionGroup *formatGroup = NULL; | 293 | QActionGroup *formatGroup = NULL; | ||
317 | QActionGroup *groupingGroup = NULL; | 294 | QActionGroup *groupingGroup = NULL; | ||
318 | if (valueColumn) | 295 | if (m_memViewModel && m_memViewView) | ||
319 | { | 296 | { | ||
320 | // make Format menu with action group | 297 | // make Format menu with action group | ||
321 | QMenu *formatMenu = new QMenu(i18n("&Format")); | 298 | QMenu *formatMenu = new QMenu(i18n("&Format")); | ||
322 | formatGroup = new QActionGroup(formatMenu); | 299 | formatGroup = new QActionGroup(formatMenu); | ||
323 | 300 | | |||
324 | QAction *binary = formatGroup->addAction(i18n("&Binary")); | 301 | QAction *binary = formatGroup->addAction(i18n("&Binary")); | ||
325 | binary->setData(KHE::ValueColumnInterface::BinaryCoding); | 302 | binary->setData(Okteta::ByteArrayColumnView::BinaryCoding); | ||
326 | binary->setShortcut(Qt::Key_B); | 303 | binary->setShortcut(Qt::Key_B); | ||
327 | formatMenu->addAction(binary); | 304 | formatMenu->addAction(binary); | ||
328 | 305 | | |||
329 | QAction *octal = formatGroup->addAction(i18n("&Octal")); | 306 | QAction *octal = formatGroup->addAction(i18n("&Octal")); | ||
330 | octal->setData(KHE::ValueColumnInterface::OctalCoding); | 307 | octal->setData(Okteta::ByteArrayColumnView::OctalCoding); | ||
331 | octal->setShortcut(Qt::Key_O); | 308 | octal->setShortcut(Qt::Key_O); | ||
332 | formatMenu->addAction(octal); | 309 | formatMenu->addAction(octal); | ||
333 | 310 | | |||
334 | QAction *decimal = formatGroup->addAction(i18n("&Decimal")); | 311 | QAction *decimal = formatGroup->addAction(i18n("&Decimal")); | ||
335 | decimal->setData(KHE::ValueColumnInterface::DecimalCoding); | 312 | decimal->setData(Okteta::ByteArrayColumnView::DecimalCoding); | ||
336 | decimal->setShortcut(Qt::Key_D); | 313 | decimal->setShortcut(Qt::Key_D); | ||
337 | formatMenu->addAction(decimal); | 314 | formatMenu->addAction(decimal); | ||
338 | 315 | | |||
339 | QAction *hex = formatGroup->addAction(i18n("&Hexadecimal")); | 316 | QAction *hex = formatGroup->addAction(i18n("&Hexadecimal")); | ||
340 | hex->setData(KHE::ValueColumnInterface::HexadecimalCoding); | 317 | hex->setData(Okteta::ByteArrayColumnView::HexadecimalCoding); | ||
341 | hex->setShortcut(Qt::Key_H); | 318 | hex->setShortcut(Qt::Key_H); | ||
342 | formatMenu->addAction(hex); | 319 | formatMenu->addAction(hex); | ||
343 | 320 | | |||
344 | foreach(QAction* act, formatGroup->actions()) | 321 | foreach(QAction* act, formatGroup->actions()) | ||
345 | { | 322 | { | ||
346 | act->setCheckable(true); | 323 | act->setCheckable(true); | ||
347 | act->setChecked(act->data().toInt() == valueColumn->coding()); | 324 | act->setChecked(act->data().toInt() == m_memViewView->valueCoding()); | ||
348 | act->setShortcutContext(Qt::WidgetWithChildrenShortcut); | 325 | act->setShortcutContext(Qt::WidgetWithChildrenShortcut); | ||
349 | } | 326 | } | ||
350 | 327 | | |||
351 | menu.addMenu(formatMenu); | 328 | menu.addMenu(formatMenu); | ||
352 | 329 | | |||
353 | 330 | | |||
354 | // make Grouping menu with action group | 331 | // make Grouping menu with action group | ||
355 | QMenu *groupingMenu = new QMenu(i18n("&Grouping")); | 332 | QMenu *groupingMenu = new QMenu(i18n("&Grouping")); | ||
Show All 27 Lines | |||||
383 | QAction *group16 = groupingGroup->addAction(i18n("1&6")); | 360 | QAction *group16 = groupingGroup->addAction(i18n("1&6")); | ||
384 | group16->setData(16); | 361 | group16->setData(16); | ||
385 | group16->setShortcut(Qt::Key_6); | 362 | group16->setShortcut(Qt::Key_6); | ||
386 | groupingMenu->addAction(group16); | 363 | groupingMenu->addAction(group16); | ||
387 | 364 | | |||
388 | foreach(QAction* act, groupingGroup->actions()) | 365 | foreach(QAction* act, groupingGroup->actions()) | ||
389 | { | 366 | { | ||
390 | act->setCheckable(true); | 367 | act->setCheckable(true); | ||
391 | act->setChecked(act->data().toInt() == valueColumn->noOfGroupedBytes()); | 368 | act->setChecked(act->data().toInt() == m_memViewView->noOfGroupedBytes()); | ||
392 | act->setShortcutContext(Qt::WidgetWithChildrenShortcut); | 369 | act->setShortcutContext(Qt::WidgetWithChildrenShortcut); | ||
393 | } | 370 | } | ||
394 | 371 | | |||
395 | menu.addMenu(groupingMenu); | 372 | menu.addMenu(groupingMenu); | ||
396 | } | 373 | } | ||
397 | 374 | | |||
398 | QAction* write = menu.addAction(i18n("Write changes")); | 375 | QAction* write = menu.addAction(i18n("Write changes")); | ||
399 | write->setIcon(QIcon::fromTheme("document-save")); | 376 | write->setIcon(QIcon::fromTheme("document-save")); | ||
400 | write->setEnabled(app_running && bytesEdit && bytesEdit->isModified()); | 377 | write->setEnabled(app_running && m_memViewView && m_memViewView->isModified()); | ||
401 | 378 | | |||
402 | QAction* range = menu.addAction(i18n("Change memory range")); | 379 | QAction* range = menu.addAction(i18n("Change memory range")); | ||
403 | range->setEnabled(app_running && !rangeSelector_->isVisible()); | 380 | range->setEnabled(app_running && !m_rangeSelector->isVisible()); | ||
404 | range->setIcon(QIcon::fromTheme("document-edit")); | 381 | range->setIcon(QIcon::fromTheme("document-edit")); | ||
405 | 382 | | |||
406 | QAction* close = menu.addAction(i18n("Close this view")); | 383 | QAction* close = menu.addAction(i18n("Close this view")); | ||
407 | close->setIcon(QIcon::fromTheme("window-close")); | 384 | close->setIcon(QIcon::fromTheme("window-close")); | ||
408 | 385 | | |||
409 | 386 | | |||
410 | QAction* result = menu.exec(e->globalPos()); | 387 | QAction* result = menu.exec(e->globalPos()); | ||
411 | 388 | | |||
412 | 389 | | |||
413 | if (result == reload) | 390 | if (result == reload) | ||
414 | { | 391 | { | ||
415 | // We use numeric start_ and amount_ stored in this, | 392 | // We use m_memStart and m_memAmount stored in this, | ||
416 | // not textual startAsString_ and amountAsString_, | 393 | // not textual m_memStartStr and m_memAmountStr, | ||
417 | // because program position might have changes and expressions | 394 | // because program position might have changes and expressions | ||
418 | // are no longer valid. | 395 | // are no longer valid. | ||
419 | DebugSession *session = qobject_cast<DebugSession*>( | 396 | DebugSession *session = qobject_cast<DebugSession*>( | ||
420 | KDevelop::ICore::self()->debugController()->currentSession()); | 397 | KDevelop::ICore::self()->debugController()->currentSession()); | ||
421 | if (session) { | 398 | if (session) { | ||
422 | session->addCommand(new GDBCommand(MI::DataReadMemory, | 399 | session->addCommand(MI::DataReadMemory, | ||
423 | QString("%1 x 1 1 %2").arg(start_).arg(amount_), | 400 | QString("%1 x 1 1 %2").arg(m_memStart).arg(m_memData.size()), | ||
424 | this, | 401 | this, | ||
425 | &MemoryView::memoryRead)); | 402 | &MemoryView::memoryRead); | ||
426 | } | 403 | } | ||
427 | } | 404 | } | ||
428 | 405 | | |||
429 | if (result && formatGroup && formatGroup == result->actionGroup()) | 406 | if (result && formatGroup && formatGroup == result->actionGroup()) | ||
430 | valueColumn->setCoding((KHE::ValueColumnInterface::KCoding)result->data().toInt()); | 407 | m_memViewView->setValueCoding( (Okteta::ByteArrayColumnView::ValueCoding)result->data().toInt()); | ||
431 | 408 | | |||
432 | if (result && groupingGroup && groupingGroup == result->actionGroup()) | 409 | if (result && groupingGroup && groupingGroup == result->actionGroup()) | ||
433 | valueColumn->setNoOfGroupedBytes(result->data().toInt()); | 410 | m_memViewView->setNoOfGroupedBytes(result->data().toInt()); | ||
434 | 411 | | |||
435 | if (result == write) | 412 | if (result == write) | ||
436 | { | 413 | { | ||
437 | memoryEdited(0, amount_); | 414 | memoryEdited(0, m_memData.size()); | ||
438 | bytesEdit->setModified(false); | 415 | m_memViewView->setModified(false); | ||
439 | } | 416 | } | ||
440 | 417 | | |||
441 | if (result == range) | 418 | if (result == range) | ||
442 | { | 419 | { | ||
443 | rangeSelector_->startAddressLineEdit->setText(startAsString_); | 420 | m_rangeSelector->startAddressLineEdit->setText(m_memStartStr); | ||
444 | rangeSelector_->amountLineEdit->setText(amountAsString_); | 421 | m_rangeSelector->amountLineEdit->setText(m_memAmountStr); | ||
445 | 422 | | |||
446 | rangeSelector_->show(); | 423 | m_rangeSelector->show(); | ||
447 | rangeSelector_->startAddressLineEdit->setFocus(); | 424 | m_rangeSelector->startAddressLineEdit->setFocus(); | ||
448 | } | 425 | } | ||
449 | 426 | | |||
450 | if (result == close) | 427 | if (result == close) | ||
451 | delete this; | 428 | delete this; | ||
452 | } | 429 | } | ||
453 | 430 | | |||
454 | bool MemoryView::isOk() const | 431 | bool MemoryView::isOk() const | ||
455 | { | 432 | { | ||
456 | return khexedit2_widget; | 433 | return m_memViewView; | ||
457 | } | 434 | } | ||
458 | 435 | | |||
459 | void MemoryView::slotEnableOrDisable() | 436 | void MemoryView::slotEnableOrDisable() | ||
460 | { | 437 | { | ||
461 | bool app_started = !(debuggerState_ & s_appNotStarted); | 438 | bool app_started = !(m_debuggerState & s_appNotStarted); | ||
462 | 439 | | |||
463 | bool enabled_ = app_started && !rangeSelector_->startAddressLineEdit->text().isEmpty(); | 440 | bool enabled_ = app_started && !m_rangeSelector->startAddressLineEdit->text().isEmpty(); | ||
464 | 441 | | |||
465 | rangeSelector_->okButton->setEnabled(enabled_); | 442 | m_rangeSelector->okButton->setEnabled(enabled_); | ||
466 | } | 443 | } | ||
467 | 444 | | |||
468 | 445 | | |||
469 | MemoryViewerWidget::MemoryViewerWidget(CppDebuggerPlugin* /*plugin*/, QWidget* parent) | 446 | MemoryViewerWidget::MemoryViewerWidget(CppDebuggerPlugin* /*plugin*/, QWidget* parent) | ||
470 | : QWidget(parent) | 447 | : QWidget(parent) | ||
471 | { | 448 | { | ||
472 | setWindowIcon(QIcon::fromTheme("server-database", windowIcon())); | 449 | setWindowIcon(QIcon::fromTheme("server-database", windowIcon())); | ||
473 | setWindowTitle(i18n("Memory viewer")); | 450 | setWindowTitle(i18n("Memory viewer")); | ||
474 | 451 | | |||
475 | QAction * newMemoryViewerAction = new QAction(this); | 452 | QAction * newMemoryViewerAction = new QAction(this); | ||
476 | newMemoryViewerAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); | 453 | newMemoryViewerAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); | ||
477 | newMemoryViewerAction->setText(i18n("New memory viewer")); | 454 | newMemoryViewerAction->setText(i18n("New memory viewer")); | ||
478 | newMemoryViewerAction->setToolTip(i18nc("@info:tooltip", "Open a new memory viewer.")); | 455 | newMemoryViewerAction->setToolTip(i18nc("@info:tooltip", "Open a new memory viewer.")); | ||
479 | newMemoryViewerAction->setIcon(QIcon::fromTheme("window-new")); | 456 | newMemoryViewerAction->setIcon(QIcon::fromTheme("window-new")); | ||
480 | connect(newMemoryViewerAction, SIGNAL(triggered(bool)), this, SLOT(slotAddMemoryView())); | 457 | connect(newMemoryViewerAction, &QAction::triggered, this , &MemoryViewerWidget::slotAddMemoryView); | ||
481 | addAction(newMemoryViewerAction); | 458 | addAction(newMemoryViewerAction); | ||
482 | 459 | | |||
483 | QVBoxLayout *l = new QVBoxLayout(this); | 460 | QVBoxLayout *l = new QVBoxLayout(this); | ||
484 | l->setContentsMargins(0, 0, 0, 0); | 461 | l->setContentsMargins(0, 0, 0, 0); | ||
485 | 462 | | |||
486 | toolBox_ = new QToolBox(this); | 463 | m_toolBox = new QToolBox(this); | ||
487 | toolBox_->setContentsMargins(0, 0, 0, 0); | 464 | m_toolBox->setContentsMargins(0, 0, 0, 0); | ||
488 | l->addWidget(toolBox_); | 465 | l->addWidget(m_toolBox); | ||
489 | 466 | | |||
490 | setLayout(l); | 467 | setLayout(l); | ||
491 | 468 | | |||
492 | // Start with one empty memory view. | 469 | // Start with one empty memory view. | ||
493 | slotAddMemoryView(); | 470 | slotAddMemoryView(); | ||
494 | } | 471 | } | ||
495 | 472 | | |||
496 | void MemoryViewerWidget::slotAddMemoryView() | 473 | void MemoryViewerWidget::slotAddMemoryView() | ||
497 | { | 474 | { | ||
498 | MemoryView* widget = new MemoryView(this); | 475 | MemoryView* widget = new MemoryView(this); | ||
499 | toolBox_->addItem(widget, widget->windowTitle()); | 476 | m_toolBox->addItem(widget, widget->windowTitle()); | ||
500 | toolBox_->setCurrentIndex(toolBox_->indexOf(widget)); | 477 | m_toolBox->setCurrentIndex(m_toolBox->indexOf(widget)); | ||
501 | memoryViews_.push_back(widget); | 478 | m_memoryViews.push_back(widget); | ||
mwolff: is this cast really required? I don't see why
| |||||
volden: Me neither. I'll remove this and then push. | |||||
502 | 479 | | |||
503 | connect(widget, SIGNAL(captionChanged(QString)), | 480 | connect(widget, &MemoryView::captionChanged, | ||
504 | this, SLOT(slotChildCaptionChanged(QString))); | 481 | this, &MemoryViewerWidget::slotChildCaptionChanged); | ||
505 | 482 | | |||
506 | connect(widget, SIGNAL(destroyed(QObject*)), | 483 | connect(widget, &MemoryView::destroyed, | ||
507 | this, SLOT(slotChildDestroyed(QObject*))); | 484 | this, &MemoryViewerWidget::slotChildDestroyed); | ||
508 | } | 485 | } | ||
509 | 486 | | |||
510 | void MemoryViewerWidget::slotChildCaptionChanged(const QString& caption) | 487 | void MemoryViewerWidget::slotChildCaptionChanged(const QString& caption) | ||
511 | { | 488 | { | ||
512 | const QWidget* s = static_cast<const QWidget*>(sender()); | 489 | const QWidget* s = static_cast<const QWidget*>(sender()); | ||
513 | QWidget* ncs = const_cast<QWidget*>(s); | 490 | QWidget* ncs = const_cast<QWidget*>(s); | ||
514 | QString cap = caption; | 491 | QString cap = caption; | ||
515 | // Prevent intepreting '&' as accelerator specifier. | 492 | // Prevent intepreting '&' as accelerator specifier. | ||
516 | cap.replace('&', "&&"); | 493 | cap.replace('&', "&&"); | ||
517 | toolBox_->setItemText(toolBox_->indexOf(ncs), cap); | 494 | m_toolBox->setItemText(m_toolBox->indexOf(ncs), cap); | ||
518 | } | 495 | } | ||
519 | 496 | | |||
520 | void MemoryViewerWidget::slotChildDestroyed(QObject* child) | 497 | void MemoryViewerWidget::slotChildDestroyed(QObject* child) | ||
521 | { | 498 | { | ||
522 | QList<MemoryView*>::iterator i, e; | 499 | QList<MemoryView*>::iterator i, e; | ||
523 | for(i = memoryViews_.begin(), e = memoryViews_.end(); i != e; ++i) | 500 | for(i = m_memoryViews.begin(), e = m_memoryViews.end(); i != e; ++i) | ||
524 | { | 501 | { | ||
525 | if (*i == child) | 502 | if (*i == child) | ||
526 | { | 503 | { | ||
527 | memoryViews_.erase(i); | 504 | m_memoryViews.erase(i); | ||
528 | break; | 505 | break; | ||
529 | } | 506 | } | ||
530 | } | 507 | } | ||
531 | } | 508 | } | ||
509 | | ||||
510 | | ||||
511 | } // end of namespace GDB | ||||
512 | } // end of namespace KDevMI |
why did you remove the this parameter everywhere?