Viewer: read the data-analysis algorithm documentation from Help
Build Packages / build:viewer-tgz:cpu (push) Successful in 6m52s
Build Packages / build:viewer-tgz:cuda (push) Successful in 7m23s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 10m33s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 10m40s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 10m41s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 10m17s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 10m25s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 11m26s
Build Packages / build:rpm (rocky8) (push) Successful in 11m12s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 11m40s
Build Packages / build:rpm (rocky9) (push) Successful in 12m46s
Build Packages / Generate python client (push) Successful in 17s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 12m10s
Build Packages / Create release (push) Skipped
Build Packages / Build documentation (push) Successful in 1m9s
Build Packages / XDS test (durin plugin) (push) Successful in 8m27s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m45s
Build Packages / DIALS test (push) Successful in 14m16s
Build Packages / XDS test (neggia plugin) (push) Successful in 7m30s
Build Packages / Unit tests (push) Successful in 1h32m14s
Build Packages / build:windows:nocuda (push) Canceled after 0s
Build Packages / build:windows:cuda (push) Canceled after 0s

Adds Help > Data Analysis Algorithms, showing docs/CPU_DATA_ANALYSIS.md in a
window. The document is baked into the binary through the Qt resource system
(aliased to :/cpu_data_analysis.md), so it needs no docs/ directory at runtime
and cannot drift from the build it shipped with. Same shape as the existing
third-party licences window, created once and raised thereafter.

Limitation worth knowing: QTextBrowser::setMarkdown renders the headings, lists,
emphasis and inline code well, but it has no math support, so the inline LaTeX in
the more quantitative sections appears as raw "$...$" source. The descriptive
material - which is most of the 744 lines - reads fine. Fixing that properly
means either pre-rendering the document to HTML with a math filter at build time,
or sending the user to the Read The Docs copy instead; neither seemed worth doing
without knowing which you would prefer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-26 22:05:11 +02:00
co-authored by Claude Opus 5
parent 52066f61d9
commit 681e80e46d
6 changed files with 59 additions and 0 deletions
+2
View File
@@ -87,6 +87,8 @@ ADD_EXECUTABLE(jfjoch_viewer jfjoch_viewer.cpp JFJochViewerWindow.cpp JFJochView
windows/JFJochHelperWindow.h windows/JFJochHelperWindow.h
windows/JFJochLicenseWindow.cpp windows/JFJochLicenseWindow.cpp
windows/JFJochLicenseWindow.h windows/JFJochLicenseWindow.h
windows/JFJochAlgorithmDocWindow.cpp
windows/JFJochAlgorithmDocWindow.h
image_viewer/JFJochImage.cpp image_viewer/JFJochImage.cpp
image_viewer/JFJochImage.h image_viewer/JFJochImage.h
image_viewer/JFJochFollowerImage.cpp image_viewer/JFJochFollowerImage.cpp
+13
View File
@@ -17,6 +17,7 @@
#include <QDockWidget> #include <QDockWidget>
#include "JFJochViewerWindow.h" #include "JFJochViewerWindow.h"
#include "windows/JFJochAlgorithmDocWindow.h"
#include "windows/JFJochLicenseWindow.h" #include "windows/JFJochLicenseWindow.h"
#include "../common/GitInfo.h" #include "../common/GitInfo.h"
#include "../common/CUDAWrapper.h" #include "../common/CUDAWrapper.h"
@@ -81,6 +82,9 @@ JFJochViewerMenu::JFJochViewerMenu(QWidget *parent) : QMenuBar(parent) {
const QAction *aboutAction = helpMenu->addAction("About"); const QAction *aboutAction = helpMenu->addAction("About");
connect(aboutAction, &QAction::triggered, this, &JFJochViewerMenu::aboutSelected); connect(aboutAction, &QAction::triggered, this, &JFJochViewerMenu::aboutSelected);
const QAction *algorithmDocAction = helpMenu->addAction("Data Analysis Algorithms");
connect(algorithmDocAction, &QAction::triggered, this, &JFJochViewerMenu::algorithmDocSelected);
const QAction *licensesAction = helpMenu->addAction("Third-party Licenses"); const QAction *licensesAction = helpMenu->addAction("Third-party Licenses");
connect(licensesAction, &QAction::triggered, this, &JFJochViewerMenu::licensesSelected); connect(licensesAction, &QAction::triggered, this, &JFJochViewerMenu::licensesSelected);
} }
@@ -148,6 +152,15 @@ void JFJochViewerMenu::licensesSelected() {
licenseWindow->activateWindow(); licenseWindow->activateWindow();
} }
void JFJochViewerMenu::algorithmDocSelected() {
// Same pattern as the licence window: created once, then raised.
if (algorithmDocWindow == nullptr)
algorithmDocWindow = new JFJochAlgorithmDocWindow(window());
algorithmDocWindow->show();
algorithmDocWindow->raise();
algorithmDocWindow->activateWindow();
}
void JFJochViewerMenu::openSelected() { void JFJochViewerMenu::openSelected() {
QString fileName = QFileDialog::getOpenFileName( QString fileName = QFileDialog::getOpenFileName(
this, this,
+3
View File
@@ -7,6 +7,7 @@
#include "windows/JFJochHelperWindow.h" #include "windows/JFJochHelperWindow.h"
class JFJochAlgorithmDocWindow;
class JFJochLicenseWindow; class JFJochLicenseWindow;
class QDockWidget; class QDockWidget;
@@ -21,6 +22,7 @@ class JFJochViewerMenu : public QMenuBar {
QMenu *windowMenu = nullptr; QMenu *windowMenu = nullptr;
JFJochLicenseWindow *licenseWindow = nullptr; JFJochLicenseWindow *licenseWindow = nullptr;
JFJochAlgorithmDocWindow *algorithmDocWindow = nullptr;
public: public:
explicit JFJochViewerMenu(QWidget *parent = nullptr); explicit JFJochViewerMenu(QWidget *parent = nullptr);
~JFJochViewerMenu() override = default; ~JFJochViewerMenu() override = default;
@@ -50,6 +52,7 @@ signals:
private slots: private slots:
void aboutSelected(); void aboutSelected();
void licensesSelected(); void licensesSelected();
void algorithmDocSelected();
void quitSelected(); void quitSelected();
void closeSelected(); void closeSelected();
+3
View File
@@ -7,6 +7,9 @@
<qresource prefix="/"> <qresource prefix="/">
<file>jfjoch.png</file> <file>jfjoch.png</file>
<file>third_party_licenses.html</file> <file>third_party_licenses.html</file>
<!-- The algorithm documentation is shown in-app (Help > Data Analysis Algorithms);
aliased so the viewer does not depend on the docs/ directory at runtime. -->
<file alias="cpu_data_analysis.md">../../docs/CPU_DATA_ANALYSIS.md</file>
<file>psi_01.png</file> <file>psi_01.png</file>
<file>psi_02.png</file> <file>psi_02.png</file>
<file>psi_03.png</file> <file>psi_03.png</file>
@@ -0,0 +1,23 @@
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "JFJochAlgorithmDocWindow.h"
#include <QFile>
#include <QTextBrowser>
#include <QVBoxLayout>
JFJochAlgorithmDocWindow::JFJochAlgorithmDocWindow(QWidget *parent) : QDialog(parent) {
setWindowTitle("Data Analysis Algorithms");
resize(900, 700);
auto *browser = new QTextBrowser(this);
browser->setOpenExternalLinks(true);
QFile file(":/cpu_data_analysis.md");
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
browser->setMarkdown(QString::fromUtf8(file.readAll()));
auto *layout = new QVBoxLayout(this);
layout->addWidget(browser);
}
+15
View File
@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <QDialog>
// Modeless window showing the data-analysis algorithm documentation, rendered from the copy of
// docs/CPU_DATA_ANALYSIS.md baked into the binary (:/cpu_data_analysis.md), so it is available
// wherever the viewer runs and always matches the build.
class JFJochAlgorithmDocWindow : public QDialog {
Q_OBJECT
public:
explicit JFJochAlgorithmDocWindow(QWidget *parent = nullptr);
};