Engauge Digitizer  2
main.cpp
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"
8 #include <iostream>
9 #include "Logger.h"
10 #include "MainWindow.h"
11 #include <QApplication>
12 #include <QCoreApplication>
13 #include <QDebug>
14 #include <QDir>
15 #include <QFileInfo>
16 #include <QObject>
17 #include <QProcessEnvironment>
18 #include "TranslatorContainer.h"
19 
20 using namespace std;
21 
22 const QString CMD_DEBUG ("debug");
23 const QString CMD_ERROR_REPORT ("errorreport");
24 const QString CMD_FILE_CMD_SCRIPT ("filecmdscript");
25 const QString CMD_GNUPLOT ("gnuplot");
26 const QString CMD_HELP ("help");
27 const QString CMD_REGRESSION ("regression");
28 const QString CMD_RESET ("reset");
29 const QString DASH ("-");
30 const QString DASH_DEBUG ("-" + CMD_DEBUG);
31 const QString DASH_ERROR_REPORT ("-" + CMD_ERROR_REPORT);
32 const QString DASH_FILE_CMD_SCRIPT ("-" + CMD_FILE_CMD_SCRIPT);
33 const QString DASH_GNUPLOT ("-" + CMD_GNUPLOT);
34 const QString DASH_HELP ("-" + CMD_HELP);
35 const QString DASH_REGRESSION ("-" + CMD_REGRESSION);
36 const QString DASH_RESET ("-" + CMD_RESET);
37 const QString ENGAUGE_LOG_FILE ("engauge.log");
38 
39 // Prototypes
40 bool checkFileExists (const QString &file);
41 QString engaugeLogFilename ();
42 bool engaugeLogFilenameAttempt (const QString &path,
43  QString &pathAndFile);
44 void parseCmdLine (int argc,
45  char **argv,
46  bool &isDebug,
47  bool &isReset,
48  QString &errorReportFile,
49  QString &fileCmdScriptFile,
50  bool &isErrorReportRegressionTest,
51  bool &isGnuplot,
52  QStringList &loadStartupFiles);
53 
54 // Functions
55 bool checkFileExists (const QString &file)
56 {
57  QFileInfo check (file);
58  return check.exists() && check.isFile();
59 }
60 
61 QString engaugeLogFilename()
62 {
63  QString pathAndFile; // Return empty value in OSX which is unused
64 
65 #if !defined(OSX_RELEASE) && !defined(WIN_RELEASE) && !defined(APPIMAGE_RELEASE)
66  QProcessEnvironment env;
67 
68  // Make multiple attempts until a directory is found where the log file can be written
69  if (!engaugeLogFilenameAttempt (QCoreApplication::applicationDirPath(), pathAndFile)) {
70  if (!engaugeLogFilenameAttempt (env.value ("HOME"), pathAndFile)) {
71  if (!engaugeLogFilenameAttempt (env.value ("TEMP"), pathAndFile)) {
72  pathAndFile = ENGAUGE_LOG_FILE; // Current directory will have to do
73  }
74  }
75  }
76 #endif
77 
78  return pathAndFile;
79 }
80 
81 bool engaugeLogFilenameAttempt (const QString &path,
82  QString &pathAndFile)
83 {
84  bool success = false;
85 
86  // Test if file can be opened. Checking permissions on directory is unreliable in Windows/OSX
87  pathAndFile = QString ("%1%2%3")
88  .arg (path)
89  .arg (QDir::separator())
90  .arg (ENGAUGE_LOG_FILE);
91  QFile file (pathAndFile);
92  if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
93  // Success
94  file.close();
95  success = true;
96  }
97 
98  return success;
99 }
100 
101 int main(int argc, char *argv[])
102 {
103  qRegisterMetaType<ColorFilterMode> ("ColorFilterMode");
104 
105  QApplication app(argc, argv);
106 
107  // Translations
108  TranslatorContainer translatorContainer (app); // Must exist until execution terminates
109 
110  // Command line
111  bool isDebug, isReset, isGnuplot, isErrorReportRegressionTest;
112  QString errorReportFile, fileCmdScriptFile;
113  QStringList loadStartupFiles;
114  parseCmdLine (argc,
115  argv,
116  isDebug,
117  isReset,
118  errorReportFile,
119  fileCmdScriptFile,
120  isErrorReportRegressionTest,
121  isGnuplot,
122  loadStartupFiles);
123 
124  // Logging
125  initializeLogging ("engauge",
126  engaugeLogFilename(),
127  isDebug);
128  LOG4CPP_INFO_S ((*mainCat)) << "main args=" << QApplication::arguments().join (" ").toLatin1().data();
129 
130  // Create and show main window
131  MainWindow w (errorReportFile,
132  fileCmdScriptFile,
133  isErrorReportRegressionTest,
134  isGnuplot,
135  isReset,
136  loadStartupFiles);
137  w.show();
138 
139  // Event loop
140  return app.exec();
141 }
142 
143 void parseCmdLine (int argc,
144  char **argv,
145  bool &isDebug,
146  bool &isReset,
147  QString &errorReportFile,
148  QString &fileCmdScriptFile,
149  bool &isErrorReportRegressionTest,
150  bool &isGnuplot,
151  QStringList &loadStartupFiles)
152 {
153  const int COLUMN_WIDTH = 20;
154  bool showUsage = false;
155 
156  // State
157  bool nextIsErrorReportFile = false;
158  bool nextIsFileCmdScript = false;
159 
160  // Defaults
161  isDebug = false;
162  isReset = false;
163  errorReportFile = "";
164  fileCmdScriptFile = "";
165  isErrorReportRegressionTest = false;
166  isGnuplot = false;
167 
168  for (int i = 1; i < argc; i++) {
169 
170  if (nextIsErrorReportFile) {
171  errorReportFile = argv [i];
172  showUsage |= !checkFileExists (errorReportFile);
173  nextIsErrorReportFile = false;
174  } else if (nextIsFileCmdScript) {
175  fileCmdScriptFile = argv [i];
176  showUsage |= !checkFileExists (fileCmdScriptFile);
177  nextIsFileCmdScript = false;
178  } else if (strcmp (argv [i], DASH_DEBUG.toLatin1().data()) == 0) {
179  isDebug = true;
180  } else if (strcmp (argv [i], DASH_ERROR_REPORT.toLatin1().data()) == 0) {
181  nextIsErrorReportFile = true;
182  } else if (strcmp (argv [i], DASH_FILE_CMD_SCRIPT.toLatin1().data()) == 0) {
183  nextIsFileCmdScript = true;
184  } else if (strcmp (argv [i], DASH_GNUPLOT.toLatin1().data()) == 0) {
185  isGnuplot = true;
186  } else if (strcmp (argv [i], DASH_HELP.toLatin1().data()) == 0) {
187  showUsage = true; // User requested help
188  } else if (strcmp (argv [i], DASH_REGRESSION.toLatin1().data()) == 0) {
189  isErrorReportRegressionTest = true;
190  } else if (strcmp (argv [i], DASH_RESET.toLatin1().data()) == 0) {
191  isReset = true;
192  } else if (strncmp (argv [i], DASH.toLatin1().data(), 1) == 0) {
193  showUsage = true; // User entered an unrecognized token
194  } else {
195  // MainWindow will change current directory (which is often some obscure application directory),
196  // so relative paths must be changed in advance to absolute so the files can still be found
197  QString fileName = argv [i];
198  QFileInfo fInfo (fileName);
199  if (fInfo.isRelative()) {
200  fileName = fInfo.absoluteFilePath();
201  }
202  loadStartupFiles << fileName; // Save file name
203  }
204  }
205 
206  if (showUsage || nextIsErrorReportFile) {
207 
208  cerr << "Usage: engauge "
209  << "[" << DASH_DEBUG.toLatin1().data() << "] "
210  << "[" << DASH_ERROR_REPORT.toLatin1().data() << " <file>] "
211  << "[" << DASH_FILE_CMD_SCRIPT.toLatin1().data() << " <file> "
212  << "[" << DASH_GNUPLOT.toLatin1().data() << "] "
213  << "[" << DASH_HELP.toLatin1().data() << "] "
214  << "[" << DASH_REGRESSION.toLatin1().data() << "] "
215  << "[" << DASH_RESET.toLatin1().data () << "] "
216  << "[<load_file1>] [<load_file2>] ..." << endl
217  << " " << DASH_DEBUG.leftJustified(COLUMN_WIDTH, ' ').toLatin1().data()
218  << QObject::tr ("Enables extra debug information. Used for debugging").toLatin1().data() << endl
219  << " " << DASH_ERROR_REPORT.leftJustified(COLUMN_WIDTH, ' ').toLatin1().data()
220  << QObject::tr ("Specifies an error report file as input. Used for debugging and testing").toLatin1().data() << endl
221  << " " << DASH_FILE_CMD_SCRIPT.leftJustified(COLUMN_WIDTH, ' ').toLatin1().data()
222  << QObject::tr ("Specifies a file command script file as input. Used for debugging and testing").toLatin1().data() << endl
223  << " " << DASH_GNUPLOT.leftJustified(COLUMN_WIDTH, ' ').toLatin1().data()
224  << QObject::tr ("Output diagnostic gnuplot input files. Used for debugging").toLatin1().data() << endl
225  << " " << DASH_HELP.leftJustified(COLUMN_WIDTH, ' ').toLatin1().data()
226  << QObject::tr ("Show this help information").toLatin1().data() << endl
227  << " " << DASH_REGRESSION.leftJustified(COLUMN_WIDTH, ' ').toLatin1().data()
228  << QObject::tr ("Executes the error report file or file command script. Used for regression testing").toLatin1().data() << endl
229  << " " << DASH_RESET.leftJustified(COLUMN_WIDTH, ' ').toLatin1().data()
230  << QObject::tr ("Removes all stored settings, including window positions. Used when windows start up offscreen").toLatin1().data() << endl
231  << " " << QString ("<load file> ").leftJustified(COLUMN_WIDTH, ' ').toLatin1().data()
232  << QObject::tr ("File(s) to be imported or opened at startup").toLatin1().data() << endl;
233 
234  exit (0);
235  }
236 }
Class that stores QTranslator objects for the duration of application execution.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:83