#include <QApplication>
#include <QMessageBox>
#include <cstdlib>
#include <iostream>
using namespace std;
#include "command.h"
#include "findwidget.h"
#include "findresultwidget.h"
#include "flagrow.h"
#include "flagrowobj.h"
#include "headingeditor.h"
#include "macros.h"
#include "mainwindow.h"
#include "noteeditor.h"
#include "options.h"
#include "settings.h"
#include "scripteditor.h"
#include "scriptoutput.h"
#include "shortcuts.h"
#include "taskeditor.h"
#include "taskmodel.h"
#include "version.h"
#include "warningdialog.h"
#if defined(VYM_DBUS)
#include <sys/types.h> // To retrieve PID for use in DBUS
#endif
#if defined(Q_OS_WIN32)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define getpid GetCurrentProcessId
#else
#include <unistd.h>
#endif
#if defined(VYM_DBUS)
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusError>
#endif
QString vymName;
QString vymVersion;
QString vymCodeQuality;
QString vymHome;
QString vymBuildDate;
QString vymCodeName;
QString vymInstanceName;
QString vymPlatform;
QString localeName;
QTextStream vout(stdout); // vymout - Testing for now. Flush after writing...
QStringList jiraPrefixList; // List containing URLs of Jira systems
bool jiraClientAvailable; // collabzone specific currently
bool bugzillaClientAvailable; // openSUSE specific currently
TaskModel *taskModel;
TaskEditor *taskEditor;
ScriptEditor *scriptEditor;
ScriptOutput *scriptOutput;
HeadingEditor *headingEditor;
NoteEditor *noteEditor; // used in Constr. of LinkableMapObj
// initialized in mainwindow
Main *mainWindow; // used in BranchObj::select()
FindWidget *findWidget;
FindResultWidget *findResultWidget;
Macros macros;
uint itemLastID=0; // Unique ID for all items in all models
QString tmpVymDir; // All temp files go there, created in mainwindow
QString clipboardDir; // Clipboard used in all mapEditors
QString clipboardFile; // Clipboard used in all mapEditors
uint clipboardItemCount; // Number of items in clipboard
QDir vymBaseDir; // Containing all styles, scripts, images, ...
QDir lastImageDir;
QDir lastMapDir;
QDir lastExportDir;
#if defined(Q_OS_WIN32)
QDir vymInstallDir;
#endif
QString iconPath; // Pointing to icons used for toolbars
QString flagsPath; // Pointing to flags
bool debug; // global debugging flag
bool testmode; // Used to disable saving of autosave setting
bool recoveryMode = false; // Activated via command line switch and deactivated after initial loading of files
QStringList ignoredLockedFiles;
FlagRow *systemFlagsMaster;
FlagRow *standardFlagsMaster;
Switchboard switchboard;
Settings settings ("InSilmaril","vym"); // Organization, Application name
bool zipToolAvailable = false;
bool unzipToolAvailable = false;
QString zipToolPath; // Platform dependant zip tool
QString unzipToolPath; // For windows same as zipToolPath
QList <Command*> modelCommands;
QList <Command*> vymCommands;
Options options;
ImageIO imageIO;
int statusbarTime = 10000;
int warningCount = 0;
int criticalCount = 0;
int fatalCount = 0;
QString editorFocusStyle = QString(" border-color: #3daee9; border-style:outset; border-width:3px; color:black;");
#include <QScriptEngine>
QScriptValue scriptPrint( QScriptContext * ctx, QScriptEngine * eng );
void msgHandler (QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
switch (type)
{
case QtDebugMsg:
fprintf(stderr, "%s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
warningCount++;
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
criticalCount++;
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
fatalCount++;
break;
default:
fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
}
}
int main(int argc, char* argv[])
{
QApplication app(argc,argv);
// Define some constants shared in various places
vymName = __VYM_NAME;
vymVersion = __VYM_VERSION;
vymBuildDate = __VYM_BUILD_DATE;
vymCodeName = __VYM_CODENAME;
vymCodeQuality = __VYM_CODE_QUALITY;
vymHome = __VYM_HOME;
// Install our own handler for messages
qInstallMessageHandler(msgHandler);
// Testing for now
vout.setCodec("UTF-8");
// Reading and initializing options commandline options
options.add ("batch", Option::Switch, "b", "batch");
options.add ("commands", Option::Switch, "c", "commands");
options.add ("commandslatex", Option::Switch, "cl", "commandslatex");
options.add ("debug", Option::Switch, "d", "debug");
options.add ("help", Option::Switch, "h", "help");
options.add ("load", Option::String, "L", "load");
options.add ("local", Option::Switch, "l", "local");
options.add ("locale", Option::String, "locale", "locale");
options.add ("name", Option::String, "n", "name");
options.add ("quit", Option::Switch, "q", "quit");
options.add ("run", Option::String, "R", "run");
options.add ("recover", Option::Switch, "recover", "recover");
options.add ("restore", Option::Switch, "r", "restore");
options.add ("shortcuts", Option::Switch, "s", "shortcuts");
options.add ("shortcutsLaTeX", Option::Switch, "sl", "shortcutsLaTeX");
options.add ("testmode", Option::Switch, "t", "testmode");
options.add ("version", Option::Switch, "v","version");
options.setHelpText (
"VYM - View Your Mind\n"
"--------------------\n\n"
"Information about vym can be found in vym.pdf,\n"
"which should be part of the vym package.\n"
"It is also available at the project homepage:\n\n"
"http://www.InSilmaril.de/vym\n\n"
"Usage: vym [OPTION]... [FILE]... \n"
"Open FILEs with vym\n\n"
"-b batch batch mode: hide windows\n"
"-c commands List all available commands\n"
"-d debug Show debugging output\n"
"-h help Show this help text\n"
"-L load Load script\n"
"-l local Run with ressources in current directory\n"
"--locale locale Override system locale setting to select language\n"
"-n STRING name Set name of instance for DBus access\n"
"-q quit Quit immediatly after start for benchmarking\n"
"-R FILE run Run script\n"
"-r restore Restore last session\n"
"--recover recover Delete lockfiles during initial loading of files\n"
"-s shortcuts Show Keyboard shortcuts on start\n"
"--sl LaTeX Show Keyboard shortcuts in LaTeX format on start\n"
"-t testmode Test mode, e.g. no autosave and changing of its setting\n"
"-v version Show vym version\n"
);
if (options.parse())
{
cout << endl << qPrintable( options.getHelpText())<<endl;
return 1;
}
if (options.isOn ("version"))
{
cout << "VYM - View Your Mind (c) 2004-"<< QDate::currentDate().year()<<" Uwe Drechsel " << endl
<<" Version: "<<__VYM_VERSION <<endl
<<"Build date: "<<__VYM_BUILD_DATE << endl
<<" "<<__VYM_CODENAME<<endl;
return 0;
}
// Update some configurations, which were moved in 2.4.0
// This code should be removed later, e.g. in 2.6.0... // FIXME-2
QStringList settingsChanged;
settingsChanged << "readerURL"
<< "readerPDF"
<< "autosave/use"
<< "autosave/ms"
<< "writeBackupFile"
<< "printerName"
<< "printerFormat"
<< "printerFileName";
foreach (QString s, settingsChanged)
{
if (settings.contains("/mainwindow/" + s))
{
settings.setValue("/system/" + s, settings.value("/mainwindow/" + s));
settings.remove ("/mainwindow/" + s);
}
}
if (settings.contains( "/mainwindow/readerURL") )
settings.setValue( "/system/readerURL", settings.value( "/mainwindow/readerURL"));
taskModel = new TaskModel();
debug=options.isOn ("debug");
//debug=true;
testmode=options.isOn ("testmode");
QString pidString=QString ("%1").arg(getpid());
if (debug) qDebug()<< "vym PID="<<pidString;
#if defined(VYM_DBUS)
// Register for DBUS
QDBusConnection dbusConnection=QDBusConnection::sessionBus();
if (!dbusConnection.registerService ("org.insilmaril.vym-"+pidString))
{
fprintf(stderr, "%s\n",
qPrintable(QDBusConnection::sessionBus().lastError().message()));
exit(1);
}
#endif
if (options.isOn ("name"))
vymInstanceName=options.getArg ("name");
else
vymInstanceName=pidString;
bool debugBuild=false;
#ifdef QT_DEBUG
qDebug()<<"QT_DEBUG is set";
debugBuild=true;
#endif
// Use /usr/share/vym or /usr/local/share/vym or . ?
// First try options
if (options.isOn ("local") || debugBuild)
{
vymBaseDir.setPath (vymBaseDir.currentPath());
} else
// then look for environment variable
if (getenv("VYMHOME")!=0)
{
vymBaseDir.setPath (getenv("VYMHOME"));
} else
// ok, let's find my way on my own
{
#if defined (Q_OS_MACX)
// Executable is in vym.app/Contents/MacOS, so go up first:
vymBaseDir = QCoreApplication::applicationDirPath();
vymBaseDir.cdUp();
vymBaseDir.cd("Resources");
#elif defined (Q_OS_WIN32)
QString basePath;
wchar_t wbuf[512];
if (GetModuleFileName(NULL, wbuf, 512))
{
QString mfn(QString::fromWCharArray(wbuf));
mfn.replace('\\', '/');
int i=mfn.lastIndexOf('/');
if (i<0)
{
QMessageBox::critical(0,
"Error",
"Couldn't setup vymBasePath");
return 0;
}
if (mfn.right(mfn.length() -i -1) != "vym.exe")
{
QMessageBox::critical(0,
"Error",
"vym executable not known as vym.exe");
return 0;
}
basePath=mfn.left(i);
}
if (basePath.isEmpty())
basePath = vymBaseDir.currentPath();
vymInstallDir.setPath(basePath);
vymBaseDir.setPath(basePath);
#else
vymBaseDir.setPath ("/usr/share/vym");
if (!vymBaseDir.exists())
{
vymBaseDir.setPath ("/usr/local/share/vym");
if (!vymBaseDir.exists())
vymBaseDir.setPath(vymBaseDir.currentPath() );
}
#endif
}
// Platform specific settings
vymPlatform = QSysInfo::prettyProductName();
#if defined(Q_OS_WIN32)
zipToolPath = settings.value("/system/zipToolPath", "c:\\Program Files\\7-Zip\\7z.exe").toString();
#else
zipToolPath = "/usr/bin/zip";
unzipToolPath = "/usr/bin/unzip";
#endif
iconPath = vymBaseDir.path()+"/icons/";
flagsPath = vymBaseDir.path()+"/flags/";
// Some directories
QDir useDir;
if (options.isOn ("local"))
useDir = QDir().current();
else
useDir = QDir().home();
lastImageDir = useDir;
lastMapDir = useDir;
lastExportDir = useDir;
if (options.isOn ("help"))
{
cout << qPrintable (options.getHelpText())<<endl;
return 0;
}
// Initialize translations
if (options.isOn ("locale"))
{
localeName = options.getArg ("locale");
if (debug) qDebug() << "Main: using option for locale";
}
else
{
#if defined(Q_OS_LINUX)
if (debug) qDebug() << "Main: (OS Linux) using $LANG for locale";
localeName = QProcessEnvironment::systemEnvironment().value("LANG","en");
#else
if (debug) qDebug() << "Main: (OS other) using QLocale::system().uiLanguages( using for locale";
localeName = QLocale::system().uiLanguages().first();
if (localeName.contains("-"))
{
if (debug) qDebug() << "Main: Replacing '-' with '_' in locale";
localeName.replace( "-", "_");
}
#endif
}
if (debug)
{
qDebug() << "Main: localName: " << localeName;
qDebug() << "Main: translations: " << localeName, vymBaseDir.path() + "/lang";
qDebug() << "Main: uiLanguages: " << QLocale::system().uiLanguages();
qDebug() << "Main: LANG: " << QProcessEnvironment::systemEnvironment().value("LANG","foobar");
}
QTranslator vymTranslator;
if (!vymTranslator.load( QString("vym.%1").arg( localeName ), vymBaseDir.path() + "/lang") )
{
WarningDialog warn;
warn.showCancelButton (false);
warn.setText(QString( "Couldn't load translations for locale \"%1\" in\n%2")
.arg(localeName)
.arg(vymBaseDir.path() + "/lang") );
warn.setShowAgainName("mainwindow/loadTranslations");
}
app.installTranslator( &vymTranslator );
// Initializing the master rows of flags
systemFlagsMaster=new FlagRow;
systemFlagsMaster->setName ("systemFlagsMaster");
standardFlagsMaster=new FlagRow;
standardFlagsMaster->setName ("standardFlagsMaster");
// Initialize editors
noteEditor = new NoteEditor("noteeditor");
noteEditor->setWindowIcon (QPixmap (":/vym-editor.png"));
headingEditor = new HeadingEditor("headingeditor");
// Check if there is a JiraClient // FIXME-4 check for ruby
QFileInfo fi(vymBaseDir.path() + "/scripts/jigger");
jiraClientAvailable = fi.exists();
jiraPrefixList = settings.value("/system/jiraPrefixList").toStringList(); // FIXME-2 currently not used
// Check if there is a BugzillaClient // FIXME-4 check for ruby
fi.setFile( vymBaseDir.path() + "/scripts/bugger");
bugzillaClientAvailable = fi.exists();
// Initialize mainwindow
// Note: mainWindow pointer is set in constructor // FIXME-3 check this...
#if defined(Q_OS_WIN32)
Main m(0, Qt::Window | Qt::MSWindowsOwnDC);
#else
Main m;
#endif
// Check for zip tools
checkZipTool();
checkUnzipTool();
#if defined(Q_OS_WIN32)
if (!zipToolAvailable)
{
QMessageBox::critical( 0, QObject::tr( "Critical Error" ),
QObject::tr("Couldn't find tool to unzip data. "
"Please download and install 7z and set "
"path in Settings menu:\n ","zip tool missing on Win platform") +
"http://www.7-zip.org/");
m.settingsZipTool();
}
#else
if (!zipToolAvailable || !unzipToolAvailable)
{
QMessageBox::critical( 0, QObject::tr( "Critical Error" ),
QObject::tr("Couldn't find tool to zip/unzip data. "
"Please install on your platform and set"
"path in Settings menu:\n ","zip tool missing on Linux/Mac platform"));
m.settingsZipTool();
}
#endif
m.setWindowIcon (QPixmap (":/vym.png"));
m.fileNew();
if (options.isOn ("commands"))
{
cout << "Available commands:\n";
cout << "==================:\n";
foreach (Command* c, modelCommands)
cout << c->getDescription().toStdString() << endl;
foreach (Command* c, vymCommands)
cout << c->getDescription().toStdString() << endl;
return 0;
}
if (options.isOn ("commandslatex"))
{
foreach (Command* c, modelCommands)
cout << c->getDescriptionLaTeX().toStdString() << endl;
foreach (Command* c, vymCommands)
cout << c->getDescriptionLaTeX().toStdString() << endl;
return 0;
}
if (options.isOn ("batch"))
m.hide();
else
{
// Paint Mainwindow first time
qApp->processEvents();
m.show();
}
// Show release notes, if not already done
m.checkReleaseNotes();
// Check for updates
m.checkUpdates();
if (options.isOn("shortcuts")) switchboard.printASCII(); //FIXME-3 global switchboard and exit after listing
if (options.isOn ("recover"))
recoveryMode = true;
m.loadCmdLine();
// Restore last session
if (options.isOn ("restore"))
m.fileRestoreSession();
// By now all files should have been loaded
// Reset the restore flag and display message if needed
if (ignoredLockedFiles.count() > 0 )
{
QString msg (QObject::tr("Existing lockfiles have been ignored for the maps listed below. Please check, if the maps might be openend in another instance of vym.\n\n"));
QMessageBox::warning(0, QObject::tr("Warning"), msg + ignoredLockedFiles.join("\n"));
}
recoveryMode = false;
ignoredLockedFiles.clear();
// Load script
if (options.isOn ("load"))
{
QString fn = options.getArg ("load");
if (!scriptEditor->loadScript ( fn ) )
{
QString error (QObject::tr("Error"));
QString msg (QObject::tr("Couldn't open \"%1\"\n.").arg(fn));
if (options.isOn("batch"))
qWarning () << error + ": " + msg;
else QMessageBox::warning(0, error, msg);
return 0;
}
}
// Run script
if (options.isOn ("run"))
{
QString script;
QString fn = options.getArg ("run");
if (!scriptEditor->loadScript ( fn ) )
{
QString error (QObject::tr("Error"));
QString msg (QObject::tr("Couldn't open \"%1\"\n.").arg(fn));
if (options.isOn("batch"))
qWarning () << error + ": " + msg;
else QMessageBox::warning(0, error, msg);
return 0;
}
m.runScript (scriptEditor->getScriptFile() );
}
// For benchmarking we may want to quit instead of entering event loop
if (options.isOn ("quit")) return 0;
// Enable some last minute cleanup
QObject::connect( &app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()) );
app.exec();
// Cleanup
delete noteEditor;
int s = warningCount + criticalCount + fatalCount;
if ( s > 0 )
qDebug() << "vym exiting with:\n" <<
warningCount << " warning messages\n" <<
criticalCount<<" critical messages\n" <<
fatalCount<<" fatal messages";
return s;
}