/* vi: set sw=4 ts=4: * * Copyright (C) 2001 - 2015 Christian Hohnstaedt. * * All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include "widgets/MainWindow.h" #include "widgets/OpenDb.h" #include "lib/func.h" #include "lib/db.h" #include "lib/main.h" #include "lib/entropy.h" #if defined(Q_OS_WIN32) //For the segfault handler #include #endif QLocale XCA_application::lang = QLocale::system(); QFont XCA_application::tableFont; QList XCA_application::langAvail; void XCA_application::setMainwin(MainWindow *m) { mainw = m; } bool XCA_application::languageAvailable(QLocale l) { return langAvail.contains(l); } static QString defaultlang() { return getUserSettingsDir() + QDir::separator() + "defaultlang"; } XCA_application::XCA_application(int &argc, char *argv[]) :QApplication(argc, argv) { qtTr = NULL; xcaTr = NULL; mainw = NULL; QFile file(defaultlang()); if (file.open(QIODevice::ReadOnly)) { lang = QLocale(QString(file.read(128))); } langAvail << QLocale::system(); langAvail << QString("en"); QDirIterator qmIt(getPrefix(), QStringList() << "*.qm", QDir::Files); while (qmIt.hasNext()) { XcaTranslator t; qmIt.next(); QString language = qmIt.fileInfo().baseName().mid(4, -1); if (t.load(language, "xca", getPrefix())) langAvail << QLocale(language); } setupLanguage(lang); #ifdef Q_OS_MAC QStringList libp = libraryPaths(); libp.prepend(applicationDirPath() + "/../Plugins"); setLibraryPaths(libp); #endif tableFont = QFont("Courier", QApplication::font().pointSize() #if defined (Q_OS_WIN32) +1 #else +2 #endif ); installEventFilter(this); } void XCA_application::setupLanguage(QLocale l) { QStringList dirs; lang = l; if (qtTr) { removeTranslator(qtTr); delete qtTr; } qtTr = new XcaTranslator(); if (xcaTr) { removeTranslator(xcaTr); delete xcaTr; } xcaTr = new XcaTranslator(); dirs #ifdef XCA_DEFAULT_QT_TRANSLATE << XCA_DEFAULT_QT_TRANSLATE #endif << getPrefix() #ifndef WIN32 #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) << "/usr/local/share/qt5/translations/" << "/usr/share/qt5/translations/" #else << "/usr/local/share/qt4/translations/" << "/usr/share/qt4/translations/" #endif << "/usr/share/qt/translations/" #endif ; foreach(QString dir, dirs) { if (qtTr->load(lang, "qt", dir)) { break; } } xcaTr->load(lang, "xca", getPrefix()); QLocale::setDefault(l); installTranslator(qtTr); installTranslator(xcaTr); if (mainw) mainw->initResolver(); } void XCA_application::quit() { if (mainw) mainw->close(); } void XCA_application::switchLanguage(QAction* a) { QLocale lang = a->data().toLocale(); setupLanguage(lang); if (portable_app()) return; QFile file(defaultlang()); if (lang == QLocale::system()) { file.remove(); return; } if (file.open(QIODevice::WriteOnly)) { file.write(lang.name().toUtf8()); } } bool XCA_application::eventFilter(QObject *watched, QEvent *ev) { static int mctr; QMouseEvent *me; QStringList l; XcaTreeView *treeview; int key; switch (ev->type()) { case QEvent::FileOpen: l << static_cast(ev)->file(); mainw->openURLs(l); return true; case QEvent::MouseMove: case QEvent::NonClientAreaMouseMove: if (mctr++ > 8) { me = static_cast(ev); entropy.add(me->globalX()); entropy.add(me->globalY()); mctr = 0; } break; case QEvent::KeyPress: key = static_cast(ev)->key(); if (key < 0x100) { entropy.add(key); } break; case QEvent::MouseButtonPress: me = static_cast(ev); treeview = watched ? dynamic_cast(watched->parent()) : NULL; if ((watched == mainw || treeview) && me->button() == Qt::MidButton && QApplication::clipboard()->supportsSelection()) { mainw->pastePem(); return true; } break; default: break; } return false; } bool XCA_application::notify(QObject* receiver, QEvent* event) { try { return QApplication::notify(receiver, event); } catch (errorEx &err) { mainw->Error(err); } catch (...) { qDebug() << QString("Event exception: ") << receiver << event; abort(); } return false; } XCA_application::~XCA_application() { } char segv_data[1024]; #if defined(Q_OS_WIN32) static LONG CALLBACK w32_segfault(LPEXCEPTION_POINTERS e) { if (e->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { if (segv_data[0]) { XCA_WARN(QString(segv_data)); abort(); } return EXCEPTION_CONTINUE_EXECUTION; } else return EXCEPTION_CONTINUE_SEARCH; } #else static void segv_handler_gui(int) { if (segv_data[0]) XCA_WARN(QString(segv_data)); abort(); } #endif #define CYAN "\x1b[0;36m" #define LRED "\x1b[0;92m" #define YELL "\x1b[0;33m" #define RED "\x1b[0;31m" #define RESET "\x1b[0m" void myMsgOutput(QtMsgType type, const char *msg) { static QTime *t; static int debug; if (!t) { char *d = getenv("XCA_DEBUG"); t = new QTime(); t->start(); if (d && *d) debug = 1; } int el = t->elapsed(); const char *severity = "Unknown"; switch (type) { case QtDebugMsg: if (!debug) return; severity = CYAN "Debug"; break; case QtWarningMsg: severity = LRED "Warning"; break; case QtCriticalMsg: severity = RED "Critical"; break; case QtFatalMsg: severity = RED "Fatal"; break; default: severity = CYAN "Default"; break; } fprintf(stderr, YELL "% 4d.%02d %s:" RESET " %s\n", el/1000, (el%1000)/100, severity, msg); } #if QT_VERSION >= 0x050000 void myMessageOutput(QtMsgType t, const QMessageLogContext &, const QString &m) { myMsgOutput(t, CCHAR(m)); } #endif #if DQT_VERSION >= 0x050000 case QtInfoMsg: severity = "Info"; break; #endif int main( int argc, char *argv[] ) { int ret = 0; MainWindow *mw; QDir d; #if defined(Q_OS_WIN32) SetUnhandledExceptionFilter(w32_segfault); #else signal(SIGSEGV, segv_handler_gui); #endif d.mkpath(getUserSettingsDir()); #if QT_VERSION < 0x050000 qInstallMsgHandler(myMsgOutput); #else qInstallMessageHandler(myMessageOutput); #endif XCA_application a(argc, argv); mw = new MainWindow(NULL); try { a.setMainwin(mw); OpenDb::checkSqLite(); mw->read_cmdline(argc, argv); if (mw->exitApp == 0) { mw->load_history(); if (mw->open_default_db() != 2) { mw->show(); ret = a.exec(); } } } catch (errorEx &ex) { mw->Error(ex); } delete mw; return ret; }