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