Merge branch '158-the-source-code-view-should-reload-when-the-underlying-file-changes-or-at-least-offer-to-do-so'

This commit is contained in:
Ernie Pasveer
2023-10-02 20:00:33 -05:00
8 changed files with 201 additions and 29 deletions
+1
View File
@@ -7,6 +7,7 @@
* Add --gdb-program and --gdb-arguments to command line to override settings from Seer's config.
* Fixed a rare bug with blank lines from gdb causing a segv in GdbMonitor.
* Fixed bug specifying path to "rr" debugger.
* Add option to reload source file if it changes.
## [2.2] - 2023-09-07
* Fixed infinite loop when starting with RR mode.
+12
View File
@@ -805,6 +805,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::refreshBreakpointsStackFrames, this, &SeerEditorManagerWidget::handleRefreshBreakpointsStackFrames);
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::runToLine, this, &SeerEditorManagerWidget::handleRunToLine);
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addVariableLoggerExpression, this, &SeerEditorManagerWidget::handleAddVariableLoggerExpression);
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addVariableTrackerExpression, this, &SeerEditorManagerWidget::handleAddVariableTrackerExpression);
@@ -863,6 +864,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::refreshBreakpointsStackFrames, this, &SeerEditorManagerWidget::handleRefreshBreakpointsStackFrames);
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::runToLine, this, &SeerEditorManagerWidget::handleRunToLine);
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addVariableLoggerExpression, this, &SeerEditorManagerWidget::handleAddVariableLoggerExpression);
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addVariableTrackerExpression, this, &SeerEditorManagerWidget::handleAddVariableTrackerExpression);
@@ -962,6 +964,7 @@ SeerEditorWidgetAssembly* SeerEditorManagerWidget::createAssemblyWidgetTab () {
QObject::connect(assemblyWidget->assemblyArea(), &SeerEditorWidgetAssemblyArea::deleteBreakpoints, this, &SeerEditorManagerWidget::handleDeleteBreakpoints);
QObject::connect(assemblyWidget->assemblyArea(), &SeerEditorWidgetAssemblyArea::enableBreakpoints, this, &SeerEditorManagerWidget::handleEnableBreakpoints);
QObject::connect(assemblyWidget->assemblyArea(), &SeerEditorWidgetAssemblyArea::disableBreakpoints, this, &SeerEditorManagerWidget::handleDisableBreakpoints);
QObject::connect(assemblyWidget->assemblyArea(), &SeerEditorWidgetAssemblyArea::refreshBreakpointsStackFrames, this, &SeerEditorManagerWidget::handleRefreshBreakpointsStackFrames);
QObject::connect(assemblyWidget->assemblyArea(), &SeerEditorWidgetAssemblyArea::runToAddress, this, &SeerEditorManagerWidget::handleRunToAddress);
QObject::connect(assemblyWidget->assemblyArea(), &SeerEditorWidgetAssemblyArea::requestAssembly, this, &SeerEditorManagerWidget::handleRequestAssembly);
QObject::connect(assemblyWidget->assemblyArea(), &SeerEditorWidgetAssemblyArea::requestSourceAndAssembly, this, &SeerEditorManagerWidget::handleRequestSourceAndAssembly);
@@ -1142,6 +1145,15 @@ void SeerEditorManagerWidget::handleDisableBreakpoints (QString breakpoints) {
emit disableBreakpoints (breakpoints);
}
void SeerEditorManagerWidget::handleRefreshBreakpointsStackFrames () {
// Ask for the breakpoint list to be resent, in case files have breakpoints.
emit refreshBreakpointsList();
// Ask for the stackframe list to be resent, in case files have currently executing lines.
emit refreshStackFrames();
}
void SeerEditorManagerWidget::handleRunToLine (QString fullname, int lineno) {
//qDebug() << fullname << lineno;
+1
View File
@@ -73,6 +73,7 @@ class SeerEditorManagerWidget : public QWidget, protected Ui::SeerEditorManagerW
void handleDeleteBreakpoints (QString breakpoints);
void handleEnableBreakpoints (QString breakpoints);
void handleDisableBreakpoints (QString breakpoints);
void handleRefreshBreakpointsStackFrames ();
void handleRunToLine (QString fullname, int lineno);
void handleRunToAddress (QString address);
void handleAddVariableLoggerExpression (QString expression);
+1
View File
@@ -104,6 +104,7 @@ class SeerEditorWidgetAssemblyArea : public SeerPlainTextEdit {
void deleteBreakpoints (QString breakpoints);
void enableBreakpoints (QString breakpoints);
void disableBreakpoints (QString breakpoints);
void refreshBreakpointsStackFrames ();
void runToAddress (QString address);
void addMemoryVisualize (QString expression);
void addArrayVisualize (QString expression);
+36 -4
View File
@@ -28,12 +28,14 @@ SeerEditorWidgetSource::SeerEditorWidgetSource(QWidget* parent) : QWidget(parent
showSearchBar(false); // Hide the search bar. ctrl+F to show it again.
showAlternateBar(false); // Hide the alternate bar. ctrl+O to show it again.
showReloadBar(false); // Hide the reload file bar. Automatically shown if file gets updated.
setSearchMatchCase(true); // Search with case sensitivity.
_textSearchShortcut = new QShortcut(QKeySequence(tr("Ctrl+F")), this);
_textSearchNextShortcut = new QShortcut(QKeySequence(tr("Ctrl+G")), this);
_textSearchPrevShortcut = new QShortcut(QKeySequence(tr("Ctrl+Shift+G")), this);
_alternateDirShortcut = new QShortcut(QKeySequence(tr("Ctrl+O")), this);
_textSearchShortcut = new QShortcut(QKeySequence(tr("Ctrl+F")), this);
_textSearchNextShortcut = new QShortcut(QKeySequence(tr("Ctrl+G")), this);
_textSearchPrevShortcut = new QShortcut(QKeySequence(tr("Ctrl+Shift+G")), this);
_textSearchReloadShortcut = new QShortcut(QKeySequence(tr("Ctrl+R")), this);
_alternateDirShortcut = new QShortcut(QKeySequence(tr("Ctrl+O")), this);
setKeySettings(SeerKeySettings::populate());
@@ -43,16 +45,21 @@ SeerEditorWidgetSource::SeerEditorWidgetSource(QWidget* parent) : QWidget(parent
QObject::connect(searchDownToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleSearchDownToolButton);
QObject::connect(searchUpToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleSearchUpToolButton);
QObject::connect(searchLineNumberLineEdit, &QLineEdit::returnPressed, this, &SeerEditorWidgetSource::handleSearchLineNumberLineEdit);
QObject::connect(searchReloadToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleReloadToolButton);
QObject::connect(searchCloseToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleSearchCloseToolButton);
QObject::connect(alternateCloseToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleAlternateCloseToolButton);
QObject::connect(alternateFileOpenToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleAlternateFileOpenToolButton);
QObject::connect(alternateLineEdit, &QLineEdit::returnPressed, this, &SeerEditorWidgetSource::handleAlternateLineEdit);
QObject::connect(reloadToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleReloadToolButton);
QObject::connect(reloadCloseToolButton, &QToolButton::clicked, this, &SeerEditorWidgetSource::handleReloadCloseToolButton);
QObject::connect(sourceWidget, &SeerEditorWidgetSourceArea::showSearchBar, this, &SeerEditorWidgetSource::showSearchBar);
QObject::connect(sourceWidget, &SeerEditorWidgetSourceArea::showAlternateBar, this, &SeerEditorWidgetSource::showAlternateBar);
QObject::connect(sourceWidget, &SeerEditorWidgetSourceArea::showReloadBar, this, &SeerEditorWidgetSource::showReloadBar);
QObject::connect(_textSearchShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleTextSearchShortcut);
QObject::connect(_textSearchNextShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleSearchDownToolButton);
QObject::connect(_textSearchPrevShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleSearchUpToolButton);
QObject::connect(_textSearchReloadShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleReloadToolButton);
QObject::connect(_alternateDirShortcut, &QShortcut::activated, this, &SeerEditorWidgetSource::handleAlternateDirectoryShortcut);
}
@@ -131,6 +138,19 @@ void SeerEditorWidgetSource::showAlternateBar (bool flag) {
}
}
void SeerEditorWidgetSource::showReloadBar (bool flag) {
reloadBarWidget->setVisible(flag);
reloadBarWidget->setStyleSheet("QWidget { background-color : #00AA00; color : #FFFF00; }");
if (flag) {
reloadFilenameLabel->setText("The file \"" + sourceArea()->file() + "\" has changed on disk.");
reloadToolButton->setFocus(Qt::MouseFocusReason); // If 'show', give the reload button the focus.
}else{
reloadFilenameLabel->setText("");
}
}
void SeerEditorWidgetSource::handleSearchLineNumberLineEdit () {
QString str = searchLineNumberLineEdit->text();
@@ -253,3 +273,15 @@ void SeerEditorWidgetSource::handleAlternateDirectoryShortcut () {
}
}
void SeerEditorWidgetSource::handleReloadToolButton () {
showReloadBar(false);
sourceArea()->reload();
}
void SeerEditorWidgetSource::handleReloadCloseToolButton () {
showReloadBar(false);
}
+12 -2
View File
@@ -15,6 +15,8 @@
#include <QtCore/QStringList>
#include <QtCore/QVector>
#include <QtCore/QMap>
#include <QtCore/QFileSystemWatcher>
class SeerEditorWidgetSourceLineNumberArea;
class SeerEditorWidgetSourceBreakPointArea;
@@ -48,9 +50,10 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit {
bool isOpen () const;
void open (const QString& fullname, const QString& file, const QString& alternateDirectory="");
void openText (const QString& text, const QString& file);
void close ();
void reload ();
const QString& fullname () const;
const QString& file () const;
void close ();
void setAlternateDirectory (const QString& alternateDirectory);
const QString& alternateDirectory () const;
void setAlternateDirectories (const QStringList& alternateDirectories);
@@ -99,6 +102,7 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit {
void deleteBreakpoints (QString breakpoints);
void enableBreakpoints (QString breakpoints);
void disableBreakpoints (QString breakpoints);
void refreshBreakpointsStackFrames ();
void runToLine (QString fullname, int lineno);
void addVariableLoggerExpression (QString expression);
void addVariableTrackerExpression (QString expression);
@@ -109,12 +113,13 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit {
void addStructVisualize (QString expression);
void showSearchBar (bool flag);
void showAlternateBar (bool flag);
void showReloadBar (bool flag);
void highlighterSettingsChanged ();
public slots:
void handleText (const QString& text);
void handleHighlighterSettingsChanged ();
void handleWatchFileModified (const QString& path);
protected:
void resizeEvent (QResizeEvent* event);
@@ -135,6 +140,7 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit {
QString _file;
QString _alternateDirectory;
QStringList _alternateDirectories;
QFileSystemWatcher* _fileWatcher;
bool _enableLineNumberArea;
bool _enableBreakPointArea;
@@ -244,6 +250,7 @@ class SeerEditorWidgetSource : public QWidget, protected Ui::SeerEditorWidgetSou
void showSearchBar (bool flag);
void setSearchMatchCase (bool flag);
void showAlternateBar (bool flag);
void showReloadBar (bool flag);
private slots:
void handleSearchLineNumberLineEdit ();
@@ -256,6 +263,8 @@ class SeerEditorWidgetSource : public QWidget, protected Ui::SeerEditorWidgetSou
void handleAlternateLineEdit ();
void handleTextSearchShortcut ();
void handleAlternateDirectoryShortcut ();
void handleReloadToolButton ();
void handleReloadCloseToolButton ();
signals:
void addAlternateDirectory (QString path);
@@ -265,6 +274,7 @@ class SeerEditorWidgetSource : public QWidget, protected Ui::SeerEditorWidgetSou
QShortcut* _textSearchShortcut;
QShortcut* _textSearchNextShortcut;
QShortcut* _textSearchPrevShortcut;
QShortcut* _textSearchReloadShortcut;
QShortcut* _alternateDirShortcut;
};
+71 -16
View File
@@ -13,20 +13,8 @@
<property name="windowTitle">
<string>SeerEditorWidgetSourceForm</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QWidget" name="alternateBarWidget" native="true">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
@@ -119,7 +107,53 @@
</layout>
</widget>
</item>
<item>
<item row="1" column="0">
<widget class="QWidget" name="reloadBarWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="reloadFilenameLabel">
</widget>
</item>
<item>
<widget class="QToolButton" name="reloadToolButton">
<property name="toolTip">
<string>Reload source file.</string>
</property>
<property name="text">
<string>Reload</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="reloadCloseToolButton">
<property name="toolTip">
<string>Close the reload bar.</string>
</property>
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="resource.qrc">
<normaloff>:/seer/resources/RelaxLightIcons/list-remove.svg</normaloff>:/seer/resources/RelaxLightIcons/list-remove.svg</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="SeerEditorWidgetSourceArea" name="sourceWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@@ -129,7 +163,7 @@
</property>
</widget>
</item>
<item>
<item row="3" column="0">
<widget class="QWidget" name="searchBarWidget" native="true">
<layout class="QHBoxLayout" name="searchBarLayout">
<property name="leftMargin">
@@ -228,6 +262,27 @@
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="searchReloadToolButton">
<property name="toolTip">
<string>Reload source file.</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resource.qrc">
<normaloff>:/seer/resources/RelaxLightIcons/view-refresh.svg</normaloff>:/seer/resources/RelaxLightIcons/view-refresh.svg</iconset>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
+67 -7
View File
@@ -28,6 +28,7 @@
SeerEditorWidgetSourceArea::SeerEditorWidgetSourceArea(QWidget* parent) : SeerPlainTextEdit(parent) {
_fileWatcher = 0;
_enableLineNumberArea = false;
_enableBreakPointArea = false;
_enableMiniMapArea = false;
@@ -543,6 +544,11 @@ bool SeerEditorWidgetSourceArea::isOpen () const {
void SeerEditorWidgetSourceArea::open (const QString& fullname, const QString& file, const QString& alternateDirectory) {
// Delete old file watcher, if any.
if (_fileWatcher) {
delete _fileWatcher; _fileWatcher = 0;
}
// Close the previous file, if any.
if (isOpen()) {
close();
@@ -616,6 +622,12 @@ void SeerEditorWidgetSourceArea::open (const QString& fullname, const QString& f
// Put the contents in the editor.
openText(text, _fullname);
// Watch the file.
_fileWatcher = new QFileSystemWatcher(this);
_fileWatcher->addPath(filename);
QObject::connect(_fileWatcher, &QFileSystemWatcher::fileChanged, this, &SeerEditorWidgetSourceArea::handleWatchFileModified);
}
void SeerEditorWidgetSourceArea::openText (const QString& text, const QString& file) {
@@ -648,6 +660,54 @@ void SeerEditorWidgetSourceArea::openText (const QString& text, const QString& f
}
}
void SeerEditorWidgetSourceArea::reload () {
// Open the same file again.
QString fullname = _fullname;
QString file = _file;
QString alternateDirectory = _alternateDirectory;
if (fullname == "") return;
if (file == "") return;
// Save old cursor and scroll position.
int blockno = textCursor().blockNumber();
int posinblock = textCursor().positionInBlock();
int vscrollpos = verticalScrollBar()->value();
// Reload file.
open(fullname, file, alternateDirectory);
// Restore to old cursor and scroll position.
QTextCursor c = textCursor();
c.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor, 1);
c.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, blockno);
c.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, posinblock);
setTextCursor(c);
ensureCursorVisible();
verticalScrollBar()->setValue(vscrollpos);
// Refresh any breakpoints or current lines in the stackframes.
emit refreshBreakpointsStackFrames();
}
void SeerEditorWidgetSourceArea::close () {
setDocumentTitle("");
setPlainText("");
clearExpression();
// Delete old file watcher, if any.
if (_fileWatcher) {
delete _fileWatcher; _fileWatcher = 0;
}
}
const QString& SeerEditorWidgetSourceArea::fullname () const {
return _fullname;
}
@@ -656,13 +716,6 @@ const QString& SeerEditorWidgetSourceArea::file () const {
return _file;
}
void SeerEditorWidgetSourceArea::close () {
setDocumentTitle("");
setPlainText("");
clearExpression();
}
void SeerEditorWidgetSourceArea::setAlternateDirectory (const QString& alternateDirectory) {
_alternateDirectory = alternateDirectory;
@@ -1681,6 +1734,13 @@ void SeerEditorWidgetSourceArea::handleHighlighterSettingsChanged () {
// The new highlighter settings will be used.
}
void SeerEditorWidgetSourceArea::handleWatchFileModified (const QString& path) {
Q_UNUSED(path);
emit showReloadBar(true);
}
//
// LineNumber area.
//