musredit 1.0.0
Loading...
Searching...
No Matches
PMsrHighlighter.cpp
Go to the documentation of this file.
1
12
13/***************************************************************************
14 * Copyright (C) 2007-2026 by Andreas Suter *
15 * andreas.suter@psi.ch *
16 * *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
21 * *
22 * This program is distributed in the hope that it will be useful, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
26 * *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program; if not, write to the *
29 * Free Software Foundation, Inc., *
30 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
31 ***************************************************************************/
32
33#include <utility>
34
35#include <QGuiApplication>
36#include <QStyleHints>
37#include <QMessageBox> //as35
38
39#include "PMsrHighlighter.h"
40
49 : QSyntaxHighlighter(parent) {
50
51 // =========================================================================
52 // TABLEAU COLOURS
53 // =========================================================================
54
55 // Individual QColor definitions grouped by color pairs (Dark / Light)
56 const QColor tabBlue("#1F77B4");
57 const QColor tabBlueLight("#AEC7E8");
58
59 const QColor tabOrange("#FF7F0E");
60 const QColor tabOrangeLight("#FFBB78");
61
62 const QColor tabGreen("#2CA02C");
63 const QColor tabGreenLight("#98DF8A");
64
65 const QColor tabRed("#D62728");
66 const QColor tabRedLight("#FF9896");
67
68 const QColor tabPurple("#9467BD");
69 const QColor tabPurpleLight("#C5B0D5");
70
71 const QColor tabBrown("#8C564B");
72 const QColor tabBrownLight("#C49C94");
73
74 const QColor tabPink("#E377C2");
75 const QColor tabPinkLight("#F7B6D2");
76
77 const QColor tabGray("#7F7F7F");
78 const QColor tabGrayLight("#C7C7C7");
79
80 const QColor tabOlive("#BCBD22");
81 const QColor tabOliveLight("#DBDB8D");
82
83 const QColor tabCyan("#17BECF");
84 const QColor tabCyanLight("#9EDAE5");
85
86 // =========================================================================
87 // KEYWORD STYLING
88 // =========================================================================
89
90 // Define the colour/styling for each keyword type.
91 Qt::ColorScheme scheme = QGuiApplication::styleHints()->colorScheme();
92
93 if (scheme == Qt::ColorScheme::Light) {
94 fBlockFormat.setForeground(tabOlive); // BLOCK keywords
95 fTheoryFormat.setForeground(tabGreen); // THEORY keywords
96 fFunctionsFormat.setForeground(tabRed); // FUNCTION keywords
97 fParFormat.setForeground(tabPink); // parX keywords
98 fMapFormat.setForeground(tabOrange); // mapX keywords
99 fFunFormat.setForeground(tabPurple); // funX keywords
100 fRunFormat.setForeground(tabGreen); // RUN/GLOBAL keywords
101 fCommandsFormat.setForeground(tabGreen); // COMMANDS keywords
102 fFourierFormat.setForeground(tabGreen); // FOURIER keywords
103 fPlotFormat.setForeground(tabGreen); // PLOT keywords
104 fOptionsFormat.setForeground(tabRed); // keywords input options
105 fInfoFormat.setForeground(tabGray); // auto-printed information
106 fBoolFormat.setForeground(tabRed); // boolean strings
107 fNullFormat.setForeground(tabRed); // null strings
108 fDateFormat.setForeground(tabPink); // date & time strings
109 fNumberFormat.setForeground(tabBlue); // integer & float strings
110 fCommentFormat.setForeground(tabGray); // comments
111 fCommentFormat.setFontItalic(true);
112 fTitleFormat.setForeground(Qt::black); // title
113 } else if (scheme == Qt::ColorScheme::Dark) {
114 fBlockFormat.setForeground(tabOlive); // BLOCK keywords
115 fTheoryFormat.setForeground(tabGreen); // THEORY keywords
116 fFunctionsFormat.setForeground(tabRed); // FUNCTION keywords
117 fParFormat.setForeground(tabPink); // parX keywords
118 fMapFormat.setForeground(tabOrange); // mapX keywords
119 fFunFormat.setForeground(tabPurple); // funX keywords
120 fRunFormat.setForeground(tabGreen); // RUN/GLOBAL keywords
121 fCommandsFormat.setForeground(tabGreen); // COMMANDS keywords
122 fFourierFormat.setForeground(tabGreen); // FOURIER keywords
123 fPlotFormat.setForeground(tabGreen); // PLOT keywords
124 fOptionsFormat.setForeground(tabRed); // keywords input options
125 fInfoFormat.setForeground(tabGray); // auto-printed information
126 fBoolFormat.setForeground(tabRed); // boolean strings
127 fNullFormat.setForeground(tabRed); // null strings
128 fDateFormat.setForeground(tabPink); // date & time strings
129 fNumberFormat.setForeground(tabBlueLight); // integer & float strings
130 fCommentFormat.setForeground(tabGray); // comments
131 fCommentFormat.setFontItalic(true);
132 fTitleFormat.setForeground(Qt::white); // title
133 } else { // set it to Light for now
134 fBlockFormat.setForeground(tabOlive); // BLOCK keywords
135 fTheoryFormat.setForeground(tabGreen); // THEORY keywords
136 fFunctionsFormat.setForeground(tabRed); // FUNCTION keywords
137 fParFormat.setForeground(tabPink); // parX keywords
138 fMapFormat.setForeground(tabOrange); // mapX keywords
139 fFunFormat.setForeground(tabPurple); // funX keywords
140 fRunFormat.setForeground(tabGreen); // RUN/GLOBAL keywords
141 fCommandsFormat.setForeground(tabGreen); // COMMANDS keywords
142 fFourierFormat.setForeground(tabGreen); // FOURIER keywords
143 fPlotFormat.setForeground(tabGreen); // PLOT keywords
144 fOptionsFormat.setForeground(tabRed); // keywords input options
145 fInfoFormat.setForeground(tabGray); // auto-printed information
146 fBoolFormat.setForeground(tabRed); // boolean strings
147 fNullFormat.setForeground(tabRed); // null strings
148 fDateFormat.setForeground(tabPink); // date & time strings
149 fNumberFormat.setForeground(tabBlue); // integer & float strings
150 fCommentFormat.setForeground(tabGray); // comments
151 fCommentFormat.setFontItalic(true);
152 fTitleFormat.setForeground(Qt::black); // title
153 }
154
155 // =========================================================================
156 // BLOCK HEADERS
157 // =========================================================================
158 QStringList block_keywords = {"FITPARAMETER", "THEORY", "FUNCTIONS",
159 "GLOBAL", "RUN", "COMMANDS",
160 "FOURIER", "PLOT", "STATISTIC"};
161 AddRule(block_keywords, fBlockFormat);
162
163 // =========================================================================
164 // THEORY KEYWORDS
165 // =========================================================================
166 QStringList theory_keywords_long = {
167 "const", "asymmetry", "simplExpo", "generExpo",
168 "simpleGss", "statGssKT", "statGssKTLF", "dynGssKTLF",
169 "statExpKT", "statExpKTLF", "dynExpKTLF", "dynGLKT_F_ZF",
170 "dynGLKT_F_LF", "dynGLKT_LF", "combiLGKT", "strKT",
171 "spinGlass", "rdAnisoHf", "TFieldCos", "internFld",
172 "Bessel", "internbsl", "internFldGK", "internFldLL",
173 "F_mu_F", "abragam", "skewedGss", "staticNKZF",
174 "staticNKTF", "dynamicNKZF", "dynamicNKTF", "muMinusExpTF",
175 "polynom", "userFcn"};
176
177 QStringList theory_keywords_short = {"c",
178 "a",
179 "se",
180 "ge",
181 "sg",
182 "stg",
183 "sgktlf",
184 "dgktlf",
185 "sekt",
186 "sektlf",
187 "dektlf",
188 "dglktfzf",
189 "dglktflf",
190 "dglktlf",
191 "lgkt",
192 "skt",
193 "spg",
194 "rahf",
195 "tf",
196 "ifld",
197 "b",
198 "ib",
199 "ifgk",
200 "ifll",
201 "fmuf",
202 "ab",
203 "skg",
204 "snkzf",
205 "snktf",
206 "dnkzf",
207 "dnktf",
208 "mmsetf",
209 "p",
210 "u"};
211
212 // combine both theory keyword lists
213 QStringList theory_keywords = theory_keywords_long + theory_keywords_short;
214
215 AddRule(theory_keywords, fTheoryFormat);
216
217 // =========================================================================
218 // FUNCTIONS KEYWORDS
219 // =========================================================================
220 QStringList functions_keywords = {
221 "gamma_mu", "pi", "B", "b", "En", "en", "T\\d+",
222 /* "+", "-", "*", "/", */
223 };
224 AddRule(functions_keywords, fFunctionsFormat);
225
226 // =========================================================================
227 // funX KEYWORDS
228 // =========================================================================
229 QStringList fun_keywords = {"fun\\d+"};
230 AddRule(fun_keywords, fFunFormat);
231
232 // =========================================================================
233 // parX KEYWORDS
234 // =========================================================================
235 QStringList par_keywords = {"par\\d+"};
236 AddRule(par_keywords, fParFormat);
237
238 // =========================================================================
239 // mapX KEYWORDS
240 // =========================================================================
241 QStringList map_keywords = {"map\\d+"};
242 AddRule(map_keywords, fMapFormat);
243
244 // =========================================================================
245 // RUN KEYWORDS
246 // =========================================================================
247 QStringList run_keywords = {
248 "fittype", "data", "t0", "addt0",
249 "deadtime-cor", "fit", "packing", "rrf_freq",
250 "rrf_packing", "rrf_phase", "alpha", "beta",
251 "norm", "backgr.fit", "lifetime", "lifetimecorrection",
252 "map", "forward", "backward", "backgr.fix",
253 "background", "xy-data"};
254 AddRule(run_keywords, fRunFormat);
255
256 // =========================================================================
257 // FOURIER KEYWORDS
258 // =========================================================================
259 QStringList fourier_keywords = {"units",
260 "fourier_power",
261 "dc-corrected",
262 "apodization",
263 "plot",
264 "phase",
265 "range_for_phase_correction",
266 "range"};
267 AddRule(fourier_keywords, fFourierFormat);
268
269 // =========================================================================
270 // PLOT KEYWORDS
271 // =========================================================================
272 QStringList plot_keywords = {"lifetimecorrection",
273 "runs",
274 "range",
275 "sub_ranges",
276 "use_fit_ranges",
277 "view_packing",
278 "logx",
279 "logy",
280 "rrf_packing value",
281 "rrf_freq value unit",
282 "rrf_phase value"};
283 AddRule(plot_keywords, fPlotFormat);
284
285 // =========================================================================
286 // UNITS OPTIONS
287 // =========================================================================
288 QStringList units_options = {"Gauss", "Tesla", "MHz", "Mc/s"};
289
290 // =========================================================================
291 // APODIZATION OPTIONS
292 // =========================================================================
293 QStringList apodization_options = {"NONE", "WEAK", "MEDIUM", "STRONG"};
294
295 // =========================================================================
296 // RRF OPTIONS
297 // =========================================================================
298 QStringList rrf_options = {"MHz", "Mc", "T"};
299
300 // =========================================================================
301 // FOURIER OPTIONS
302 // =========================================================================
303 QStringList fourier_options = {"REAL", "IMAG", "REAL_AND_IMAG",
304 "POWER", "PHASE", "PHASE_OPT_REAL"};
305
306 // =========================================================================
307 // COMMANDS OPTIONS
308 // =========================================================================
309 QStringList commands_options = {"RESET"};
310
311 // =========================================================================
312 // ALL OPTIONS
313 // =========================================================================
314 QStringList all_options = units_options + apodization_options + rrf_options +
315 fourier_options + commands_options;
316
317 AddRule(all_options, fOptionsFormat);
318
319 // =========================================================================
320 // FIT INFO
321 // =========================================================================
322 QStringList fit_info = {
323 "(single histogram fit)", "(single histogram RRF fit)",
324 "(asymmetry fit)", "(asymmetry RRF fit)",
325 "(mu minus fit)", "(beta-NMR fit)",
326 "(non muSR fit)"};
327
328 // =========================================================================
329 // PLOT INFO
330 // =========================================================================
331 QStringList plot_info = {"(single histo plot)", "(single histo RRF plot)",
332 "(asymmetry plot)", "(asymmetry RRF plot)",
333 "(mu minus plot)", "(beta-NMR asymmetry plot)",
334 "(non muSR plot)"};
335
336 // =========================================================================
337 // RUN INFO
338 // =========================================================================
339 QStringList run_info = {"(name beamline institute data-file-format)"};
340
341 // =========================================================================
342 // THEORY INFO
343 // =========================================================================
344 QStringList theory_info = {"(N0 tau A lambda phase nu tshift)",
345 "(N0 tau A lambda phase nu)",
346 "(damping hopping-rate tshift)",
347 "(damping hopping-rate)",
348 "(damping_D0 R_b nu_c tshift)",
349 "(damping_D0 R_b nu_c)",
350 "(damping_D0 R_b tshift)",
351 "(damping_D0 R_b)",
352 "(fraction frequency sigma lambda beta tshift)",
353 "(fraction frequency sigma lambda beta)",
354 "(fraction phase frequency Trate Lrate tshift)",
355 "(fraction phase frequency Trate Lrate)",
356 "(frequency damping hopping-rate tshift)",
357 "(frequency damping hopping-rate)",
358 "(frequency damping tshift)",
359 "(frequency damping)",
360 "(frequency rate tshift)",
361 "(frequency rate)",
362 "(frequency tshift)",
363 "(frequency)",
364 "(lorentzRate gaussRate tshift)",
365 "(lorentzRate gaussRate)",
366 "(phase frequency damping_D0 R_b nu_c tshift)",
367 "(phase frequency damping_D0 R_b nu_c)",
368 "(phase frequency damping_D0 R_b tshift)",
369 "(phase frequency damping_D0 R_b)",
370 "(phase frequency rate_m rate_p tshift)",
371 "(phase frequency rate_m rate_p)",
372 "(phase frequency tshift)",
373 "(phase frequency)",
374 "(rate beta tshift)",
375 "(rate beta)",
376 "(rate exponent tshift)",
377 "(rate exponent)",
378 "(rate hopprate order tshift)",
379 "(rate hopprate order)",
380 "(rate hopprate tshift)",
381 "(rate hopprate)",
382 "(rate tshift)",
383 "(rate)",
384 "(tshift p0 p1 ... pn)"};
385
386 // =========================================================================
387 // ALL INFO
388 // =========================================================================
389 QStringList all_info = fit_info + run_info + plot_info + theory_info;
390
391 AddRule(all_info, fInfoFormat);
392
393 // =========================================================================
394 // COMMANDS BLOCK KEYWORDS
395 // =========================================================================
396 QStringList commands_keywords = {
397 "STRATEGY", "MIGRAD", "SIMPLEX", "MINIMIZE",
398 "MINOS", "HESSE", "SAVE", "SET BATCH",
399 "END RETURN", "MAX_LIKELIHOOD", "PRINT_LEVEL", "SCAN",
400 "CONTOURS", "MNPLOT", "FIX", "RELEASE",
401 "FIT_RANGE", "SCALE_N0_BKG", "SECTOR", "OpenMP",
402 "CUDA", "OpenCL-CPU", "OpenCL-GPU"};
403
404 AddRule(commands_keywords, fCommandsFormat);
405
406 // =========================================================================
407 // BOOLEANS
408 // =========================================================================
409 QStringList bool_keywords = {"true", "false"};
410 AddRule(bool_keywords, fBoolFormat);
411
412 // =========================================================================
413 // NULLS
414 // =========================================================================
415 QStringList null_keywords = {"none"};
416 AddRule(null_keywords, fNullFormat);
417
418 // =========================================================================
419 // NUMBERS
420 // =========================================================================
421 // Distinguish integer/decimal numbers from raw text.
422 PHighlightingRule number_rule;
423 QRegularExpression number_regex("\\b-?\\d*\\.?\\d+\\b");
424 number_rule.fPattern = number_regex;
425 number_rule.fFormat = fNumberFormat;
426 fHighlightingRules.append(number_rule);
427
428 // =========================================================================
429 // DATES
430 // =========================================================================
431 // Distinguish date/time strings from raw text.
432 PHighlightingRule date_rule;
433 // date regex (for dates of the form: YYYY-MM-DD HH:mm:ss)
434 QRegularExpression date_regex("\\b\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3["
435 "01]) (0\\d|1\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\b");
436 date_rule.fPattern = date_regex;
437 date_rule.fFormat = fDateFormat;
438 fHighlightingRules.append(date_rule);
439
440 // =========================================================================
441 // INLINE AND LINE COMMENTS
442 // =========================================================================
443 // Musrfit treats lines beginning with '#' as ignored comments.
444 // This matches a literal '#' symbol and captures everything remaining on that
445 // line. Styled gray and italicized to quickly indicate non-executable text
446 // annotations.
447 PHighlightingRule comment_rule;
448 QRegularExpression comment_regex("#.*");
449 comment_rule.fPattern = comment_regex;
450 comment_rule.fFormat = fCommentFormat;
451 fHighlightingRules.append(comment_rule);
452}
453
462void PMsrHighlighter::AddRule(const QStringList &keywords,
463 const QTextCharFormat &formatting) {
464 // Instantiate the PHighlightingRule struct.
466
467 // loop through every keyword
468 for (const QString &keyword : keywords) {
469 // Wrap each keyword string into a strict word-boundary (\b) regular
470 // expression. This ensures keywords matching inside longer variable titles
471 // do not falsely trigger formatting.
472 QRegularExpression regex(QString("\\b%1\\b").arg(keyword));
473
474 // apply the formatting to the rule struct
475 rule.fPattern = regex;
476 rule.fFormat = formatting;
477
478 // add the rule to the main list
479 this->fHighlightingRules.append(rule);
480 }
481}
482
491void PMsrHighlighter::highlightBlock(const QString &text) {
492
493 // Sequentially process each entry stored inside the rules vector array.
494 for (const PHighlightingRule &rule : std::as_const(fHighlightingRules)) {
495 // Execute a global search through the single block string provided.
496 QRegularExpressionMatchIterator matchIterator =
497 rule.fPattern.globalMatch(text);
498
499 // Loop over every match location instance discovered within this single
500 // text string.
501 while (matchIterator.hasNext()) {
502 QRegularExpressionMatch match = matchIterator.next();
503
504 // Extract the position details of the substring match sequence.
505 int index = match.capturedStart();
506 int length = match.capturedLength();
507
508 // Core Qt framework utility method which maps styles directly onto
509 // coordinates of the running open source buffer segment.
510 setFormat(index, length, rule.fFormat);
511 }
512 }
513
514 // Treat highlighting of the TITLE block separately so that it take precedence
515 // over all other rules.
516 if (currentBlock().blockNumber() == 0) {
517 // applies the title formatting for the entirety of the first line
518 setFormat(0, text.length(), fTitleFormat);
519 }
520}
Definition of the PMsrHighlighter class for musredit.
QTextCharFormat fFunctionsFormat
Formatting profile for FUNCTION keywords.
QTextCharFormat fRunFormat
Formatting profile RUN/GLOBAL keywords.
QTextCharFormat fParFormat
Formatting profile for parX keywords.
QTextCharFormat fTitleFormat
Formatting profile for TITLE line.
QTextCharFormat fCommentFormat
Formatting profile for comments.
QTextCharFormat fOptionsFormat
Formatting profile for keyword input options.
QTextCharFormat fFunFormat
Formatting profile funX keywords.
QTextCharFormat fMapFormat
Formatting profile mapX keywords.
void AddRule(const QStringList &keywords, const QTextCharFormat &formatting)
Helper function for passing formatting information to the fHighlightingRules dynamic array.
QTextCharFormat fDateFormat
Formatting profile for date & time strings.
QTextCharFormat fFourierFormat
Formatting profile FOURIER keywords.
QTextCharFormat fBoolFormat
Formatting profile for boolean strings.
QTextCharFormat fCommandsFormat
Formatting profile COMMANDS keywords.
QTextCharFormat fPlotFormat
Formatting profile PLOT keywords.
void highlightBlock(const QString &text) override
Automatically called by the Qt rendering engine to format lines of text.
QTextCharFormat fBlockFormat
Formatting profile for BLOCK keywords.
QTextCharFormat fInfoFormat
Formatting profile for auto-printed information.
QTextCharFormat fNullFormat
Formatting profile for null strings.
QTextCharFormat fNumberFormat
Formatting profile for integer & float strings.
PMsrHighlighter(QTextDocument *parent=nullptr)
Constructs a PMsrHighlighter object and attaches it to a target document.
QTextCharFormat fTheoryFormat
Formatting profile for THEORY keywords.
QVector< PHighlightingRule > fHighlightingRules
A dynamic array tracking all active syntax parsing rules.
Container grouping a lookup pattern with its visual theme mapping.
QRegularExpression fPattern
The compiled regular expression pattern to search for.
QTextCharFormat fFormat
The text style (color, font, weight) applied upon match.