diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c63fa8..674b22d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ - Detached and minimized - Attached in Seer's tab view (with gdb logs and seer logs). * Improved handling of \n \t and other escaped characters in gdb log window. +* Show breakpoint info as a tooltip if the breakpoint icon is clicked with + LMB and held down. ## [2.4] - 2024-03-18 * Changed main icon to a more license friendly one. diff --git a/src/SeerBreakpointsBrowserWidget.cpp b/src/SeerBreakpointsBrowserWidget.cpp index 24b9f50b..6df1534a 100644 --- a/src/SeerBreakpointsBrowserWidget.cpp +++ b/src/SeerBreakpointsBrowserWidget.cpp @@ -121,7 +121,7 @@ void SeerBreakpointsBrowserWidget::handleText (const QString& text) { QStringList bkpt_list = Seer::parse(newtext, "bkpt=", '{', '}', false); - for ( const auto& bkpt_text : bkpt_list ) { + for (const auto& bkpt_text : bkpt_list) { // // A different way (better?) of parsing the table output diff --git a/src/SeerEditorManagerWidget.cpp b/src/SeerEditorManagerWidget.cpp index 97b7d1df..1057043e 100644 --- a/src/SeerEditorManagerWidget.cpp +++ b/src/SeerEditorManagerWidget.cpp @@ -416,6 +416,7 @@ const QString& SeerEditorManagerWidget::editorExternalEditorCommand () const { void SeerEditorManagerWidget::handleText (const QString& text) { + // Update the current line. if (text.startsWith("*stopped")) { //qDebug() << ":stopped:" << text; @@ -489,6 +490,7 @@ void SeerEditorManagerWidget::handleText (const QString& text) { return; + // Refresh the breakpoints for all opened files. }else if (text.startsWith("^done,BreakpointTable={") && text.endsWith("}")) { // @@ -558,6 +560,35 @@ void SeerEditorManagerWidget::handleText (const QString& text) { } } + // Send the info for an individual breakpoint to all opened files. + // Each opened file can accept it (or reject it) to display the + // info as a ToolTip. + }else if (text.contains(QRegularExpression("^([0-9]+)\\^done,BreakpointTable={")) && text.endsWith("}")) { + + // + // See SeerBreakpointsBrowserWidget.cpp + // + // 7^done,BreakpointTable={ + // ... + // } + // + + // Loop through each opened file and forward the text. + SeerEditorManagerEntries::iterator i = beginEntry(); + SeerEditorManagerEntries::iterator e = endEntry(); + + while (i != e) { + i->widget->sourceArea()->handleText(text); + i++; + } + + // Forward the text to the assembly widget, if there is one. + SeerEditorWidgetAssembly* assemblyWidget = assemblyWidgetTab(); + + if (assemblyWidget) { + assemblyWidget->assemblyArea()->handleText(text); + } + }else if (text.startsWith("^done,stack=[") && text.endsWith("]")) { //qDebug() << ":stack:" << text; @@ -828,6 +859,7 @@ SeerEditorWidgetSource* SeerEditorManagerWidget::createEditorWidgetTab (const QS QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::deleteBreakpoints, this, &SeerEditorManagerWidget::handleDeleteBreakpoints); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::enableBreakpoints, this, &SeerEditorManagerWidget::handleEnableBreakpoints); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::disableBreakpoints, this, &SeerEditorManagerWidget::handleDisableBreakpoints); + QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::infoBreakpoint, this, &SeerEditorManagerWidget::handleInfoBreakpoint); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::refreshBreakpointsStackFrames, this, &SeerEditorManagerWidget::handleRefreshBreakpointsStackFrames); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::runToLine, this, &SeerEditorManagerWidget::handleRunToLine); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addVariableLoggerExpression, this, &SeerEditorManagerWidget::handleAddVariableLoggerExpression); @@ -888,6 +920,7 @@ SeerEditorWidgetSource* SeerEditorManagerWidget::createEditorWidgetTab (const QS QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::deleteBreakpoints, this, &SeerEditorManagerWidget::handleDeleteBreakpoints); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::enableBreakpoints, this, &SeerEditorManagerWidget::handleEnableBreakpoints); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::disableBreakpoints, this, &SeerEditorManagerWidget::handleDisableBreakpoints); + QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::infoBreakpoint, this, &SeerEditorManagerWidget::handleInfoBreakpoint); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::refreshBreakpointsStackFrames, this, &SeerEditorManagerWidget::handleRefreshBreakpointsStackFrames); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::runToLine, this, &SeerEditorManagerWidget::handleRunToLine); QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addVariableLoggerExpression, this, &SeerEditorManagerWidget::handleAddVariableLoggerExpression); @@ -1131,44 +1164,40 @@ void SeerEditorManagerWidget::handleAddAlternateDirectory (QString path) { void SeerEditorManagerWidget::handleInsertBreakpoint (QString breakpoint) { - //qDebug() << breakpoint; - // rethrow emit insertBreakpoint (breakpoint); } void SeerEditorManagerWidget::handleInsertPrintpoint (QString printpoint) { - //qDebug() << printpoint; - // rethrow emit insertPrintpoint (printpoint); } void SeerEditorManagerWidget::handleDeleteBreakpoints (QString breakpoints) { - //qDebug() << breakpoints; - // rethrow emit deleteBreakpoints (breakpoints); } void SeerEditorManagerWidget::handleEnableBreakpoints (QString breakpoints) { - //qDebug() << breakpoints; - // rethrow emit enableBreakpoints (breakpoints); } void SeerEditorManagerWidget::handleDisableBreakpoints (QString breakpoints) { - //qDebug() << breakpoints; - // rethrow emit disableBreakpoints (breakpoints); } +void SeerEditorManagerWidget::handleInfoBreakpoint (int breakpointid, QString breakpoint) { + + // rethrow + emit infoBreakpoint (breakpointid, breakpoint); +} + void SeerEditorManagerWidget::handleRefreshBreakpointsStackFrames () { // Ask for the breakpoint list to be resent, in case files have breakpoints. @@ -1180,80 +1209,60 @@ void SeerEditorManagerWidget::handleRefreshBreakpointsStackFrames () { void SeerEditorManagerWidget::handleRunToLine (QString fullname, int lineno) { - //qDebug() << fullname << lineno; - // rethrow emit runToLine (fullname, lineno); } void SeerEditorManagerWidget::handleRunToAddress (QString address) { - //qDebug() << address; - // rethrow emit runToAddress (address); } void SeerEditorManagerWidget::handleAddVariableLoggerExpression (QString expression) { - //qDebug() << expression; - // rethrow emit addVariableLoggerExpression (expression); } void SeerEditorManagerWidget::handleAddVariableTrackerExpression (QString expression) { - //qDebug() << expression; - // rethrow emit addVariableTrackerExpression (expression); } void SeerEditorManagerWidget::handleRefreshVariableTrackerValues () { - //qDebug(); - // rethrow emit refreshVariableTrackerValues (); } void SeerEditorManagerWidget::handleEvaluateVariableExpression (int expressionid, QString expression) { - //qDebug(); - // rethrow emit evaluateVariableExpression (expressionid, expression); } void SeerEditorManagerWidget::handleAddMemoryVisualizer (QString expression) { - //qDebug() << expression; - // rethrow emit addMemoryVisualize (expression); } void SeerEditorManagerWidget::handleAddArrayVisualizer (QString expression) { - //qDebug() << expression; - // rethrow emit addArrayVisualize (expression); } void SeerEditorManagerWidget::handleAddStructVisualizer (QString expression) { - //qDebug() << expression; - // rethrow emit addStructVisualize (expression); } void SeerEditorManagerWidget::handleRequestAssembly (QString address) { - //qDebug() << address; - // rethrow emit requestAssembly (address); @@ -1264,8 +1273,6 @@ void SeerEditorManagerWidget::handleRequestAssembly (QString address) { void SeerEditorManagerWidget::handleRequestSourceAndAssembly (QString address) { - //qDebug() << address; - // rethrow emit requestSourceAndAssembly (address); diff --git a/src/SeerEditorManagerWidget.h b/src/SeerEditorManagerWidget.h index 0d1b8aee..0ae1959c 100644 --- a/src/SeerEditorManagerWidget.h +++ b/src/SeerEditorManagerWidget.h @@ -75,6 +75,7 @@ class SeerEditorManagerWidget : public QWidget, protected Ui::SeerEditorManagerW void handleDeleteBreakpoints (QString breakpoints); void handleEnableBreakpoints (QString breakpoints); void handleDisableBreakpoints (QString breakpoints); + void handleInfoBreakpoint (int breakpointid, QString breakpoint); void handleRefreshBreakpointsStackFrames (); void handleRunToLine (QString fullname, int lineno); void handleRunToAddress (QString address); @@ -104,6 +105,7 @@ class SeerEditorManagerWidget : public QWidget, protected Ui::SeerEditorManagerW void deleteBreakpoints (QString breakpoints); void enableBreakpoints (QString breakpoints); void disableBreakpoints (QString breakpoints); + void infoBreakpoint (int breakpointid, QString breakpoint); void runToLine (QString file, int lineno); void runToAddress (QString address); void addVariableLoggerExpression (QString expression); diff --git a/src/SeerEditorWidgetSource.h b/src/SeerEditorWidgetSource.h index 26722655..c0292479 100644 --- a/src/SeerEditorWidgetSource.h +++ b/src/SeerEditorWidgetSource.h @@ -84,6 +84,7 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit { void showContextMenu (const QPoint& pos, const QPointF& globalPos); void setQuickBreakpoint (QMouseEvent* event); void setQuickRunToLine (QMouseEvent* event); + void showBreakpointToolTip (QMouseEvent* event); void clearExpression (); @@ -105,6 +106,7 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit { void deleteBreakpoints (QString breakpoints); void enableBreakpoints (QString breakpoints); void disableBreakpoints (QString breakpoints); + void infoBreakpoint (int breakpointid, QString breakpoint); void refreshBreakpointsStackFrames (); void runToLine (QString fullname, int lineno); void addVariableLoggerExpression (QString expression); @@ -123,6 +125,7 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit { void handleText (const QString& text); void handleHighlighterSettingsChanged (); void handleWatchFileModified (const QString& path); + void handleBreakpointToolTip (QPoint pos, const QString& text); protected: void resizeEvent (QResizeEvent* event); @@ -159,6 +162,8 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit { int _selectedExpressionId; QString _selectedExpressionName; QString _selectedExpressionValue; + QPoint _selectedBreakpointPosition; + int _selectedBreakpointId; SeerEditorWidgetSourceLineNumberArea* _lineNumberArea; SeerEditorWidgetSourceBreakPointArea* _breakPointArea; diff --git a/src/SeerEditorWidgetSourceAreas.cpp b/src/SeerEditorWidgetSourceAreas.cpp index 63de28d9..5bfcfb03 100644 --- a/src/SeerEditorWidgetSourceAreas.cpp +++ b/src/SeerEditorWidgetSourceAreas.cpp @@ -40,6 +40,7 @@ SeerEditorWidgetSourceArea::SeerEditorWidgetSourceArea(QWidget* parent) : SeerPl _sourceHighlighterEnabled = true; _sourceTabSize = 4; _selectedExpressionId = Seer::createID(); + _selectedBreakpointId = Seer::createID(); QFont font("monospace"); font.setStyleHint(QFont::Monospace); @@ -54,9 +55,11 @@ SeerEditorWidgetSourceArea::SeerEditorWidgetSourceArea(QWidget* parent) : SeerPl _lineNumberArea = new SeerEditorWidgetSourceLineNumberArea(this); _breakPointArea = new SeerEditorWidgetSourceBreakPointArea(this); + _breakPointArea->setMouseTracking(true); _miniMapArea = new SeerEditorWidgetSourceMiniMapArea(this); _miniMapPixmap = 0; + enableLineNumberArea(true); enableBreakPointArea(true); enableMiniMapArea(false); // Doesn't work yet. Need to work on the "mini" part. @@ -505,8 +508,6 @@ bool SeerEditorWidgetSourceArea::event(QEvent* event) { // If the hover text is empty, do nothing. Reset things. Exit this function. QString word = cursor.selectedText(); - //qDebug() << "Hover text=" << word; - if (word.isEmpty() == true) { QToolTip::hideText(); @@ -623,8 +624,6 @@ void SeerEditorWidgetSourceArea::open (const QString& fullname, const QString& f // QString filename = findFile(_file, _fullname, _alternateDirectory, _alternateDirectories); - //qDebug() << "Loading" << _file << "from" << filename; - if (filename == "") { QMessageBox::critical(this, "Can't find source file.", "Can't find : " + _file + "\nIts location may have changed."); @@ -825,8 +824,6 @@ QString SeerEditorWidgetSourceArea::findFile (const QString& file, const QString while (iter.hasNext()) { - //qDebug() << iter.next(); - QString filename = iter.next() + "/" + file; if (QFileInfo::exists(filename) == true) { @@ -840,8 +837,6 @@ QString SeerEditorWidgetSourceArea::findFile (const QString& file, const QString void SeerEditorWidgetSourceArea::setCurrentLine (int lineno) { - //qDebug() << lineno << file(); - // Clear current line selections. _currentLinesExtraSelections.clear(); @@ -874,8 +869,6 @@ void SeerEditorWidgetSourceArea::setCurrentLine (int lineno) { void SeerEditorWidgetSourceArea::scrollToLine (int lineno) { - //qDebug() << lineno << file(); - // Scroll to the first line if we went before it. if (lineno < 1) { lineno = 1; @@ -897,8 +890,6 @@ void SeerEditorWidgetSourceArea::scrollToLine (int lineno) { void SeerEditorWidgetSourceArea::clearCurrentLines () { - //qDebug() << file(); - _currentLinesExtraSelections.clear(); refreshExtraSelections(); @@ -906,8 +897,6 @@ void SeerEditorWidgetSourceArea::clearCurrentLines () { void SeerEditorWidgetSourceArea::addCurrentLine (int lineno) { - //qDebug() << lineno << file(); - // Any line will be highlighted with a yellow line. // The 'yellow' color is for the current line of the most recent stack frame. // The 'grey' color is for older stack frames. @@ -1242,8 +1231,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin return; } - //qDebug() << dlg.breakpointText(); - // Emit the create breakpoint signal. emit insertBreakpoint(dlg.breakpointText()); @@ -1263,8 +1250,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin return; } - //qDebug() << dlg.printpointText(); - // Emit the create breakpoint signal. emit insertPrintpoint(dlg.printpointText()); @@ -1274,8 +1259,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle deleting a breakpoint. if (action == deleteAction) { - //qDebug() << "deleteBreakpoints" << lineno; - // Emit the delete breakpoint signal. emit deleteBreakpoints(QString("%1").arg(breakpointLineToNumber(lineno))); @@ -1285,8 +1268,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle enabling a breakpoint. if (action == enableAction) { - //qDebug() << "enableBreakpoints" << lineno; - // Emit the enable breakpoint signal. emit enableBreakpoints(QString("%1").arg(breakpointLineToNumber(lineno))); @@ -1296,8 +1277,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle disabling a breakpoint. if (action == disableAction) { - //qDebug() << "disableBreakpoints" << lineno; - // Emit the disable breakpoint signal. emit disableBreakpoints(QString("%1").arg(breakpointLineToNumber(lineno))); @@ -1307,8 +1286,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle running to a line number. if (action == runToLineAction) { - //qDebug() << "runToLine" << lineno; - // Emit the runToLine signal. emit runToLine(fullname(), lineno); @@ -1357,8 +1334,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding a variable to log. if (action == addVariableLoggerExpressionAction) { - //qDebug() << "addVariableLoggerExpression" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addVariableLoggerExpression(textCursor().selectedText()); @@ -1370,8 +1345,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding a variable to log. if (action == addVariableLoggerAsteriskExpressionAction) { - //qDebug() << "addVariableLoggerAsteriskExpression" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addVariableLoggerExpression(QString("*") + textCursor().selectedText()); @@ -1383,8 +1356,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding a variable to log. if (action == addVariableLoggerAmpersandExpressionAction) { - //qDebug() << "addVariableLoggerAmpersandExpression" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addVariableLoggerExpression(QString("&") + textCursor().selectedText()); @@ -1396,8 +1367,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding a variable to log. if (action == addVariableLoggerAsteriskAmpersandExpressionAction) { - //qDebug() << "addVariableLoggerAsteriskAmpersandExpression" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addVariableLoggerExpression(QString("*&") + textCursor().selectedText()); @@ -1409,8 +1378,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding a variable to track. if (action == addVariableTrackerExpressionAction) { - //qDebug() << "addVariableTrackerExpression" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addVariableTrackerExpression(textCursor().selectedText()); @@ -1423,8 +1390,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding a variable to track. if (action == addVariableTrackerAsteriskExpressionAction) { - //qDebug() << "addVariableTrackerAsteriskExpression" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addVariableTrackerExpression(QString("*") + textCursor().selectedText()); @@ -1437,8 +1402,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding a variable to track. if (action == addVariableTrackerAmpersandExpressionAction) { - //qDebug() << "addVariableTrackerAmpersandExpression" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addVariableTrackerExpression(QString("&") + textCursor().selectedText()); @@ -1451,8 +1414,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding a variable to track. if (action == addVariableTrackerAsteriskAmpersandExpressionAction) { - //qDebug() << "addVariableTrackerAsteriskAmpersandExpression" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addVariableTrackerExpression(QString("*&") + textCursor().selectedText()); @@ -1465,8 +1426,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding memory to visualize. if (action == addMemoryVisualizerAction) { - //qDebug() << "addMemoryVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addMemoryVisualize(textCursor().selectedText()); @@ -1478,8 +1437,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding memory to visualize. if (action == addMemoryAsteriskVisualizerAction) { - //qDebug() << "addMemoryAsteriskVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addMemoryVisualize(QString("*") + textCursor().selectedText()); @@ -1491,8 +1448,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding memory to visualize. if (action == addMemoryAmpersandVisualizerAction) { - //qDebug() << "addMemoryAmpersandVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addMemoryVisualize(QString("&") + textCursor().selectedText()); @@ -1504,8 +1459,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding array to visualize. if (action == addArrayVisualizerAction) { - //qDebug() << "addArrayVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addArrayVisualize(textCursor().selectedText()); @@ -1517,8 +1470,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding array to visualize. if (action == addArrayAsteriskVisualizerAction) { - //qDebug() << "addArrayAsteriskVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addArrayVisualize(QString("*") + textCursor().selectedText()); @@ -1530,8 +1481,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding array to visualize. if (action == addArrayAmpersandVisualizerAction) { - //qDebug() << "addArrayAmpersandVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addArrayVisualize(QString("&") + textCursor().selectedText()); @@ -1543,8 +1492,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding struct to visualize. if (action == addStructVisualizerAction) { - //qDebug() << "addStructVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addStructVisualize(textCursor().selectedText()); @@ -1556,8 +1503,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding struct to visualize. if (action == addStructAsteriskVisualizerAction) { - //qDebug() << "addStructAsteriskVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addStructVisualize(QString("*") + textCursor().selectedText()); @@ -1569,8 +1514,6 @@ void SeerEditorWidgetSourceArea::showContextMenu (const QPoint& pos, const QPoin // Handle adding struct to visualize. if (action == addStructAmpersandVisualizerAction) { - //qDebug() << "addStructAmpersandVisualizer" << lineno; - // Emit the signals. if (textCursor().selectedText() != "") { emit addStructVisualize(QString("&") + textCursor().selectedText()); @@ -1613,20 +1556,39 @@ void SeerEditorWidgetSourceArea::setQuickRunToLine (QMouseEvent* event) { int lineno = cursor.blockNumber()+1; - //qDebug() << "runToLine" << lineno; - // Emit the runToLine signal. emit runToLine(fullname(), lineno); return; } +void SeerEditorWidgetSourceArea::showBreakpointToolTip (QMouseEvent* event) { + + // Get the line number for the cursor position. + QTextCursor cursor = cursorForPosition(event->pos()); + + int lineno = cursor.blockNumber()+1; + + // If there is a breakpoint on the line, ask for its information. + if (hasBreakpointLine(lineno)) { + + _selectedBreakpointPosition = event->pos(); + + // Emit the info breakpoint signal. + emit infoBreakpoint(_selectedBreakpointId, QString("%1").arg(breakpointLineToNumber(lineno))); + + }else{ + _selectedBreakpointPosition = QPoint(); + } +} + void SeerEditorWidgetSourceArea::clearExpression() { _selectedExpressionCursor = QTextCursor(); _selectedExpressionPosition = QPoint(); _selectedExpressionName = ""; _selectedExpressionValue = ""; + _selectedBreakpointPosition = QPoint(); } void SeerEditorWidgetSourceArea::setHighlighterSettings (const SeerHighlighterSettings& settings) { @@ -1751,9 +1713,6 @@ void SeerEditorWidgetSourceArea::handleText (const QString& text) { QString file_text = Seer::parseFirst(frame_text, "file=", '"', '"', false); QString line_text = Seer::parseFirst(frame_text, "line=", '"', '"', false); - //qDebug() << frame_text; - //qDebug() << fullname_text << file_text << line_text; - // Read the file if it hasn't been read before or if we are reading a different file. if (fullname_text != fullname()) { open(fullname_text, QFileInfo(file_text).fileName()); @@ -1774,13 +1733,18 @@ void SeerEditorWidgetSourceArea::handleText (const QString& text) { if (id_text.toInt() == _selectedExpressionId) { _selectedExpressionValue = Seer::filterEscapes(Seer::parseFirst(text, "value=", '"', '"', false)); + } - //qDebug() << _selectedExpressionValue; + return; - // Refresh the tooltip event. - QHelpEvent* event = new QHelpEvent(QEvent::ToolTip, _selectedExpressionPosition, this->mapToGlobal(_selectedExpressionPosition)); + }else if (text.contains(QRegularExpression("^([0-9]+)\\^done,BreakpointTable="))) { - QCoreApplication::postEvent(this, event); + // 11^done,BreakpointTable={...} + + QString id_text = text.section('^', 0,0); + + if (id_text.toInt() == _selectedBreakpointId && _selectedBreakpointPosition != QPoint()) { + handleBreakpointToolTip(_selectedBreakpointPosition, text); } return; @@ -1796,22 +1760,22 @@ void SeerEditorWidgetSourceArea::handleText (const QString& text) { _selectedExpressionValue = Seer::filterEscapes(Seer::parseFirst(text, "msg=", '"', '"', false)); - //qDebug() << _selectedExpressionValue; - // Refresh the tooltip event. QHelpEvent* event = new QHelpEvent(QEvent::ToolTip, _selectedExpressionPosition, this->mapToGlobal(_selectedExpressionPosition)); QCoreApplication::postEvent(this, event); } + if (id_text.toInt() == _selectedBreakpointId && _selectedBreakpointPosition != QPoint()) { + qDebug() << "XXX - Error displaying breakpoint info as a ToolTip"; + } + return; }else{ // Ignore others. return; } - - qDebug() << text; } void SeerEditorWidgetSourceArea::handleHighlighterSettingsChanged () { @@ -1850,6 +1814,60 @@ void SeerEditorWidgetSourceArea::handleWatchFileModified (const QString& path) { emit showReloadBar(true); } +void SeerEditorWidgetSourceArea::handleBreakpointToolTip (QPoint pos, const QString& text) { + + // 11^7^done,BreakpointTable={...} + // 7^done,BreakpointTable={ + // nr_rows="1", + // nr_cols="6", + // hdr=[], + // body=[ + // bkpt={ + // number="2", + // type="breakpoint", + // disp="keep", + // enabled="y", + // addr="0x0000000000400ccd", + // func="main(int, char**)", + // file="helloworld.cpp", + // fullname="/nas/erniep/Development/seer/tests/helloworld/helloworld.cpp", + // line="30", + // thread-groups=["i1"], + // times="1", + // original-location="-source /nas/erniep/Development/seer/tests/helloworld/helloworld.cpp -line 30" + // } + // ] + // } + + QString newtext = Seer::filterEscapes(text); // Filter escaped characters. + QString tooltiptext; + + // + // Parse 'body' text. + // + QString body_text = Seer::parseFirst(newtext, "body=", '[', ']', false); + + if (body_text != "") { + + QStringList bkpt_list = Seer::parse(body_text, "bkpt=", '{', '}', false); + + // Construct the tooltip. + tooltiptext += "Breakpoint information\n\n"; + for (const auto& bkpt_text : bkpt_list) { + + QStringList item_list = Seer::parseCommaList(bkpt_text); + + for (const auto& item_text : item_list) { + tooltiptext += item_text + "\n"; + } + + break; // Take the first breakpoint in case, somehow, more are returned. + } + } + + QToolTip::showText(mapToGlobal(pos), tooltiptext); +} + // // LineNumber area. // @@ -1941,7 +1959,8 @@ void SeerEditorWidgetSourceBreakPointArea::mousePressEvent (QMouseEvent* event) if (event->button() == Qt::RightButton) { _editorWidget->showContextMenu(event); - + }else if (event->button() == Qt::LeftButton) { + _editorWidget->showBreakpointToolTip(event); }else{ QWidget::mousePressEvent(event); } diff --git a/src/SeerGdbWidget.cpp b/src/SeerGdbWidget.cpp index ccf484d3..8b3f625b 100644 --- a/src/SeerGdbWidget.cpp +++ b/src/SeerGdbWidget.cpp @@ -191,6 +191,7 @@ SeerGdbWidget::SeerGdbWidget (QWidget* parent) : QWidget(parent) { QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::deleteBreakpoints, this, &SeerGdbWidget::handleGdbBreakpointDelete); QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::enableBreakpoints, this, &SeerGdbWidget::handleGdbBreakpointEnable); QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::disableBreakpoints, this, &SeerGdbWidget::handleGdbBreakpointDisable); + QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::infoBreakpoint, this, &SeerGdbWidget::handleGdbBreakpointInfo); QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::runToLine, this, &SeerGdbWidget::handleGdbRunToLine); QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::runToAddress, this, &SeerGdbWidget::handleGdbRunToAddress); QObject::connect(editorManagerWidget, &SeerEditorManagerWidget::addVariableLoggerExpression, variableManagerWidget->variableLoggerBrowserWidget(), &SeerVariableLoggerBrowserWidget::addVariableExpression); @@ -1975,6 +1976,17 @@ void SeerGdbWidget::handleGdbBreakpointDisable (QString breakpoints) { handleGdbGenericpointList(); } +void SeerGdbWidget::handleGdbBreakpointInfo (int breakpointid, QString breakpoint) { + + if (executableLaunchMode() == "") { + return; + } + + QString str = QString("%1-break-info %2").arg(breakpointid).arg(breakpoint); + + handleGdbCommand(str); +} + void SeerGdbWidget::handleGdbBreakpointInsert (QString breakpoint) { if (executableLaunchMode() == "") { diff --git a/src/SeerGdbWidget.h b/src/SeerGdbWidget.h index 3bfe8a2b..8bc54896 100644 --- a/src/SeerGdbWidget.h +++ b/src/SeerGdbWidget.h @@ -275,6 +275,7 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm { void handleGdbBreakpointDelete (QString breakpoints); void handleGdbBreakpointEnable (QString breakpoints); void handleGdbBreakpointDisable (QString breakpoints); + void handleGdbBreakpointInfo (int breakpointid, QString breakpoint); void handleGdbBreakpointInsert (QString breakpoint); void handleGdbBreakpointCondition (QString breakpoint, QString condition); void handleGdbBreakpointIgnore (QString breakpoint, QString count); diff --git a/src/SeerMainWindow.cpp b/src/SeerMainWindow.cpp index 40f5532c..181df459 100644 --- a/src/SeerMainWindow.cpp +++ b/src/SeerMainWindow.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/src/build/README.cmake b/src/build/README.cmake index 809ca5e9..d1bebd46 100644 --- a/src/build/README.cmake +++ b/src/build/README.cmake @@ -24,6 +24,11 @@ MacOS may need help finding the cmake config file for Qt6. % cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt6/ -DCMAKE_BUILD_TYPE=Release .. +Sometimes you need to specify a newer version of g++/gcc. Your installation +may have an old version as the default. + + % cmake -D CMAKE_C_COMPILER=gcc-13 -D CMAKE_CXX_COMPILER=g++-13 -DQTVERSION=QT6 -DCMAKE_BUILD_TYPE=Debug .. + Checkout the Seer wiki for more build info. https://github.com/epasveer/seer/wiki/Building-Seer---Qt5