1 #include <QApplication>
3 #include <QStyleFactory>
10 #include "debuginfo.h"
11 #include "findresultwidget.h"
12 #include "findwidget.h"
14 #include "flagrowobj.h"
15 #include "headingeditor.h"
17 #include "mainwindow.h"
18 #include "noteeditor.h"
20 #include "scripteditor.h"
21 #include "scriptoutput.h"
23 #include "shortcuts.h"
24 #include "taskeditor.h"
25 #include "taskmodel.h"
27 #include "warningdialog.h"
30 #include <QtDBus/QDBusConnection>
31 #include <QtDBus/QDBusError>
39 QString vymCodeQuality;
40 QString vymInstanceName;
44 QTextStream vout(stdout); // vymout - Testing for now. Flush after writing...
46 // Accessing JIRA and Confluence is done using agents
47 // Credentials may be stored in settings, but only on request
49 QString confluencePassword;
52 TaskEditor *taskEditor;
53 ScriptEditor *scriptEditor;
54 ScriptOutput *scriptOutput;
55 HeadingEditor *headingEditor;
56 NoteEditor *noteEditor; // used in Constr. of LinkableMapObj
57 BranchPropertyEditor *branchPropertyEditor;
59 // initialized in mainwindow
61 FindWidget *findWidget;
62 FindResultWidget *findResultWidget;
64 FlagRowMaster *systemFlagsMaster;
65 FlagRowMaster *standardFlagsMaster;
66 FlagRowMaster *userFlagsMaster;
70 ulong itemLastID = 0; // Unique ID for all items in all models
71 ulong imageLastID = 0; // Unique ID for caching images, also flags not in tree
73 QDir tmpVymDir; // All temp files go there, created in mainwindow
74 QDir cacheDir; // tmp dir with cached svg files in tmpVymDir
75 QString clipboardDir; // Clipboard used in all mapEditors
76 QString clipboardFile; // Clipboard used in all mapEditors
78 QDir vymBaseDir; // Containing all styles, scripts, images, ...
80 QDir vymTranslationsDir; // Translation files (*.qm)
81 QTranslator vymTranslator;
86 #if defined(Q_OS_WINDOWS)
89 QString iconPath; // Pointing to icons used for toolbars
90 QString flagsPath; // Pointing to flags
92 bool debug; // global debugging flag
93 bool testmode; // Used to disable saving of autosave setting
94 bool restoreMode = false; // During restore, existing lockfiles are ignored
96 QStringList ignoredLockedFiles;
97 QStringList lastSessionFiles; //! Will be overwritten in setting after load, so read initially
99 Switchboard switchboard;
101 Settings settings("InSilmaril", "vym"); // Organization, Application name
103 bool zipToolAvailable = false;
104 bool unzipToolAvailable = false;
105 QString zipToolPath; // Platform dependant zip tool
106 QString unzipToolPath; // For windows same as zipToolPath
108 QList<Command *> modelCommands;
109 QList<Command *> vymCommands;
114 int statusbarTime = 10000;
119 int warningCount = 0;
120 int criticalCount = 0;
123 QString editorFocusStyle =
124 QString(" border-color: #3daee9; border-style:outset; border-width:3px; "
127 #include <QScriptEngine>
128 QScriptValue scriptPrint(QScriptContext *ctx, QScriptEngine *eng);
130 void msgHandler(QtMsgType type, const QMessageLogContext &context,
133 QByteArray localMsg = msg.toLocal8Bit();
136 fprintf(stderr, "%s (%s:%u, %s)\n", localMsg.constData(), context.file,
137 context.line, context.function);
140 fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(),
141 context.file, context.line, context.function);
145 fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(),
146 context.file, context.line, context.function);
150 fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(),
151 context.file, context.line, context.function);
155 fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(),
156 context.file, context.line, context.function);
160 int main(int argc, char *argv[])
162 QApplication app(argc, argv);
164 // Define some constants shared in various places
165 vymName = __VYM_NAME;
166 vymVersion = __VYM_VERSION;
167 vymBuildDate = __VYM_BUILD_DATE;
168 vymCodeName = __VYM_CODENAME;
169 vymCodeQuality = __VYM_CODE_QUALITY;
170 vymHome = __VYM_HOME;
172 // Install our own handler for messages
173 qInstallMessageHandler(msgHandler);
176 vout.setCodec("UTF-8");
178 // Reading and initializing options commandline options
179 options.add("batch", Option::Switch, "b", "batch");
180 options.add("commands", Option::Switch, "c", "commands");
181 options.add("commandslatex", Option::Switch, "cl", "commandslatex");
182 options.add("debug", Option::Switch, "d", "debug");
183 options.add("help", Option::Switch, "h", "help");
184 options.add("load", Option::String, "L", "load");
185 options.add("local", Option::Switch, "l", "local");
186 options.add("locale", Option::String, "locale", "locale");
187 options.add("name", Option::String, "n", "name");
188 options.add("quit", Option::Switch, "q", "quit");
189 options.add("run", Option::String, "R", "run");
190 options.add("recover", Option::Switch, "recover", "recover");
191 options.add("restore", Option::Switch, "r", "restore");
192 options.add("shortcuts", Option::Switch, "s", "shortcuts");
193 options.add("testmode", Option::Switch, "t", "testmode");
194 options.add("version", Option::Switch, "v", "version");
196 "VYM - View Your Mind\n"
197 "--------------------\n\n"
198 "Information about vym can be found in vym.pdf,\n"
199 "which should be part of the vym package.\n"
200 "It is also available at the project homepage:\n\n"
201 "http://www.InSilmaril.de/vym\n\n"
202 "Usage: vym [OPTION]... [FILE]... \n"
203 "Open FILEs with vym\n\n"
204 "-b batch batch mode: hide windows\n"
205 "-c commands List all available commands\n"
206 "-cl commandslatex List commands in LaTeX format\n"
207 "-d debug Show debugging output\n"
208 "-h help Show this help text\n"
209 "-L load Load script\n"
210 "-l local Run with ressources in current directory\n"
211 "--locale locale Override system locale setting to select\n"
213 "-n STRING name Set name of instance for DBus access\n"
214 "-q quit Quit immediatly after start for benchmarking\n"
215 "-R FILE run Run script\n"
216 "-r restore Restore last session\n"
217 "--recover recover Delete lockfiles during initial loading of\n"
219 "-s shortcuts Show Keyboard shortcuts on start\n"
220 "-t testmode Test mode, e.g. no autosave and changing\n"
222 "-v version Show vym version\n");
224 if (options.parse()) {
225 cout << endl << qPrintable(options.getHelpText()) << endl;
229 if (options.isOn("version")) {
230 QString s = QString("VYM - View Your Mind (c) 2004-%1").arg(QDate::currentDate().year());
231 s += " Uwe Drechsel\n";
232 s += " Version: " + vymVersion;
233 if (!vymCodeName.isEmpty())
234 s += QString(" - \"%1\"").arg(vymCodeName);
236 s += " Quality: " + vymCodeQuality + "\n";
237 s += "Build date: " + vymBuildDate + "\n";
238 cout << s.toStdString();
243 taskModel = new TaskModel();
245 debug = options.isOn("debug");
247 testmode = options.isOn("testmode");
249 QString pidString = QString::number(QCoreApplication::applicationPid());
251 #if defined(VYM_DBUS)
253 QDBusConnection dbusConnection = QDBusConnection::sessionBus();
254 if (!dbusConnection.registerService("org.insilmaril.vym-" + pidString)) {
257 qPrintable(QDBusConnection::sessionBus().lastError().message()));
262 if (options.isOn("name"))
263 vymInstanceName = options.getArg("name");
265 vymInstanceName = pidString;
268 qDebug() << "QT_DEBUG is set";
272 // Use /usr/share/vym or /usr/local/share/vym or . ?
274 if (options.isOn("local")) {
275 vymBaseDir.setPath(vymBaseDir.currentPath());
278 // then look for environment variable
279 if (getenv("VYMHOME") != 0) {
280 vymBaseDir.setPath(getenv("VYMHOME"));
283 // ok, let's find my way on my own
285 #if defined(Q_OS_MACX)
286 // Executable is in vym.app/Contents/MacOS, so go up first:
287 vymBaseDir = QCoreApplication::applicationDirPath();
289 vymBaseDir.cd("Resources");
290 #elif defined(Q_OS_WINDOWS)
291 vymBaseDir.setPath(QCoreApplication::applicationDirPath());
293 vymBaseDir.setPath(VYMBASEDIR);
297 // Platform specific settings
298 vymPlatform = QSysInfo::prettyProductName();
300 #if defined(Q_OS_WINDOWS)
301 // Only Windows 10 has tar. Older windows versions not supported.
304 zipToolPath = "/usr/bin/zip";
305 unzipToolPath = "/usr/bin/unzip";
307 iconPath = vymBaseDir.path() + "/icons/";
308 flagsPath = vymBaseDir.path() + "/flags/";
310 // When running locally, use local macros. Otherwise settings are used
311 if (options.isOn("local"))
312 macros.setPath(vymBaseDir.path() + "/macros/macros.vys");
316 .value("/macros/path", vymBaseDir.path() + "/macros/macros.vys")
321 if (options.isOn("local"))
322 useDir = QDir().current();
324 useDir = QDir().home();
325 lastImageDir = useDir;
327 lastExportDir = useDir;
329 if (options.isOn("help")) {
330 cout << qPrintable(options.getHelpText()) << endl;
334 // Initialize translations
335 if (options.isOn("locale"))
336 localeName = options.getArg("locale");
338 // Use dark theme depending on system appearance and preferences
339 int text_hsv_value = app.palette().color(QPalette::WindowText).value();
340 int bg_hsv_value = app.palette().color(QPalette::Base).value();
341 bool systemSeemsDark = (text_hsv_value > bg_hsv_value);
342 QString settingsDarkTheme = settings.value("/system/darkTheme", "system").toString();
343 usingDarkTheme = false;
344 if (settingsDarkTheme != "never") {
345 if (settingsDarkTheme == "always" || (settingsDarkTheme == "system" && systemSeemsDark))
346 usingDarkTheme = true;
349 #if defined(Q_OS_WINDOWS)
350 if (usingDarkTheme) {
351 qApp->setStyle(QStyleFactory::create("fusion"));
353 // On Windows, there is no dark palette predefined, let's do that on our own
355 palette.setColor(QPalette::Window, QColor(53,53,53));
356 palette.setColor(QPalette::WindowText, Qt::white);
357 palette.setColor(QPalette::Base, QColor(27, 30, 32));
358 palette.setColor(QPalette::AlternateBase, QColor(53,53,53));
359 palette.setColor(QPalette::ToolTipBase, Qt::white);
360 palette.setColor(QPalette::ToolTipText, Qt::white);
361 palette.setColor(QPalette::Text, Qt::white);
362 palette.setColor(QPalette::Button, QColor(53,53,53));
363 palette.setColor(QPalette::ButtonText, Qt::white);
364 palette.setColor(QPalette::BrightText, Qt::red);
365 palette.setColor(QPalette::Highlight, QColor(142,45,197).lighter());
366 palette.setColor(QPalette::HighlightedText, Qt::black);
367 qApp->setPalette(palette);
371 // Prepare and check translations
372 vymTranslationsDir = QDir(vymBaseDir.path() + "/translations");
373 vymTranslationsDir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
375 bool translationsMissing = false;
376 if(!vymTranslationsDir.exists())
377 translationsMissing = true;
378 else if (vymTranslationsDir.isEmpty())
379 translationsMissing = true;
381 if (translationsMissing) {
383 warn.setMinimumWidth(800);
384 warn.setMinimumHeight(350);
385 warn.showCancelButton(false);
386 warn.setShowAgainName("mainwindow/translations/qmFilesMissing");
387 warn.setCaption("Translations not available");
389 "vym has not been built correctly and only will be available in English: \n\n"
390 "No translation files in\n" +
391 vymTranslationsDir.path().toLatin1() + "\n\n" +
392 "Please get vym from\n"
393 " * https://sourceforge.net/projects/vym/ or \n"
394 " * https://software.opensuse.org//download.html?project=home%3Ainsilmaril&package=vym");
398 if (!localeName.isEmpty())
399 // Use localeName to load specific language
400 ok = vymTranslator.load(QString("vym.%1.qm").arg(localeName), vymTranslationsDir.path());
402 ok = vymTranslator.load(QLocale(), "vym", ".", vymTranslationsDir.path(), ".qm");
406 warn.showCancelButton(false);
408 QString("Couldn't load translation for locale \"%1\" from\n%2")
410 .arg(vymTranslationsDir.path()));
411 warn.setShowAgainName("mainwindow/translations/localeMissing");
414 QCoreApplication::installTranslator(&vymTranslator);
417 // Initializing the master rows of flags
418 systemFlagsMaster = new FlagRowMaster;
419 systemFlagsMaster->setName("systemFlagsMaster");
421 standardFlagsMaster = new FlagRowMaster;
422 standardFlagsMaster->setName("standardFlagsMaster");
423 standardFlagsMaster->setPrefix("standard/");
425 userFlagsMaster = new FlagRowMaster;
426 userFlagsMaster->setName("userFlagsMaster");
427 userFlagsMaster->setPrefix("user/");
429 // Initialize editors
430 noteEditor = new NoteEditor("noteeditor");
431 noteEditor->setWindowIcon(QPixmap(":/vym-editor.png"));
432 headingEditor = new HeadingEditor("headingeditor");
433 branchPropertyEditor = new BranchPropertyEditor();
435 // Initially read filenames of last session, before settings are
436 // overwritten during loading of maps
437 lastSessionFiles = settings.value("/mainwindow/sessionFileList", QStringList()).toStringList();
442 // Check for zip tools
446 #if defined(Q_OS_WINDOWS)
447 if (!zipToolAvailable || QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows10) {
448 QMessageBox::critical(
449 0, QObject::tr("Critical Error"),
450 QObject::tr("Couldn't find tool to unzip data,"
451 "or your Windows version is older than Windows 10."));
455 if (!zipToolAvailable || !unzipToolAvailable) {
456 QMessageBox::critical(
457 0, QObject::tr("Critical Error"),
458 QObject::tr("Couldn't find tool to zip/unzip data. "
459 "Please install on your platform and set"
460 "path in Settings menu:\n ",
461 "zip tool missing on Linux/Mac platform"));
466 m.setWindowIcon(QPixmap(":/vym.png"));
470 // Show debug info AFTER creating MainWindow
471 cout << debugInfo().toStdString() << endl;
473 if (options.isOn("commands")) {
474 cout << "Available commands in map:\n";
475 cout << "=========================:\n";
476 foreach (Command *c, modelCommands)
477 cout << c->getDescription().toStdString() << endl;
479 cout << "Available commands in vym:\n";
480 cout << "=========================:\n";
481 foreach (Command *c, vymCommands)
482 cout << c->getDescription().toStdString() << endl;
486 if (options.isOn("commandslatex")) {
487 foreach (Command *c, modelCommands)
488 cout << c->getDescriptionLaTeX().toStdString() << endl;
489 foreach (Command *c, vymCommands)
490 cout << c->getDescriptionLaTeX().toStdString() << endl;
494 if (options.isOn("batch"))
497 // Paint Mainwindow first time
498 qApp->processEvents();
502 // Show release notes and afterwards updates
503 m.checkReleaseNotesAndUpdates();
505 if (options.isOn("shortcuts"))
507 .printASCII(); // FIXME-3 global switchboard and exit after listing
511 // Restore last session
512 if (options.isOn("restore"))
513 m.fileRestoreSession();
516 if (options.isOn("load")) {
517 QString fn = options.getArg("load");
518 if (!scriptEditor->loadScript(fn)) {
519 QString error(QObject::tr("Error"));
520 QString msg(QObject::tr("Couldn't open \"%1\"\n.").arg(fn));
521 if (options.isOn("batch"))
522 qWarning() << error + ": " + msg;
524 QMessageBox::warning(0, error, msg);
530 if (options.isOn("run")) {
532 QString fn = options.getArg("run");
533 if (!scriptEditor->loadScript(fn)) {
534 QString error(QObject::tr("Error"));
535 QString msg(QObject::tr("Couldn't open \"%1\"\n.").arg(fn));
536 if (options.isOn("batch"))
537 qWarning() << error + ": " + msg;
539 QMessageBox::warning(0, error, msg);
542 m.runScript(scriptEditor->getScriptFile());
545 // For benchmarking we may want to quit instead of entering event loop
546 if (options.isOn("quit"))
549 // Enable some last minute cleanup
550 QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
557 int s = warningCount + criticalCount + fatalCount;
559 qDebug() << "vym exiting with:\n"
560 << warningCount << " warning messages\n"
561 << criticalCount << " critical messages\n"
562 << fatalCount << " fatal messages";