// Who When What\r
// --- ---------- -----------------------------------------------------------\r
// JPM 12/07/2017 Created this file\r
+// JPM 09/14/2018 Added a status bar, better status report and set information values in a tab\r
+// JPM April/2019 Added a sorting filter, tableview unique rows creation\r
//\r
\r
// STILL TO DO:\r
+// Better presentation\r
+// To set the information display at the right\r
+// To understand/fix the problem with the sorting filter\r
+// Display arrays information\r
+// Display structures information\r
//\r
\r
+//#define AW_SORTINGFILTER // Authorise the sorting filtes\r
+//#define AW_DEBUGNUMVARIABLE 4415 // Set the global variable number to debug\r
+#ifndef AW_DEBUGNUMVARIABLE\r
+#define AW_STARTNUMVARIABLE 0 // Must be kept to 0 in case of no debug is required\r
+#else\r
+#define AW_STARTNUMVARIABLE AW_DEBUGNUMVARIABLE - 1\r
+#endif\r
+\r
+\r
#include "debugger/allwatchbrowser.h"\r
#include "memory.h"\r
#include "debugger/DBGManager.h"\r
\r
\r
+// \r
AllWatchBrowserWindow::AllWatchBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r
- layout(new QVBoxLayout), text(new QTextBrowser),\r
-// layout(new QVBoxLayout), text(new QLabel),\r
-// refresh(new QPushButton(tr("Refresh"))),\r
-// address(new QLineEdit),\r
-// go(new QPushButton(tr("Go"))),\r
-// memBase(0),\r
- NbWatch(0),\r
- PtrWatchInfo(NULL)\r
+layout(new QVBoxLayout),\r
+symbol(new QLineEdit),\r
+search(new QPushButton(tr("Search"))),\r
+#ifdef AW_LAYOUTTEXTS\r
+text(new QTextBrowser),\r
+#else\r
+TableView(new QTableView),\r
+model(new QStandardItemModel),\r
+#endif\r
+NbWatch(0),\r
+CurrentWatch(0),\r
+statusbar(new QStatusBar),\r
+PtrWatchInfo(NULL)\r
{\r
setWindowTitle(tr("All Watch"));\r
\r
-// address->setInputMask("hhhhhh");\r
-// QHBoxLayout * hbox1 = new QHBoxLayout;\r
-// hbox1->addWidget(refresh);\r
-// hbox1->addWidget(address);\r
-// hbox1->addWidget(go);\r
-\r
- // Need to set the size as well...\r
-// resize(560, 480);\r
-\r
+ // set the font\r
QFont fixedFont("Lucida Console", 8, QFont::Normal);\r
-// QFont fixedFont("", 8, QFont::Normal);\r
fixedFont.setStyleHint(QFont::TypeWriter);\r
- text->setFont(fixedFont);\r
-//// layout->setSizeConstraint(QLayout::SetFixedSize);\r
- setLayout(layout);\r
\r
+#ifdef AW_LAYOUTTEXTS\r
+ // Set original layout\r
+ text->setFont(fixedFont);\r
layout->addWidget(text);\r
-// layout->addWidget(refresh);\r
-// layout->addLayout(hbox1);\r
+#else\r
+ // Set the new layout with proper identation and readibility\r
+ model->setColumnCount(3);\r
+ model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));\r
+ model->setHeaderData(1, Qt::Horizontal, QObject::tr("Value"));\r
+ model->setHeaderData(2, Qt::Horizontal, QObject::tr("Type"));\r
+ // Information table\r
+ TableView->setModel(model);\r
+ TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);\r
+ TableView->setShowGrid(0);\r
+ TableView->setFont(fixedFont);\r
+ TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());\r
+ TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);\r
+ layout->addWidget(TableView);\r
+#endif\r
+\r
+ // search bar\r
+ QHBoxLayout * hbox1 = new QHBoxLayout;\r
+ symbol->setPlaceholderText("symbol name");\r
+ hbox1->addWidget(symbol);\r
+ hbox1->addWidget(search);\r
+ layout->addLayout(hbox1);\r
+\r
+ // status bar\r
+ layout->addWidget(statusbar);\r
+ setLayout(layout);\r
\r
-// connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));\r
-// connect(go, SIGNAL(clicked()), this, SLOT(GoToAddress()));\r
+ // connect slot\r
+ connect(search, SIGNAL(clicked()), this, SLOT(SearchSymbol()));\r
+ connect(symbol, SIGNAL(cursorPositionChanged(int, int)), this, SLOT(SelectSearchSymbol()));\r
}\r
\r
\r
//\r
AllWatchBrowserWindow::~AllWatchBrowserWindow(void)\r
{\r
- NbWatch = 0;\r
+ Reset();\r
+}\r
+\r
+\r
+// Search the symbol in the watch list\r
+void AllWatchBrowserWindow::SearchSymbol(void)
+{
+ bool found = false;
+ size_t i;
+
+ // user cannot enter symbol to allow the search
+ symbol->setDisabled(true);
+
+ // look for the symbol in the watch list
+ for (i = AW_STARTNUMVARIABLE; (i < NbWatch) && !found; i++)\r
+ {\r
+ // check symbol presence\r
+ if (!symbol->text().compare(PtrWatchInfo[i].PtrVariableName, Qt::CaseSensitive))\r
+ {\r
+ found = true;\r
+ }\r
+ }\r
+\r
+ if (found)\r
+ {\r
+ // remove previous highlight\r
+ if (CurrentWatch)\r
+ {\r
+ model->item((int)(CurrentWatch - 1), 0)->setBackground(QColor(255, 255, 255));\r
+ model->item((int)(CurrentWatch - 1), 1)->setBackground(QColor(255, 255, 255));\r
+ model->item((int)(CurrentWatch - 1), 2)->setBackground(QColor(255, 255, 255));\r
+ }\r
+ // Get the slider maximum position\r
+ int MaxSlider = TableView->verticalScrollBar()->maximum(); \r
+ // Number of items displayed in the scroll bar slider\r
+ int DeltaSlider = (int)NbWatch - MaxSlider;\r
+ // set the scroll bar\r
+ TableView->verticalScrollBar()->setSliderPosition((int)i - (DeltaSlider / 2) - 1);\r
+ // highlight watch symbol\r
+ CurrentWatch = i;\r
+ model->item((int)(CurrentWatch - 1), 0)->setBackground(QColor(0xff, 0xfa, 0xcd));\r
+ model->item((int)(CurrentWatch - 1), 1)->setBackground(QColor(0xff, 0xfa, 0xcd));\r
+ model->item((int)(CurrentWatch - 1), 2)->setBackground(QColor(0xff, 0xfa, 0xcd));\r
+ // allow new symbol\r
+ symbol->setText("");\r
+ }\r
+ else\r
+ {\r
+ // invalid symbol\r
+ symbol->setStyleSheet("color: red");\r
+ }\r
+
+ // user can enter a symbol
+ symbol->setEnabled(true);
+ symbol->setFocus();
+}
+
+
+//
+void AllWatchBrowserWindow::SelectSearchSymbol(void)\r
+{\r
+ symbol->setStyleSheet("color: black");\r
+}\r
+\r
+\r
+//\r
+void AllWatchBrowserWindow::Reset(void)\r
+{\r
free(PtrWatchInfo);\r
+ NbWatch = 0;\r
+ PtrWatchInfo = NULL;\r
}\r
\r
\r
//\r
void AllWatchBrowserWindow::RefreshContents(void)\r
{\r
+ char msg[100];\r
+#ifdef AW_LAYOUTTEXTS\r
char string[1024];\r
-// char buf[64];\r
+#endif\r
QString WatchAll;\r
+ size_t Error = AW_NOERROR;\r
+ char *PtrValue;\r
\r
if (isVisible())\r
{\r
if (!NbWatch)\r
{\r
+ // Pre-catch the information for each global variables\r
if (NbWatch = DBGManager_GetNbGlobalVariables())\r
{\r
PtrWatchInfo = (WatchInfo *)calloc(NbWatch, sizeof(WatchInfo));\r
-#ifdef _MSC_VER\r
-#pragma message("Warning: !!! Need to check the memory desalocation for PtrWatchInfo !!!")\r
-#else\r
- #warning "!!! Need to do the memory desalocation for PtrWatchInfo !!!"\r
-#endif // _MSC_VER\r
- \r
- for (uint32_t i = 0; i < NbWatch; i++)\r
+#ifndef AW_LAYOUTTEXTS\r
+#ifdef AW_SORTINGFILTER\r
+ TableView->setSortingEnabled(false);\r
+#endif\r
+ model->setRowCount(0);\r
+#endif\r
+ for (uint32_t i = AW_STARTNUMVARIABLE; i < NbWatch; i++)\r
{\r
PtrWatchInfo[i].PtrVariableName = DBGManager_GetGlobalVariableName(i + 1);\r
- PtrWatchInfo[i].addr = DBGManager_GetGlobalVariableAdr(i + 1);\r
PtrWatchInfo[i].TypeTag = DBGManager_GetGlobalVariableTypeTag(i + 1);\r
+#ifdef AW_LAYOUTTEXTS\r
+ PtrWatchInfo[i].addr = DBGManager_GetGlobalVariableAdr(i + 1);\r
if (!strlen(PtrWatchInfo[i].PtrVariableBaseTypeName = DBGManager_GetGlobalVariableTypeName(i + 1)))\r
{\r
PtrWatchInfo[i].PtrVariableBaseTypeName = (char *)"<font color='#ff0000'>N/A</font>";\r
}\r
+#else\r
+ PtrWatchInfo[i].PtrVariableBaseTypeName = DBGManager_GetGlobalVariableTypeName(i + 1);\r
+ model->insertRow(i);\r
+#endif\r
}\r
}\r
}\r
\r
- for (uint32_t i = 0; i < NbWatch; i++)\r
+ if (NbWatch)\r
{\r
- if (PtrWatchInfo[i].PtrVariableName && PtrWatchInfo[i].PtrVariableBaseTypeName)\r
+ for (uint32_t i = AW_STARTNUMVARIABLE; i < NbWatch; i++)\r
{\r
- sprintf(string, "%i : %s | %s | 0x%06X | %s", (i + 1), PtrWatchInfo[i].PtrVariableBaseTypeName, PtrWatchInfo[i].PtrVariableName, (unsigned int)PtrWatchInfo[i].addr, (PtrWatchInfo[i].TypeTag & 0x8) ? "" : DBGManager_GetGlobalVariableValue(i + 1));\r
- WatchAll += QString(string);\r
- sprintf(string, "<br>");\r
+ if ((PtrWatchInfo[i].TypeTag & (DBG_TAG_TYPE_array | DBG_TAG_TYPE_structure)))\r
+ {\r
+#if defined(AW_SUPPORTARRAY) || defined(AW_SUPPORTSTRUCTURE)\r
+ //PtrValue = (char *)memcpy(Value, &jaguarMainRAM[PtrWatchInfo[i].addr], 20);\r
+ PtrValue = NULL;\r
+#else\r
+ PtrValue = NULL;\r
+#endif\r
+ }\r
+ else\r
+ {\r
+ PtrValue = DBGManager_GetGlobalVariableValue(i + 1);\r
+ }\r
+#ifdef AW_LAYOUTTEXTS\r
+ if (i)\r
+ {\r
+ WatchAll += QString("<br>");\r
+ }\r
+ 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
WatchAll += QString(string);\r
+#else\r
+ model->setItem(i, 0, new QStandardItem(QString("%1").arg(PtrWatchInfo[i].PtrVariableName)));\r
+ model->setItem(i, 1, new QStandardItem(QString("%1").arg(PtrValue)));\r
+ model->setItem(i, 2, new QStandardItem(QString("%1").arg(PtrWatchInfo[i].PtrVariableBaseTypeName)));\r
+#endif\r
}\r
+#ifdef AW_LAYOUTTEXTS\r
+ text->clear();\r
+ text->setText(WatchAll);\r
+#else\r
+#ifdef AW_SORTINGFILTER\r
+ TableView->setSortingEnabled(true);\r
+#endif\r
+#endif\r
+ sprintf(msg, "Ready");\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "No watches");\r
+ Error = AW_NOALLWATCH;\r
}\r
\r
- text->clear();\r
- text->setText(WatchAll);\r
+ // Display status bar\r
+ if (Error)\r
+ {\r
+ if ((Error & AW_WARNING))\r
+ {\r
+ statusbar->setStyleSheet("background-color: lightyellow; font: bold");\r
+ }\r
+ else\r
+ {\r
+ statusbar->setStyleSheet("background-color: tomato; font: bold");\r
+ }\r
+ }\r
+ else\r
+ {\r
+ statusbar->setStyleSheet("background-color: lightgreen; font: bold");\r
+ }\r
+ statusbar->showMessage(QString(msg));\r
}\r
}\r
\r
\r
-#if 0\r
+// Handle keyboard event\r
void AllWatchBrowserWindow::keyPressEvent(QKeyEvent * e)\r
{\r
+ // ESC to close / hide the window\r
if (e->key() == Qt::Key_Escape)\r
- hide();\r
- else if (e->key() == Qt::Key_PageUp)\r
- {\r
- memBase -= 480;\r
-\r
- if (memBase < 0)\r
- memBase = 0;\r
-\r
- RefreshContents();\r
- }\r
- else if (e->key() == Qt::Key_PageDown)\r
{\r
- memBase += 480;\r
-\r
- if (memBase > (0x200000 - 480))\r
- memBase = 0x200000 - 480;\r
-\r
- RefreshContents();\r
- }\r
- else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus)\r
- {\r
- memBase -= 16;\r
-\r
- if (memBase < 0)\r
- memBase = 0;\r
-\r
- RefreshContents();\r
+ hide();\r
}\r
- else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal)\r
+ else\r
{\r
- memBase += 16;\r
-\r
- if (memBase > (0x200000 - 480))\r
- memBase = 0x200000 - 480;\r
-\r
- RefreshContents();\r
+ // select the \r
+ if (e->key() == Qt::Key_Return)\r
+ {\r
+ SearchSymbol();\r
+ }\r
}\r
}\r
-#endif\r
-\r
-\r
-#if 0\r
-void AllWatchBrowserWindow::GoToAddress(void)\r
-{\r
- bool ok;\r
- QString newAddress = address->text();\r
- memBase = newAddress.toUInt(&ok, 16);\r
- RefreshContents();\r
-}\r
-#endif\r
\r