Commit | Line | Data |
---|---|---|
0203b5fd JPM |
1 | //\r |
2 | // allwatchbrowser.cpp - All Watch\r | |
3 | //\r | |
4 | // by Jean-Paul Mari\r | |
5 | //\r | |
6 | // JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r | |
7 | //\r | |
8 | // Who When What\r | |
9 | // --- ---------- -----------------------------------------------------------\r | |
10 | // JPM 12/07/2017 Created this file\r | |
4873fe0a | 11 | // JPM 09/14/2018 Added a status bar, better status report and set information values in a tab\r |
8d705db0 | 12 | // JPM April/2019 Added a sorting filter, tableview unique rows creation\r |
0203b5fd JPM |
13 | //\r |
14 | \r | |
15 | // STILL TO DO:\r | |
a4e46c05 | 16 | // Better presentation\r |
2b91c435 | 17 | // To set the information display at the right\r |
8d705db0 | 18 | // To understand/fix the problem with the sorting filter\r |
fe3b257d JPM |
19 | // Display arrays information\r |
20 | // Display structures information\r | |
0203b5fd JPM |
21 | //\r |
22 | \r | |
8d705db0 | 23 | //#define AW_SORTINGFILTER // Authorise the sorting filtes\r |
4873fe0a | 24 | //#define AW_DEBUGNUMVARIABLE 4415 // Set the global variable number to debug\r |
2b91c435 JPM |
25 | #ifndef AW_DEBUGNUMVARIABLE\r |
26 | #define AW_STARTNUMVARIABLE 0 // Must be kept to 0 in case of no debug is required\r | |
27 | #else\r | |
28 | #define AW_STARTNUMVARIABLE AW_DEBUGNUMVARIABLE - 1\r | |
29 | #endif\r | |
30 | \r | |
31 | \r | |
0203b5fd JPM |
32 | #include "debugger/allwatchbrowser.h"\r |
33 | #include "memory.h"\r | |
34 | #include "debugger/DBGManager.h"\r | |
35 | \r | |
36 | \r | |
a4e46c05 | 37 | // \r |
0203b5fd | 38 | AllWatchBrowserWindow::AllWatchBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r |
2b91c435 | 39 | layout(new QVBoxLayout),\r |
117e41c2 JPM |
40 | symbol(new QLineEdit),\r |
41 | search(new QPushButton(tr("Search"))),\r | |
2b91c435 JPM |
42 | #ifdef AW_LAYOUTTEXTS\r |
43 | text(new QTextBrowser),\r | |
44 | #else\r | |
45 | TableView(new QTableView),\r | |
46 | model(new QStandardItemModel),\r | |
47 | #endif\r | |
48 | NbWatch(0),\r | |
117e41c2 | 49 | CurrentWatch(0),\r |
2b91c435 JPM |
50 | statusbar(new QStatusBar),\r |
51 | PtrWatchInfo(NULL)\r | |
0203b5fd JPM |
52 | {\r |
53 | setWindowTitle(tr("All Watch"));\r | |
54 | \r | |
117e41c2 | 55 | // set the font\r |
0203b5fd | 56 | QFont fixedFont("Lucida Console", 8, QFont::Normal);\r |
0203b5fd | 57 | fixedFont.setStyleHint(QFont::TypeWriter);\r |
0203b5fd | 58 | \r |
2b91c435 JPM |
59 | #ifdef AW_LAYOUTTEXTS\r |
60 | // Set original layout\r | |
61 | text->setFont(fixedFont);\r | |
0203b5fd | 62 | layout->addWidget(text);\r |
2b91c435 JPM |
63 | #else\r |
64 | // Set the new layout with proper identation and readibility\r | |
65 | model->setColumnCount(3);\r | |
66 | model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));\r | |
67 | model->setHeaderData(1, Qt::Horizontal, QObject::tr("Value"));\r | |
68 | model->setHeaderData(2, Qt::Horizontal, QObject::tr("Type"));\r | |
69 | // Information table\r | |
70 | TableView->setModel(model);\r | |
71 | TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);\r | |
72 | TableView->setShowGrid(0);\r | |
73 | TableView->setFont(fixedFont);\r | |
74 | TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());\r | |
75 | TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);\r | |
76 | layout->addWidget(TableView);\r | |
77 | #endif\r | |
78 | \r | |
117e41c2 JPM |
79 | // search bar\r |
80 | QHBoxLayout * hbox1 = new QHBoxLayout;\r | |
81 | symbol->setPlaceholderText("symbol name");\r | |
82 | hbox1->addWidget(symbol);\r | |
83 | hbox1->addWidget(search);\r | |
84 | layout->addLayout(hbox1);\r | |
85 | \r | |
86 | // status bar\r | |
2b91c435 JPM |
87 | layout->addWidget(statusbar);\r |
88 | setLayout(layout);\r | |
117e41c2 JPM |
89 | \r |
90 | // connect slot\r | |
91 | connect(search, SIGNAL(clicked()), this, SLOT(SearchSymbol()));\r | |
92 | connect(symbol, SIGNAL(cursorPositionChanged(int, int)), this, SLOT(SelectSearchSymbol()));\r | |
0203b5fd JPM |
93 | }\r |
94 | \r | |
95 | \r | |
96 | //\r | |
97 | AllWatchBrowserWindow::~AllWatchBrowserWindow(void)\r | |
98 | {\r | |
a4e46c05 JPM |
99 | Reset();\r |
100 | }\r | |
101 | \r | |
102 | \r | |
117e41c2 JPM |
103 | // Search the symbol in the watch list\r |
104 | void AllWatchBrowserWindow::SearchSymbol(void) | |
105 | { | |
106 | bool found = false; | |
107 | size_t i; | |
108 | ||
109 | // user cannot enter symbol to allow the search | |
110 | symbol->setDisabled(true); | |
111 | ||
112 | // look for the symbol in the watch list | |
113 | for (i = AW_STARTNUMVARIABLE; (i < NbWatch) && !found; i++)\r | |
114 | {\r | |
115 | // check symbol presence\r | |
116 | if (!symbol->text().compare(PtrWatchInfo[i].PtrVariableName, Qt::CaseSensitive))\r | |
117 | {\r | |
118 | found = true;\r | |
119 | }\r | |
120 | }\r | |
121 | \r | |
122 | if (found)\r | |
123 | {\r | |
124 | // remove previous highlight\r | |
125 | if (CurrentWatch)\r | |
126 | {\r | |
127 | model->item((int)(CurrentWatch - 1), 0)->setBackground(QColor(255, 255, 255));\r | |
128 | model->item((int)(CurrentWatch - 1), 1)->setBackground(QColor(255, 255, 255));\r | |
129 | model->item((int)(CurrentWatch - 1), 2)->setBackground(QColor(255, 255, 255));\r | |
130 | }\r | |
131 | // Get the slider maximum position\r | |
132 | int MaxSlider = TableView->verticalScrollBar()->maximum(); \r | |
133 | // Number of items displayed in the scroll bar slider\r | |
134 | int DeltaSlider = (int)NbWatch - MaxSlider;\r | |
135 | // set the scroll bar\r | |
136 | TableView->verticalScrollBar()->setSliderPosition((int)i - (DeltaSlider / 2) - 1);\r | |
137 | // highlight watch symbol\r | |
138 | CurrentWatch = i;\r | |
139 | model->item((int)(CurrentWatch - 1), 0)->setBackground(QColor(0xff, 0xfa, 0xcd));\r | |
140 | model->item((int)(CurrentWatch - 1), 1)->setBackground(QColor(0xff, 0xfa, 0xcd));\r | |
141 | model->item((int)(CurrentWatch - 1), 2)->setBackground(QColor(0xff, 0xfa, 0xcd));\r | |
142 | // allow new symbol\r | |
143 | symbol->setText("");\r | |
144 | }\r | |
145 | else\r | |
146 | {\r | |
147 | // invalid symbol\r | |
148 | symbol->setStyleSheet("color: red");\r | |
149 | }\r | |
150 | ||
151 | // user can enter a symbol | |
152 | symbol->setEnabled(true); | |
153 | symbol->setFocus(); | |
154 | } | |
155 | ||
156 | ||
157 | // | |
158 | void AllWatchBrowserWindow::SelectSearchSymbol(void)\r | |
159 | {\r | |
160 | symbol->setStyleSheet("color: black");\r | |
161 | }\r | |
162 | \r | |
163 | \r | |
a4e46c05 JPM |
164 | //\r |
165 | void AllWatchBrowserWindow::Reset(void)\r | |
166 | {\r | |
0203b5fd | 167 | free(PtrWatchInfo);\r |
a4e46c05 JPM |
168 | NbWatch = 0;\r |
169 | PtrWatchInfo = NULL;\r | |
0203b5fd JPM |
170 | }\r |
171 | \r | |
172 | \r | |
173 | //\r | |
174 | void AllWatchBrowserWindow::RefreshContents(void)\r | |
175 | {\r | |
2b91c435 JPM |
176 | char msg[100];\r |
177 | #ifdef AW_LAYOUTTEXTS\r | |
0203b5fd | 178 | char string[1024];\r |
2b91c435 | 179 | #endif\r |
0203b5fd | 180 | QString WatchAll;\r |
2b91c435 JPM |
181 | size_t Error = AW_NOERROR;\r |
182 | char *PtrValue;\r | |
0203b5fd JPM |
183 | \r |
184 | if (isVisible())\r | |
185 | {\r | |
186 | if (!NbWatch)\r | |
187 | {\r | |
2b91c435 | 188 | // Pre-catch the information for each global variables\r |
0203b5fd JPM |
189 | if (NbWatch = DBGManager_GetNbGlobalVariables())\r |
190 | {\r | |
191 | PtrWatchInfo = (WatchInfo *)calloc(NbWatch, sizeof(WatchInfo));\r | |
8d705db0 JPM |
192 | #ifndef AW_LAYOUTTEXTS\r |
193 | #ifdef AW_SORTINGFILTER\r | |
194 | TableView->setSortingEnabled(false);\r | |
195 | #endif\r | |
196 | model->setRowCount(0);\r | |
197 | #endif\r | |
2b91c435 | 198 | for (uint32_t i = AW_STARTNUMVARIABLE; i < NbWatch; i++)\r |
0203b5fd JPM |
199 | {\r |
200 | PtrWatchInfo[i].PtrVariableName = DBGManager_GetGlobalVariableName(i + 1);\r | |
0203b5fd | 201 | PtrWatchInfo[i].TypeTag = DBGManager_GetGlobalVariableTypeTag(i + 1);\r |
2b91c435 JPM |
202 | #ifdef AW_LAYOUTTEXTS\r |
203 | PtrWatchInfo[i].addr = DBGManager_GetGlobalVariableAdr(i + 1);\r | |
0203b5fd JPM |
204 | if (!strlen(PtrWatchInfo[i].PtrVariableBaseTypeName = DBGManager_GetGlobalVariableTypeName(i + 1)))\r |
205 | {\r | |
206 | PtrWatchInfo[i].PtrVariableBaseTypeName = (char *)"<font color='#ff0000'>N/A</font>";\r | |
207 | }\r | |
2b91c435 JPM |
208 | #else\r |
209 | PtrWatchInfo[i].PtrVariableBaseTypeName = DBGManager_GetGlobalVariableTypeName(i + 1);\r | |
8d705db0 | 210 | model->insertRow(i);\r |
2b91c435 | 211 | #endif\r |
0203b5fd JPM |
212 | }\r |
213 | }\r | |
214 | }\r | |
8d705db0 | 215 | \r |
2b91c435 | 216 | if (NbWatch)\r |
0203b5fd | 217 | {\r |
2b91c435 | 218 | for (uint32_t i = AW_STARTNUMVARIABLE; i < NbWatch; i++)\r |
0203b5fd | 219 | {\r |
2b91c435 JPM |
220 | if ((PtrWatchInfo[i].TypeTag & (DBG_TAG_TYPE_array | DBG_TAG_TYPE_structure)))\r |
221 | {\r | |
222 | #if defined(AW_SUPPORTARRAY) || defined(AW_SUPPORTSTRUCTURE)\r | |
223 | //PtrValue = (char *)memcpy(Value, &jaguarMainRAM[PtrWatchInfo[i].addr], 20);\r | |
224 | PtrValue = NULL;\r | |
225 | #else\r | |
226 | PtrValue = NULL;\r | |
227 | #endif\r | |
228 | }\r | |
229 | else\r | |
230 | {\r | |
231 | PtrValue = DBGManager_GetGlobalVariableValue(i + 1);\r | |
232 | }\r | |
233 | #ifdef AW_LAYOUTTEXTS\r | |
234 | if (i)\r | |
235 | {\r | |
236 | WatchAll += QString("<br>");\r | |
237 | }\r | |
238 | sprintf(string, "%i : %s | %s | 0x%06X | %s", (i + 1), PtrWatchInfo[i].PtrVariableBaseTypeName, PtrWatchInfo[i].PtrVariableName, (unsigned int)PtrWatchInfo[i].addr, PtrValue ? PtrValue : (char *)"<font color='#ff0000'>N/A</font>");\r | |
0203b5fd | 239 | WatchAll += QString(string);\r |
2b91c435 | 240 | #else\r |
2b91c435 JPM |
241 | model->setItem(i, 0, new QStandardItem(QString("%1").arg(PtrWatchInfo[i].PtrVariableName)));\r |
242 | model->setItem(i, 1, new QStandardItem(QString("%1").arg(PtrValue)));\r | |
243 | model->setItem(i, 2, new QStandardItem(QString("%1").arg(PtrWatchInfo[i].PtrVariableBaseTypeName)));\r | |
244 | #endif\r | |
0203b5fd | 245 | }\r |
2b91c435 JPM |
246 | #ifdef AW_LAYOUTTEXTS\r |
247 | text->clear();\r | |
248 | text->setText(WatchAll);\r | |
4873fe0a | 249 | #else\r |
8d705db0 | 250 | #ifdef AW_SORTINGFILTER\r |
4873fe0a | 251 | TableView->setSortingEnabled(true);\r |
8d705db0 | 252 | #endif\r |
2b91c435 JPM |
253 | #endif\r |
254 | sprintf(msg, "Ready");\r | |
255 | }\r | |
256 | else\r | |
257 | {\r | |
258 | sprintf(msg, "No watches");\r | |
259 | Error = AW_NOALLWATCH;\r | |
0203b5fd JPM |
260 | }\r |
261 | \r | |
2b91c435 JPM |
262 | // Display status bar\r |
263 | if (Error)\r | |
264 | {\r | |
265 | if ((Error & AW_WARNING))\r | |
266 | {\r | |
267 | statusbar->setStyleSheet("background-color: lightyellow; font: bold");\r | |
268 | }\r | |
269 | else\r | |
270 | {\r | |
271 | statusbar->setStyleSheet("background-color: tomato; font: bold");\r | |
272 | }\r | |
273 | }\r | |
274 | else\r | |
275 | {\r | |
276 | statusbar->setStyleSheet("background-color: lightgreen; font: bold");\r | |
277 | }\r | |
278 | statusbar->showMessage(QString(msg));\r | |
0203b5fd JPM |
279 | }\r |
280 | }\r | |
281 | \r | |
282 | \r | |
117e41c2 | 283 | // Handle keyboard event\r |
0203b5fd JPM |
284 | void AllWatchBrowserWindow::keyPressEvent(QKeyEvent * e)\r |
285 | {\r | |
117e41c2 | 286 | // ESC to close / hide the window\r |
0203b5fd | 287 | if (e->key() == Qt::Key_Escape)\r |
0203b5fd | 288 | {\r |
a4e46c05 | 289 | hide();\r |
0203b5fd | 290 | }\r |
117e41c2 JPM |
291 | else\r |
292 | {\r | |
293 | // select the \r | |
294 | if (e->key() == Qt::Key_Return)\r | |
295 | {\r | |
296 | SearchSymbol();\r | |
297 | }\r | |
298 | }\r | |
0203b5fd | 299 | }\r |
0203b5fd | 300 | \r |