mupp 1.1.0
Loading...
Searching...
No Matches
PmuppAdmin.cpp
Go to the documentation of this file.
1/****************************************************************************
2
3 PmuppAdmin.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8*****************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2010-2026 by Andreas Suter *
12 * andreas.suter@psi.ch *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
29
53
54#include <cstdlib>
55#include <iostream>
56
57#include <QMessageBox>
58#include <QString>
59#include <QStringView>
60#include <QFile>
61#include <QTextStream>
62#include <QVector>
63#include <QDir>
64#include <QProcessEnvironment>
65#include <QSysInfo>
66
67#include <QtDebug>
68
69#include "PmuppAdmin.h"
70
71//--------------------------------------------------------------------------
72// implementation of PmuppColor class
73//--------------------------------------------------------------------------
81{
82 fName = "UnDef";
83 fRed = -1;
84 fGreen = -1;
85 fBlue = -1;
86}
87
88//--------------------------------------------------------------------------
100void PmuppColor::setRGB(const int r, const int g, const int b)
101{
102 if ((r>=0) && (r<=255))
103 fRed = r;
104 if ((g>=0) && (g<=255))
105 fGreen = g;
106 if ((b>=0) && (b<=255))
107 fBlue = b;
108}
109
110//--------------------------------------------------------------------------
111// implementation of PmuppAdminXMLParser class
112//--------------------------------------------------------------------------
124{
125 fValid = false;
127
128 QFile file(fln);
129 if (!file.open(QFile::ReadOnly | QFile::Text)) {
130 // warning and create default - STILL MISSING
131 }
132
133 fValid = parse(&file);
134}
135
136//--------------------------------------------------------------------------
151bool PmuppAdminXMLParser::parse(QIODevice *device)
152{
153 fXml.setDevice(device);
154
155 bool expectChars = false;
156 while (!fXml.atEnd()) {
157 fXml.readNext();
158 if (fXml.isStartDocument()) {
160 } else if (fXml.isStartElement()) {
161 startElement();
162 expectChars = true;
163 } else if (fXml.isCharacters() && expectChars) {
164 characters();
165 } else if (fXml.isEndElement()) {
166 endElement();
167 expectChars = false;
168 } else if (fXml.isEndDocument()) {
169 endDocument();
170 }
171 }
172 if (fXml.hasError()) {
173 QString msg;
174 msg = QString("%1 Line %2, column %3").arg(fXml.errorString()).arg(fXml.lineNumber()).arg(fXml.columnNumber());
175 QMessageBox::critical(0, "**ERROR**", msg, QMessageBox::Ok, QMessageBox::NoButton);
176 return false;
177 }
178
179 return true;
180}
181
182//--------------------------------------------------------------------------
192{
193 // nothing to be done here for now
194 return true;
195}
196
197//--------------------------------------------------------------------------
217{
218 QString qName = fXml.name().toString();
219
220 if (qName == "path_file_name") {
222 } else if (qName == "ignore_theme_auto_detection") {
224 } else if (qName == "dark_theme_icon_menu") {
226 } else if (qName == "dark_theme_icon_toolbar") {
228 } else if (qName == "marker") {
230 } else if (qName == "color") {
232 }
233
234 return true;
235}
236
237//--------------------------------------------------------------------------
248{
250
251 return true;
252}
253
254//--------------------------------------------------------------------------
273{
274 QString str = fXml.text().toString();
275 if (str.isEmpty())
276 return true;
277
278 bool ok;
279 int ival, r, g, b;
280 double dval;
281 QString name("");
282 QStringList tok;
283
284 switch (fKeyWord) {
285 case eRecentFile:
286 fAdmin->addRecentFile(QString(str.toLatin1()).trimmed());
287 break;
289 if ((str == "yes") || (str == "y") || (str == "1") || (str == "true"))
290 fAdmin->setIgnoreThemeAutoDetection(true);
291 else
292 fAdmin->setIgnoreThemeAutoDetection(false);
293 break;
295 if ((str == "yes") || (str == "y") || (str == "1") || (str == "true"))
296 fAdmin->setThemeIconsMenu(true);
297 else
298 fAdmin->setThemeIconsMenu(false);
299 break;
301 if ((str == "yes") || (str == "y") || (str == "1") || (str == "true"))
302 fAdmin->setThemeIconsToolbar(true);
303 else
304 fAdmin->setThemeIconsToolbar(false);
305 break;
306 case eMarker:
307 tok = str.split(",", Qt::SkipEmptyParts);
308
309 if ((tok.count() != 1) && (tok.count() != 2)) {
310 return false;
311 }
312
313 ival = tok[0].toInt(&ok);
314 if (!ok)
315 return false;
316
317 dval = 1.0;
318 if (tok.count() == 2) {
319 dval = tok[1].toDouble(&ok);
320 if (!ok)
321 return false;
322 }
323 fAdmin->setMarker(ival, dval);
324 break;
325 case eColor:
326 tok = str.split(",", Qt::SkipEmptyParts);
327
328 if ((tok.count() != 3) && (tok.count() != 4)) {
329 return false;
330 }
331 ival = tok[0].toInt(&ok);
332 if (!ok)
333 return false;
334 r = ival;
335 ival = tok[1].toInt(&ok);
336 if (!ok)
337 return false;
338 g = ival;
339 ival = tok[2].toInt(&ok);
340 if (!ok)
341 return false;
342 b = ival;
343 if (tok.count() == 4)
344 name = tok[3];
345 fAdmin->setColor(r, g, b, name);
346 break;
347 default:
348 break;
349 }
350
351 return true;
352}
353
354//--------------------------------------------------------------------------
365{
366 return true;
367}
368
369//--------------------------------------------------------------------------
370// implementation of PmuppAdmin class
371//--------------------------------------------------------------------------
389{
390 // XML Parser part
391 // 1st: check local directory
392 QString path = QString("./");
393 QString fln = QString("mupp_startup.xml");
394 QString pathFln = path + fln;
395 QProcessEnvironment procEnv = QProcessEnvironment::systemEnvironment();
396 if (!QFile::exists(pathFln)) {
397 // 2nd: check $HOME/.musrfit/mupp/mupp_startup.xml
398 path = procEnv.value("HOME", "");
399 pathFln = path + "/.musrfit/mupp/" + fln;
400 if (!QFile::exists(pathFln)) {
401 // 3rd: check $MUSRFITPATH/mupp_startup.xml
402 path = procEnv.value("MUSRFITPATH", "");
403 pathFln = path + "/" + fln;
404 if (!QFile::exists(pathFln)) {
405 // 4th: check $ROOTSYS/bin/mupp_startup.xml
406 path = procEnv.value("ROOTSYS", "");
407 pathFln = path + "/bin/" + fln;
408 if (!QFile::exists(pathFln)) {
409 // 5th: not found anywhere hence create it
410 path = procEnv.value("HOME", "");
411 pathFln = path + "/.musrfit/mupp/" + fln;
413 }
414 }
415 }
416 }
417
418 if (QFile::exists(pathFln)) { // administration file present
419 PmuppAdminXMLParser handler(pathFln, this);
420 if (!handler.isValid()) {
421 QMessageBox::critical(0, "**ERROR**",
422 "Error parsing mupp_startup.xml settings file.\nProbably a few things will not work porperly.\nPlease fix this first.",
423 QMessageBox::Ok, QMessageBox::NoButton);
424 return;
425 }
426 } else {
427 QMessageBox::critical(0, "**ERROR**",
428 "Couldn't find the mupp_startup.xml settings file.\nProbably a few things will not work porperly.\nPlease fix this first.",
429 QMessageBox::Ok, QMessageBox::NoButton);
430 return;
431 }
432}
433
434//--------------------------------------------------------------------------
446
447//--------------------------------------------------------------------------
458void PmuppAdmin::addRecentFile(const QString str)
459{
460 // check if file name is not already present
461 for (int i=0; i<fRecentFile.size(); i++) {
462 if (str == fRecentFile[i])
463 return;
464 }
465
466 fRecentFile.push_front(str);
467 if (fRecentFile.size() > MAX_RECENT_FILES)
469}
470
471//--------------------------------------------------------------------------
483{
484 QString str("");
485
486 if ((idx >= 0) && (idx < fRecentFile.size()))
487 str = fRecentFile[idx];
488
489 return str;
490}
491
492//--------------------------------------------------------------------------
504 PmuppMarker marker;
505
506 if (idx >= fMarker.size())
507 return marker;
508
509 return fMarker[idx];
510}
511
512//--------------------------------------------------------------------------
524void PmuppAdmin::getColor(QString name, int &r, int &g, int &b)
525{
526 int idx=-1;
527 for (int i=0; i<fColor.size(); i++) {
528 if (fColor[i].getName() == name) {
529 idx = i;
530 break;
531 }
532 }
533
534 if (idx == -1) {
535 r = -1;
536 g = -1;
537 b = -1;
538 } else {
539 fColor[idx].getRGB(r, g, b);
540 }
541}
542
543//--------------------------------------------------------------------------
556void PmuppAdmin::getColor(int idx, int &r, int &g, int &b)
557{
558 if ((idx<=0) || (idx>fColor.size())) {
559 r = -1;
560 g = -1;
561 b = -1;
562 } else {
563 fColor[idx].getRGB(r, g, b);
564 }
565}
566
567//--------------------------------------------------------------------------
578void PmuppAdmin::setMarker(const int marker, const double size)
579{
580 PmuppMarker markerObj;
581
582 // make sure marker is in proper range
583 if ((marker<1) || (marker>49)) {
584 QMessageBox::warning(0, "WARNING", QString("Found Marker (%1) not in the expected range.\nWill ignore it.").arg(marker));
585 return;
586 }
587 markerObj.setMarker(marker);
588 markerObj.setMarkerSize(size);
589
590 fMarker.push_back(markerObj);
591}
592
593//--------------------------------------------------------------------------
606void PmuppAdmin::setColor(const int r, const int g, const int b, QString name)
607{
608 if (((r<0) || (r>255)) ||
609 ((g<0) || (g>255)) ||
610 ((b<0) || (b>255))) {
611 QMessageBox::warning(0, "WARNING", QString("Found Color (%1,%2,%3) not in the expected range.\nWill ignore it.").arg(r).arg(g).arg(b));
612 return;
613 }
614
615 PmuppColor color;
616 color.setName(name);
617 color.setRGB(r,g,b);
618
619 fColor.push_back(color);
620}
621
622//--------------------------------------------------------------------------
641{
642 // check if mupp_startup.xml is present in the current directory, and if yes, use this file to
643 // save the recent file names otherwise use the "master" mupp_startup.xml
644
645 QString str("");
646 QString fln = QString("./mupp_startup.xml");
647 if (!QFile::exists(fln)) {
648 QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
649 fln = QString("%1/.musrfit/mupp/mupp_startup.xml").arg(env.value("HOME"));
650 }
651
652 if (QFile::exists(fln)) { // administration file present
653 QVector<QString> data;
654 QFile file(fln);
655 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
656 std::cerr << std::endl << ">> PmuppAdmin::saveRecentFile: **ERROR** Cannot open " << fln.toLatin1().data() << " for reading." << std::endl;
657 return;
658 }
659 QTextStream fin(&file);
660 while (!fin.atEnd()) {
661 data.push_back(fin.readLine());
662 }
663 file.close();
664
665 // remove <path_file_name> from data
666 for (QVector<QString>::iterator it = data.begin(); it != data.end(); ++it) {
667 if (it->contains("<path_file_name>")) {
668 it = data.erase(it);
669 --it;
670 }
671 }
672
673 // add recent files
674 int i;
675 for (i=0; i<data.size(); i++) {
676 if (data[i].contains("<recent_files>"))
677 break;
678 }
679
680 if (i == data.size()) {
681 std::cerr << std::endl << ">> PmuppAdmin::saveRecentFile: **ERROR** " << fln.toLatin1().data() << " seems to be corrupt." << std::endl;
682 return;
683 }
684 i++;
685 for (int j=0; j<fRecentFile.size(); j++) {
686 str = " <path_file_name>" + fRecentFile[j] + "</path_file_name>";
687 data.insert(i++, str);
688 }
689
690 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
691 std::cerr << std::endl << ">> PmuppAdmin::saveRecentFile: **ERROR** Cannot open " << fln.toLatin1().data() << " for reading." << std::endl;
692 return;
693 }
694 fin.setDevice(&file);
695 for (int i=0; i<data.size(); i++) {
696 fin << data[i] << Qt::endl;
697 }
698 file.close();
699 } else {
700 QString msg("Failed to write mupp_startup.xml. Neither a local nor a global copy found.");
701 QMessageBox::warning(0, "WARNING", msg, QMessageBox::Ok, QMessageBox::NoButton);
702 }
703}
704
705//--------------------------------------------------------------------------
723{
724 // get $HOME
725 QProcessEnvironment procEnv = QProcessEnvironment::systemEnvironment();
726 QString pathName = procEnv.value("HOME", "");
727 pathName += "/.musrfit/mupp";
728
729 // check if the directory $HOME/.musrfit/mupp exists if not create it
730 QDir dir(pathName);
731 if (!dir.exists()) {
732 // directory $HOME/.musrfit/mupp does not exist hence create it
733 dir.mkpath(pathName);
734 }
735
736 // create default mupp_startup.xml file in $HOME/.musrfit/mupp
737 pathName += "/mupp_startup.xml";
738
739 // get the default mupp_startup.xml.in from the internal resources
740 QFile fres(":/mupp_startup.xml.in");
741 if (!fres.exists()) {
742 QString msg = QString("Neither couldn't find nor create mupp_startup.xml. Things are likely not to work.");
743 QMessageBox::critical(0, "ERROR", msg);
744 return;
745 }
746
747 if (!fres.open(QIODevice::ReadOnly | QIODevice::Text)) {
748 QString msg = QString("Couldn't open internal resource file mupp_startup.xml.in. Things are likely not to work.");
749 QMessageBox::critical(0, "ERROR", msg);
750 return;
751 }
752 // text stream for fres
753 QTextStream fin(&fres);
754
755 // mupp_startup.xml default file
756 QFile file(pathName);
757
758 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
759 return;
760
761 // text stream for file
762 QTextStream fout(&file);
763
764 QString line;
765 while (!fin.atEnd()) {
766 line = fin.readLine();
767 fout << line << Qt::endl;
768 }
769
770 file.close();
771 fres.close();
772}
773
774//--------------------------------------------------------------------------
775// END
776//--------------------------------------------------------------------------
Administration and configuration management for mupp application.
bool startDocument()
Handler for XML document start.
PmuppAdmin * fAdmin
pointer to the admin object being populated
Definition PmuppAdmin.h:298
bool parse(QIODevice *device)
Main parsing method that processes the XML document.
EAdminKeyWords fKeyWord
current element type being processed
Definition PmuppAdmin.h:297
QXmlStreamReader fXml
Qt XML stream reader object for parsing.
Definition PmuppAdmin.h:295
virtual bool isValid()
Checks if the XML parsing was successful.
Definition PmuppAdmin.h:242
PmuppAdminXMLParser(const QString &fln, PmuppAdmin *)
Constructor that parses the XML configuration file.
bool fValid
flag indicating successful XML parsing
Definition PmuppAdmin.h:296
bool characters()
Handler for XML element text content.
bool startElement()
Handler for XML element opening tags.
@ eIgnoreThemeAutoDetection
theme auto-detection override
Definition PmuppAdmin.h:252
@ eEmpty
no specific element being processed
Definition PmuppAdmin.h:250
@ eDarkThemeIconsMenu
menu icon theme setting
Definition PmuppAdmin.h:253
@ eDarkThemeIconsToolbar
toolbar icon theme setting
Definition PmuppAdmin.h:254
@ eRecentFile
recent file path element
Definition PmuppAdmin.h:251
@ eMarker
marker definition element
Definition PmuppAdmin.h:255
bool endElement()
Handler for XML element closing tags.
bool endDocument()
Handler for XML document end.
Main administration class for mupp configuration management.
Definition PmuppAdmin.h:325
void addRecentFile(const QString str)
Adds a file to the recent files list.
void setMarker(const int marker, const double size)
Adds a marker definition to the configuration.
QVector< PmuppColor > fColor
vector of configured plot colors
Definition PmuppAdmin.h:466
PmuppAdmin()
Constructor. Loads configuration from mupp_startup.xml.
virtual ~PmuppAdmin()
Destructor. Saves recent files list before destruction.
QVector< PmuppMarker > fMarker
vector of configured plot markers
Definition PmuppAdmin.h:465
QString getRecentFile(int idx)
Gets a recent file path by index.
friend class PmuppAdminXMLParser
Definition PmuppAdmin.h:458
void setColor(const int r, const int g, const int b, QString name="")
Adds a color definition to the configuration.
void createMuppStartupFile()
Creates a default mupp_startup.xml configuration file.
void saveRecentFiles()
Saves the recent files list to the configuration file.
QVector< QString > fRecentFile
ring buffer of recent file paths (max MAX_RECENT_FILES)
Definition PmuppAdmin.h:460
void getColor(QString name, int &r, int &g, int &b)
Gets a color by name.
PmuppMarker getMarker(int idx)
Gets a marker definition by index.
Represents an RGB color for plotting.
Definition PmuppAdmin.h:84
int fBlue
blue component (0-255)
Definition PmuppAdmin.h:128
int fRed
red component (0-255)
Definition PmuppAdmin.h:126
PmuppColor()
Default constructor. Initializes color with undefined values.
QString fName
optional name identifier for the color
Definition PmuppAdmin.h:125
int fGreen
green component (0-255)
Definition PmuppAdmin.h:127
void setName(const QString name)
Sets the color name.
Definition PmuppAdmin.h:114
void setRGB(const int r, const int g, const int b)
Sets the RGB values with validation.
Represents a plot marker style and size.
Definition PmuppAdmin.h:146
void setMarker(int marker)
Sets the marker code.
Definition PmuppAdmin.h:188
void setMarkerSize(double size)
Sets the marker size multiplier.
Definition PmuppAdmin.h:194
#define MAX_RECENT_FILES
Maximum number of recent files to be tracked.
Definition mupp.h:53