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