From 75d3d79fca483a5d9fedfe10b0eb53a43523156f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 28 Apr 2025 18:25:40 -0400 Subject: [PATCH] open available error URLs with double click or from context menu --- doc/src/Howto_lammps_gui.rst | 5 ++- tools/lammps-gui/TODO.md | 1 - tools/lammps-gui/flagwarnings.cpp | 3 +- tools/lammps-gui/lammps-gui.appdata.xml | 2 + tools/lammps-gui/logwindow.cpp | 56 +++++++++++++++++++++++++ tools/lammps-gui/logwindow.h | 4 ++ 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/doc/src/Howto_lammps_gui.rst b/doc/src/Howto_lammps_gui.rst index 592e67abc5..f6cfdefc81 100644 --- a/doc/src/Howto_lammps_gui.rst +++ b/doc/src/Howto_lammps_gui.rst @@ -308,7 +308,10 @@ of the *Output* window showing how many warnings and errors were detected and how many lines the entire output has. By clicking on the button on the right with the warning symbol or by using the keyboard shortcut `Ctrl-N` (`Command-N` on macOS), you can jump to the next -line with a warning or error. +line with a warning or error. If there is a URL pointing to additional +explanations in the online manual, that URL will be highlighted and +double-clicking on it shall open the corresponding manual page in +the web browser. The option is also available from the context menu. By default, the *Output* window is replaced each time a run is started. The runs are counted and the run number for the current run is displayed diff --git a/tools/lammps-gui/TODO.md b/tools/lammps-gui/TODO.md index ff5a88740e..1871c1b0aa 100644 --- a/tools/lammps-gui/TODO.md +++ b/tools/lammps-gui/TODO.md @@ -2,7 +2,6 @@ LAMMPS-GUI TODO list: # Short term goals (v1.x) -- open highlighted errorURL in web browser when clicking on it in the logfile viewer. - add a "Colors" menu to the image viewer to adjust color settings for the current image (unlike the defaults in the perferences) including assigning colors to individual atom types. diff --git a/tools/lammps-gui/flagwarnings.cpp b/tools/lammps-gui/flagwarnings.cpp index dce286eb3f..deeb9f8306 100644 --- a/tools/lammps-gui/flagwarnings.cpp +++ b/tools/lammps-gui/flagwarnings.cpp @@ -23,7 +23,8 @@ // workaround for Qt-5.12 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) namespace QColorConstants { -const QColor Red = QColor::fromRgb(0xff, 0x00, 0x00); +const QColor Red = QColor::fromRgb(0xff, 0x00, 0x00); +const QColor Blue = QColor::fromRgb(0x00, 0x00, 0xff); } // namespace QColorConstants #endif diff --git a/tools/lammps-gui/lammps-gui.appdata.xml b/tools/lammps-gui/lammps-gui.appdata.xml index 460e47f509..875f0bfea2 100644 --- a/tools/lammps-gui/lammps-gui.appdata.xml +++ b/tools/lammps-gui/lammps-gui.appdata.xml @@ -63,6 +63,8 @@ Add text fields for editing plot title and axis labels for charts Add option to automatically open tutorial websites (enabled by default) Add preferences tab for charts to set default for title, plot colors, smooth/raw plot, smooth params + Highlight error URLs with pointers to additional explanations in log window + Double-click on highlighted URL opens it in web browser. Also available via context menu. diff --git a/tools/lammps-gui/logwindow.cpp b/tools/lammps-gui/logwindow.cpp index 82689924dc..49b168b616 100644 --- a/tools/lammps-gui/logwindow.cpp +++ b/tools/lammps-gui/logwindow.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -37,6 +38,7 @@ const QString LogWindow::yaml_regex = QStringLiteral("^(keywords:.*$|data:$|---$|\\.\\.\\.$| - \\[.*\\]$)"); +const QString LogWindow::url_regex = QStringLiteral("^.*(https://docs.lammps.org/err[0-9]+).*$"); LogWindow::LogWindow(const QString &_filename, QWidget *parent) : QPlainTextEdit(parent), filename(_filename), warnings(nullptr) @@ -198,8 +200,53 @@ void LogWindow::extract_yaml() file.close(); } +void LogWindow::open_errorurl() +{ + if (!errorurl.isEmpty()) QDesktopServices::openUrl(QUrl(errorurl)); +} + +void LogWindow::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + // select the entire word (non-space text) under the cursor + // we need to do it in this complicated way, since QTextCursor does not recognize + // special characters as part of a word. + auto cursor = textCursor(); + auto line = cursor.block().text(); + int begin = qMin(cursor.positionInBlock(), line.length() - 1); + + while (begin >= 0) { + if (line[begin].isSpace()) break; + --begin; + } + + int end = begin + 1; + while (end < line.length()) { + if (line[end].isSpace()) break; + ++end; + } + cursor.setPosition(cursor.position() - cursor.positionInBlock() + begin + 1); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, end - begin - 1); + + auto text = cursor.selectedText(); + auto url = QRegularExpression(url_regex).match(text); + if (url.hasMatch()) { + errorurl = url.captured(1); + if (!errorurl.isEmpty()) { + QDesktopServices::openUrl(QUrl(errorurl)); + return; + } + } + } + // forward event to parent class for all unhandled cases + QPlainTextEdit::mouseDoubleClickEvent(event); +} + void LogWindow::contextMenuEvent(QContextMenuEvent *event) { + // reposition the cursor here, but only if there is no active selection + if (!textCursor().hasSelection()) setTextCursor(cursorForPosition(event->pos())); + // show augmented context menu auto *menu = createStandardContextMenu(); menu->addSeparator(); @@ -214,6 +261,15 @@ void LogWindow::contextMenuEvent(QContextMenuEvent *event) action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Y)); connect(action, &QAction::triggered, this, &LogWindow::extract_yaml); } + + // process line of text where the cursor is + auto text = textCursor().block().text().replace('\t', ' ').trimmed(); + auto url = QRegularExpression(url_regex).match(text); + if (url.hasMatch()) { + errorurl = url.captured(1); + action = menu->addAction("Open &URL in Web Browser", this, &LogWindow::open_errorurl); + action->setIcon(QIcon(":/icons/help-browser.png")); + } action = menu->addAction("&Jump to next warning or error", this, &LogWindow::next_warning); action->setIcon(QIcon(":/icons/warning.png")); action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N)); diff --git a/tools/lammps-gui/logwindow.h b/tools/lammps-gui/logwindow.h index 38bca9ba24..a3263bb2d2 100644 --- a/tools/lammps-gui/logwindow.h +++ b/tools/lammps-gui/logwindow.h @@ -32,16 +32,20 @@ private slots: void save_as(); void stop_run(); void next_warning(); + void open_errorurl(); protected: void closeEvent(QCloseEvent *event) override; + void mouseDoubleClickEvent(QMouseEvent *event) override; void contextMenuEvent(QContextMenuEvent *event) override; bool eventFilter(QObject *watched, QEvent *event) override; bool check_yaml(); private: QString filename; + QString errorurl; static const QString yaml_regex; + static const QString url_regex; FlagWarnings *warnings; QLabel *summary; };