open available error URLs with double click or from context menu

This commit is contained in:
Axel Kohlmeyer
2025-04-28 18:25:40 -04:00
parent db3d93210d
commit 75d3d79fca
6 changed files with 68 additions and 3 deletions

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.
</description>
</release>
<release version="1.6.12" timestamp="1734890080">

View File

@ -18,6 +18,7 @@
#include <QAction>
#include <QApplication>
#include <QDesktopServices>
#include <QFile>
#include <QFileDialog>
#include <QGridLayout>
@ -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));

View File

@ -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;
};