Engauge Digitizer 2
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
7#include "ColorFilterMode.h"
10#include "Logger.h"
11#include "MainWindow.h"
12#include <QApplication>
13#include <QCoreApplication>
14#include <QDebug>
15#include <QDir>
16#include <QFileInfo>
17#include <QMessageBox>
18#include <QObject>
19#include <QProcessEnvironment>
20#include <QStyleFactory>
21#include "TranslatorContainer.h"
22#include "ZoomFactor.h"
23
24using namespace std;
25
26const QString CMD_DEBUG ("debug");
27const QString CMD_DROP_REGRESSION ("dropregression");
28const QString CMD_ERROR_REPORT ("errorreport");
29const QString CMD_EXPORT_ONLY ("exportonly");
30const QString CMD_EXTRACT_IMAGE_ONLY ("extractimageonly");
31const QString CMD_FILE_CMD_SCRIPT ("filecmdscript");
32const QString CMD_GNUPLOT ("gnuplot");
33const QString CMD_HELP ("help");
34const QString CMD_REGRESSION ("regression");
35const QString CMD_RESET ("reset");
36const QString CMD_STYLE ("style"); // Qt handles this
37const QString CMD_STYLES ("styles"); // Not to be confused with -style option that qt handles
38const QString CMD_UPGRADE ("upgrade");
39const QString DASH ("-");
53const QString ENGAUGE_LOG_FILE (".engauge.log");
54
55// Prototypes
56bool checkFileExists (const QString &file);
58bool engaugeLogFilenameAttempt (const QString &path,
60void parseCmdLine (int argc,
61 char **argv,
62 bool &isDebug,
63 bool &isDropRegression,
64 bool &isReset,
68 bool &isGnuplot,
69 bool &isExportOnly,
72 bool &isUpgrade,
81 const QString &arg,
82 const QString &msgUnadorned);
83void showMessageAndQuit (const QString &msg);
84void showStylesAndQuit ();
85void showUsageAndQuit ();
87
88// Functions
90{
91 QFileInfo check (file);
92 return check.exists() && check.isFile();
93}
94
96{
97 QString pathAndFile; // Return empty value in OSX which is unused
98
99#if !defined(OSX_RELEASE) && !defined(WIN_RELEASE) && !defined(APPIMAGE_RELEASE)
101
102 // Make multiple attempts until a directory is found where the log file can be written
103 if (!engaugeLogFilenameAttempt (QCoreApplication::applicationDirPath(), pathAndFile)) {
104 if (!engaugeLogFilenameAttempt (env.value ("HOME"), pathAndFile)) {
105 if (!engaugeLogFilenameAttempt (env.value ("TEMP"), pathAndFile)) {
106 pathAndFile = ENGAUGE_LOG_FILE; // Current directory will have to do
107 }
108 }
109 }
110#endif
111
112 return pathAndFile;
113}
114
117{
118 bool success = false;
119
120 // Test if file can be opened. Checking permissions on directory is unreliable in Windows/OSX
121 pathAndFile = QString ("%1%2%3")
122 .arg (path)
123 .arg (QDir::separator())
124 .arg (ENGAUGE_LOG_FILE);
126 if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
127 // Success
128 file.close();
129 file.remove(); // Cleanup
130 success = true;
131 }
132
133 return success;
134}
135
136int main(int argc, char *argv[])
137{
138 qRegisterMetaType<ColorFilterMode> ("ColorFilterMode");
139 qRegisterMetaType<FittingCurveCoefficients> ("FilterCurveCoefficients");
140 qRegisterMetaType<ZoomFactor> ("ZoomFactor");
141
143
144 // Translations
145 TranslatorContainer translatorContainer (app); // Must exist until execution terminates
146
147 // Command line
152 argv,
153 isDebug,
155 isReset,
159 isGnuplot,
163 isUpgrade,
166
167 // Logging
168 initializeLogging ("engauge",
170 isDebug);
171 LOG4CPP_INFO_S ((*mainCat)) << "main args=" << QApplication::arguments().join (" ").toLatin1().data();
172
173 // Upgrade or run normally
174 int rtn = 0;
175 if (isUpgrade) {
177 } else {
178 // Create and show main window
183 isGnuplot,
184 isReset,
190 w.show();
191
192 // Event loop
193 rtn = app.exec();
194 }
195
196 return rtn;
197}
198
200 char **argv,
201 bool &isDebug,
202 bool &isDropRegression,
203 bool &isReset,
207 bool &isGnuplot,
208 bool &isExportOnly,
209 bool &isExtractImageOnly,
211 bool &isUpgrade,
214{
215 bool showUsage = false;
216
218
219 // State
220 bool nextIsErrorReportFile = false;
221 bool nextIsExtractImageOnly = false;
222 bool nextIsFileCmdScript = false;
223
224 // Defaults
225 isDebug = false;
226 isDropRegression = false;
227 isReset = false;
228 errorReportFile = "";
231 isGnuplot = false;
232 isExportOnly = false;
233 isExtractImageOnly = false;
235 isUpgrade = false;
236
237 for (int i = 1; i < argc; i++) {
238
239 bool isLoadStartupFile = false;
240
243 argv [i],
244 QObject::tr ("is not a valid file name"));
246 nextIsErrorReportFile = false;
247 } else if (nextIsExtractImageOnly) {
249 argv [i],
250 QObject::tr ("is not a valid image file extension"));
253 } else if (nextIsFileCmdScript) {
255 argv [i],
256 QObject::tr ("is not a valid file name"));
258 nextIsFileCmdScript = false;
259 } else if (strcmp (argv [i], DASH_DEBUG.toLatin1().data()) == 0) {
260 isDebug = true;
261 } else if (strcmp (argv [i], DASH_DROP_REGRESSION.toLatin1().data()) == 0) {
262 isDropRegression = true;
263 } else if (strcmp (argv [i], DASH_ERROR_REPORT.toLatin1().data()) == 0) {
265 } else if (strcmp (argv [i], DASH_EXPORT_ONLY.toLatin1().data()) == 0) {
266 isExportOnly = true;
267 } else if (strcmp (argv [i], DASH_EXTRACT_IMAGE_ONLY.toLatin1().data()) == 0) {
268 isExtractImageOnly = true;
270 } else if (strcmp (argv [i], DASH_FILE_CMD_SCRIPT.toLatin1().data()) == 0) {
271 nextIsFileCmdScript = true;
272 } else if (strcmp (argv [i], DASH_GNUPLOT.toLatin1().data()) == 0) {
273 isGnuplot = true;
274 } else if (strcmp (argv [i], DASH_HELP.toLatin1().data()) == 0) {
275 showUsage = true; // User requested help
276 } else if (strcmp (argv [i], DASH_REGRESSION.toLatin1().data()) == 0) {
278 } else if (strcmp (argv [i], DASH_RESET.toLatin1().data()) == 0) {
279 isReset = true;
280 } else if (strcmp (argv [i], DASH_STYLE.toLatin1().data()) == 0) {
281 // This branch never executes because Qt strips out '-style <style>' and processes it.
282 // This comment is here just to document that special handling
283 } else if (strcmp (argv [i], DASH_STYLES.toLatin1().data()) == 0) {
285 } else if (strcmp (argv [i], DASH_UPGRADE.toLatin1().data()) == 0) {
286 isUpgrade = true;
287 } else if (strncmp (argv [i], DASH.toLatin1().data(), 1) == 0) {
288 showUsage = true; // User entered an unrecognized token
289 } else {
290 // MainWindow will change current directory (which is often some obscure application directory),
291 // so relative paths must be changed in advance to absolute so the files can still be found
294 if (fInfo.isRelative() && !fileName.startsWith ("http")) {
295 fileName = fInfo.absoluteFilePath();
296 }
297
298 isLoadStartupFile = true;
299 loadStartupFiles << fileName; // Save file name
300 }
301
302 // keep command line arguments
303 if (!isLoadStartupFile) {
305 }
306 }
307
308 // Sanity checks
319
320 // Usage
322
324
325 }
326}
327
333{
334 if (isRepeatingFlag && (!errorReportFile.isEmpty() ||
335 !fileCmdScriptFile.isEmpty() ||
336 loadStartupFiles.size() == 0)) {
337
338 // Condition that at only load files are specified, and there is at least one of them, is not satisfied so
339 // show more specific error message than showUsageAndQuit, and then quit
340 QString msg;
342 str << dashForRepeatingFlag.toLatin1().data() << " " << QObject::tr ("is used only with one or more load files");
344 }
345}
346
348 const QString &arg,
349 const QString &msgUnadorned)
350{
351 if (!requiredCondition) {
352
353 // Required condition is not satisfied. Show a more specific error message than showUsageAndQuit and then quit
354 QString msg = QString ("%1 %2")
355 .arg (arg)
356 .arg (msgUnadorned);
358 }
359}
360
362{
363 // Show message in QMessageBox instead of cout or cerr since console output is disabled in Microsoft Windows
364 QMessageBox::critical (nullptr,
365 QObject::tr ("Engauge Digitizer"),
366 msg);
367 exit (0);
368}
369
371{
372 QString msg;
374 str << QObject::tr ("Available styles") << ": " << QStyleFactory::keys ().join (", ");
376}
377
379{
380 QString msg;
382 str << "<html>Usage: engauge "
383 << "[" << DASH_DEBUG.toLatin1().data() << "] "
384 << "[" << DASH_DROP_REGRESSION.toLatin1().data() << "] "
385 << "[" << DASH_ERROR_REPORT.toLatin1().data() << " &lt;file&gt;] "
386 << "[" << DASH_EXPORT_ONLY.toLatin1().data() << "] "
387 << "[" << DASH_EXTRACT_IMAGE_ONLY.toLatin1().data() << " &lt;extension&gt;] "
388 << "[" << DASH_FILE_CMD_SCRIPT.toLatin1().data() << " &lt;file&gt; "
389 << "[" << DASH_GNUPLOT.toLatin1().data() << "] "
390 << "[" << DASH_HELP.toLatin1().data() << "] "
391 << "[" << DASH_REGRESSION.toLatin1().data() << "] "
392 << "[" << DASH_RESET.toLatin1().data () << "] "
393 << "[" << DASH_STYLE.toLatin1().data () << " &lt;style&gt;] "
394 << "[" << DASH_STYLES.toLatin1().data () << "] "
395 << "[&lt;load_file1&gt;] [&lt;load_file2&gt;] ..." << endl
396 << "<table>"
397 << "<tr>"
398 << "<td>" << DASH_DEBUG.toLatin1().data() << "</td>"
399 << "<td>"
400 << QObject::tr ("Enables extra debug information. Used for debugging").toLatin1().data()
401 << "</td>"
402 << "</tr>"
403 << "<tr>"
404 << "<td>" << DASH_DROP_REGRESSION.toLatin1().data() << "</td>"
405 << "<td>"
406 << QObject::tr ("Indicates files opened at startup are for testing drag and drop. Used for regression testing").toLatin1().data()
407 << "</td>"
408 << "</tr>"
409 << "<tr>"
410 << "<td>" << DASH_ERROR_REPORT.toLatin1().data() << "</td>"
411 << "<td>"
412 << QObject::tr ("Specifies an error report file as input. Used for debugging and regression testing").toLatin1().data()
413 << "</td>"
414 << "</tr>"
415 << "<tr>"
416 << "<td>" << DASH_EXPORT_ONLY.toLatin1().data() << "</td>"
417 << "<td>"
418 << QObject::tr ("Export each loaded startup file, which must have all axis points defined, then stop").toLatin1().data()
419 << "</td>"
420 << "</tr>"
421 << "<tr>"
422 << "<td>" << DASH_EXTRACT_IMAGE_ONLY.toLatin1().data() << "</td>"
423 << "<td>"
424 << QObject::tr ("Extract image in each loaded startup file to a file with the specified extension, then stop").toLatin1().data()
425 << "</td>"
426 << "</tr>"
427 << "<tr>"
428 << "<td>" << DASH_FILE_CMD_SCRIPT.toLatin1().data() << "</td>"
429 << "<td>"
430 << QObject::tr ("Specifies a file command script file as input. Used for debugging and testing").toLatin1().data()
431 << "</td>"
432 << "</tr>"
433 << "<tr>"
434 << "<td>" << DASH_GNUPLOT.toLatin1().data() << "</td>"
435 << "<td>"
436 << QObject::tr ("Output diagnostic gnuplot input files. Used for debugging").toLatin1().data()
437 << "</td>"
438 << "</tr>"
439 << "<tr>"
440 << "<td>" << DASH_HELP.toLatin1().data() << "</td>"
441 << "<td>"
442 << QObject::tr ("Show this help information").toLatin1().data()
443 << "</td>"
444 << "</tr>"
445 << "<tr>"
446 << "<td>" << DASH_REGRESSION.toLatin1().data() << "</td>"
447 << "<td>"
448 << QObject::tr ("Executes the error report file or file command script. Used for regression testing").toLatin1().data()
449 << "</td>"
450 << "</tr>"
451 << "<tr>"
452 << "<td>" << DASH_RESET.toLatin1().data() << "</td>"
453 << "<td>"
454 << QObject::tr ("Removes all stored settings, including window positions. Used when windows start up offscreen").toLatin1().data()
455 << "</td>"
456 << "</tr>"
457 << "<tr>"
458 << "<td>" << DASH_STYLE.toLatin1().data() << "</td>"
459 << "<td>"
460 << QString ("%1 %2")
461 .arg (QObject::tr ("Set the window style to one of the styles listed by the command line option"))
462 .arg (DASH_STYLES).toLatin1().data()
463 << "</td>"
464 << "</tr>"
465 << "<tr>"
466 << "<td>" << DASH_STYLES.toLatin1().data() << "</td>"
467 << "<td>"
468 << QString ("%1 %2")
469 .arg (QObject::tr ("Show a list of available styles that can be used with the command line option"))
470 .arg (DASH_STYLE).toLatin1().data()
471 << "</td>"
472 << "</tr>"
473 << "<tr>"
474 << "<td>" << DASH_UPGRADE.toLatin1().data() << "</td>"
475 << "<td>"
476 << QObject::tr ("Upgrade files opened at startup to the most recent version").toLatin1().data()
477 << "</td>"
478 << "</tr>"
479 << "<tr>"
480 << "<td>" << QString ("&lt;load file&gt; ").toLatin1().data() << "</td>"
481 << "<td>"
482 << QObject::tr ("File(s) to be imported or opened at startup").toLatin1().data()
483 << "</td>"
484 << "</tr>"
485 << "</table></html>";
486
488}
489
491{
492 QString FILE_SUFFIX (".dig");
493 QString UPGRADE_TOKEN ("_upgrade");
494
495 QString msg;
496
497 QStringList::const_iterator itr;
498 for (itr = loadStartupFiles.begin(); itr != loadStartupFiles.end(); itr++) {
499
502
503 // First try to insert upgrade token before file prefix if it is recognized
504 if (filenameOld.endsWith (FILE_SUFFIX,
505 Qt::CaseInsensitive)) {
506 QString withoutSuffix = filenameOld.left (filenameOld.size () - FILE_SUFFIX.size ());
507 filenameNew = QString ("%1%2%3")
508 .arg (withoutSuffix)
509 .arg (UPGRADE_TOKEN)
510 .arg (FILE_SUFFIX);
511 } else {
512
513 // Otherwise append upgrade token
514 filenameNew = QString ("%1%2")
515 .arg (filenameOld)
516 .arg (UPGRADE_TOKEN);
517 }
518
519 // Get old file
520 Document document (filenameOld);
521
522 // Make new file
524 if (!file.open (QFile::WriteOnly)) {
525
526 msg += QString ("%1 %2")
527 .arg (QObject::tr ("Could not write to"))
528 .arg (filenameNew);
529
530 } else {
531
533 writer.setAutoFormatting (true);
534 writer.writeStartDocument();
535 writer.writeDTD ("<!DOCTYPE engauge>");
536 document.saveXml (writer);
537 writer.writeEndDocument ();
538
539 msg += QString ("%1 %2 %3 %4")
540 .arg (QObject::tr ("Upgraded"))
541 .arg (filenameOld)
542 .arg (QObject::tr ("to"))
543 .arg (filenameNew);
544 }
545 }
546
547 // Do not show a message using QMessageBox since upgrade mode may be called hundreds
548 // of times successively by python scripts. Logging is used instead
549 LOG4CPP_INFO_S ((*mainCat)) << "Upgrade results: " << msg.toLatin1().data ();
550
551 exit (0);
552}
const int INNER_RADIUS_MIN
log4cpp::Category * mainCat
Definition Logger.cpp:14
void initializeLogging(const QString &name, const QString &filename, bool isDebug)
Definition Logger.cpp:21
Storage of one imported image and the data attached to that image.
Definition Document.h:42
void saveXml(QXmlStreamWriter &writer) const
Save document to xml.
Definition Document.cpp:884
Provides list of file extensions for import.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition MainWindow.h:92
Class that stores QTranslator objects for the duration of application execution.
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18
int main(int argc, char *argv[])
Definition main.cpp:136
void sanityCheckLoadStartupFiles(bool isRepeatingFlag, const QString &dashForRepeatingFlag, const QString &errorReportFile, const QString &fileCmdScriptFile, const QStringList &loadStartupFiles)
Definition main.cpp:328
const QString CMD_EXPORT_ONLY("exportonly")
const QString DASH_ERROR_REPORT("-"+CMD_ERROR_REPORT)
const QString CMD_STYLE("style")
const QString CMD_ERROR_REPORT("errorreport")
const QString CMD_RESET("reset")
bool engaugeLogFilenameAttempt(const QString &path, QString &pathAndFile)
Definition main.cpp:115
const QString CMD_STYLES("styles")
const QString ENGAUGE_LOG_FILE(".engauge.log")
const QString CMD_DROP_REGRESSION("dropregression")
const QString CMD_REGRESSION("regression")
const QString DASH_GNUPLOT("-"+CMD_GNUPLOT)
const QString DASH_EXTRACT_IMAGE_ONLY("-"+CMD_EXTRACT_IMAGE_ONLY)
void parseCmdLine(int argc, char **argv, bool &isDebug, bool &isDropRegression, bool &isReset, QString &errorReportFile, QString &fileCmdScriptFile, bool &isErrorReportRegressionTest, bool &isGnuplot, bool &isExportOnly, bool &isExtractImageOnly, QString &extractImageOnlyExtension, bool &isUpgrade, QStringList &loadStartupFiles, QStringList &commandLineWithoutLoadStartupFiles)
Definition main.cpp:199
void showUsageAndQuit()
Definition main.cpp:378
void sanityCheckValue(bool requiredCondition, const QString &arg, const QString &msgUnadorned)
Definition main.cpp:347
const QString CMD_GNUPLOT("gnuplot")
QString engaugeLogFilename()
Definition main.cpp:95
const QString DASH_HELP("-"+CMD_HELP)
const QString DASH_UPGRADE("-"+CMD_UPGRADE)
const QString CMD_EXTRACT_IMAGE_ONLY("extractimageonly")
const QString DASH_RESET("-"+CMD_RESET)
const QString CMD_HELP("help")
const QString CMD_UPGRADE("upgrade")
void showMessageAndQuit(const QString &msg)
Definition main.cpp:361
const QString DASH_STYLES("-"+CMD_STYLES)
const QString DASH_REGRESSION("-"+CMD_REGRESSION)
const QString CMD_FILE_CMD_SCRIPT("filecmdscript")
const QString DASH_EXPORT_ONLY("-"+CMD_EXPORT_ONLY)
const QString DASH_DROP_REGRESSION("-"+CMD_DROP_REGRESSION)
const QString DASH_DEBUG("-"+CMD_DEBUG)
const QString DASH_STYLE("-"+CMD_STYLE)
bool checkFileExists(const QString &file)
Definition main.cpp:89
void upgradeFiles(const QStringList &loadStartupFiles)
Definition main.cpp:490
const QString CMD_DEBUG("debug")
void showStylesAndQuit()
Definition main.cpp:370
const QString DASH("-")
const QString DASH_FILE_CMD_SCRIPT("-"+CMD_FILE_CMD_SCRIPT)