main.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #include <QApplication>
  2. #include <QDebug>
  3. #include <QTextCodec>
  4. #include <QSslSocket>
  5. #include <QLocale>
  6. #include <QTranslator>
  7. #include <QScopedPointer>
  8. #include <QOpenGLContext>
  9. #include <QDateTime>
  10. #include <QSysInfo>
  11. #include <QProcess>
  12. #include <core/configmgr.h>
  13. #include <core/mainconfig.h>
  14. #include <core/coreconfig.h>
  15. #include <core/sessionconfig.h>
  16. #include <core/singleinstanceguard.h>
  17. #include <core/vnotex.h>
  18. #include <core/logger.h>
  19. #include <widgets/mainwindow.h>
  20. #include <QWebEngineSettings>
  21. #include <core/exception.h>
  22. #include <widgets/messageboxhelper.h>
  23. using namespace vnotex;
  24. void loadTranslators(QApplication &p_app);
  25. void initWebEngineSettings();
  26. int main(int argc, char *argv[])
  27. {
  28. SingleInstanceGuard guard;
  29. bool canRun = guard.tryRun();
  30. if (!canRun) {
  31. return 0;
  32. }
  33. QTextCodec *codec = QTextCodec::codecForName("UTF8");
  34. if (codec) {
  35. QTextCodec::setCodecForLocale(codec);
  36. }
  37. QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
  38. // This only takes effect on Win, X11 and Android.
  39. QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
  40. // Set OpenGL option on Windows.
  41. // Set environment QT_OPENGL to "angle/desktop/software".
  42. #if defined(Q_OS_WIN)
  43. {
  44. auto option = SessionConfig::getOpenGLAtBootstrap();
  45. qInfo() << "OpenGL option" << SessionConfig::openGLToString(option);
  46. switch (option) {
  47. case SessionConfig::OpenGL::Desktop:
  48. QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
  49. break;
  50. case SessionConfig::OpenGL::Angle:
  51. QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
  52. break;
  53. case SessionConfig::OpenGL::Software:
  54. QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
  55. break;
  56. default:
  57. break;
  58. }
  59. }
  60. #endif
  61. QApplication app(argc, argv);
  62. initWebEngineSettings();
  63. const QString iconPath = ":/vnotex/data/core/icons/vnote.ico";
  64. // Make sense only on Windows.
  65. app.setWindowIcon(QIcon(iconPath));
  66. app.setApplicationName(ConfigMgr::c_appName);
  67. app.setOrganizationName(ConfigMgr::c_orgName);
  68. try {
  69. app.setApplicationVersion(ConfigMgr::getInst().getConfig().getVersion());
  70. } catch (Exception &e) {
  71. MessageBoxHelper::notify(MessageBoxHelper::Critical,
  72. MainWindow::tr("%1 failed to start.").arg(ConfigMgr::c_appName),
  73. MainWindow::tr("Failed to initialize configuration manager. "
  74. "Please check if all the files are intact or reinstall the application."),
  75. e.what());
  76. return -1;
  77. }
  78. // Init logger after app info is set.
  79. Logger::init(false);
  80. qInfo() << QString("%1 (v%2) started at %3 (%4)").arg(ConfigMgr::c_appName,
  81. app.applicationVersion(),
  82. QDateTime::currentDateTime().toString(),
  83. QSysInfo::productType());
  84. qInfo() << "OpenSSL build version:" << QSslSocket::sslLibraryBuildVersionString()
  85. << "link version:" << QSslSocket::sslLibraryVersionString();
  86. if (QSslSocket::sslLibraryBuildVersionNumber() != QSslSocket::sslLibraryVersionNumber()) {
  87. qWarning() << "versions of the built and linked OpenSSL mismatch, network may not work";
  88. }
  89. // TODO: parse command line options.
  90. // Should set the correct locale before VNoteX::getInst().
  91. loadTranslators(app);
  92. if (app.styleSheet().isEmpty()) {
  93. auto style = VNoteX::getInst().getThemeMgr().fetchQtStyleSheet();
  94. if (!style.isEmpty()) {
  95. app.setStyleSheet(style);
  96. }
  97. }
  98. MainWindow window;
  99. window.show();
  100. VNoteX::getInst().getThemeMgr().setBaseBackground(window.palette().color(QPalette::Base));
  101. window.kickOffOnStart();
  102. int ret = app.exec();
  103. if (ret == RESTART_EXIT_CODE) {
  104. // Asked to restart VNote.
  105. guard.exit();
  106. QProcess::startDetached(QCoreApplication::applicationFilePath(), QStringList());
  107. // Must use exit() in Linux to quit the parent process in Qt 5.12.
  108. // Thanks to @ygcaicn.
  109. exit(0);
  110. return 0;
  111. }
  112. return ret;
  113. }
  114. void loadTranslators(QApplication &p_app)
  115. {
  116. auto localeName = ConfigMgr::getInst().getCoreConfig().getLocale();
  117. if (!localeName.isEmpty()) {
  118. QLocale::setDefault(QLocale(localeName));
  119. }
  120. QLocale locale;
  121. qInfo() << "locale:" << locale.name();
  122. const QString resourceTranslationFolder(QStringLiteral(":/vnotex/data/core/translations"));
  123. const QString envTranslationFolder(QStringLiteral("translations"));
  124. // For QTextEdit/QTextBrowser and other basic widgets.
  125. QScopedPointer<QTranslator> qtbaseTranslator(new QTranslator(&p_app));
  126. if (qtbaseTranslator->load(locale, "qtbase", "_", resourceTranslationFolder)) {
  127. p_app.installTranslator(qtbaseTranslator.take());
  128. }
  129. // qt_zh_CN.ts does not cover the real QDialogButtonBox which uses QPlatformTheme.
  130. QScopedPointer<QTranslator> dialogButtonBoxTranslator(new QTranslator(&p_app));
  131. if (dialogButtonBoxTranslator->load(locale, "qdialogbuttonbox", "_", resourceTranslationFolder)) {
  132. p_app.installTranslator(dialogButtonBoxTranslator.take());
  133. }
  134. QScopedPointer<QTranslator> webengineTranslator(new QTranslator(&p_app));
  135. if (webengineTranslator->load(locale, "qwebengine", "_", resourceTranslationFolder)) {
  136. p_app.installTranslator(webengineTranslator.take());
  137. }
  138. // Load translation for Qt from resource.
  139. QScopedPointer<QTranslator> qtTranslator(new QTranslator(&p_app));
  140. if (qtTranslator->load(locale, "qt", "_", resourceTranslationFolder)) {
  141. p_app.installTranslator(qtTranslator.take());
  142. }
  143. // Load translation for Qt from env.
  144. QScopedPointer<QTranslator> qtEnvTranslator(new QTranslator(&p_app));
  145. if (qtEnvTranslator->load(locale, "qt", "_", envTranslationFolder)) {
  146. p_app.installTranslator(qtEnvTranslator.take());
  147. }
  148. // Load translation for vnote from resource.
  149. QScopedPointer<QTranslator> vnoteTranslator(new QTranslator(&p_app));
  150. if (vnoteTranslator->load(locale, "vnote", "_", resourceTranslationFolder)) {
  151. p_app.installTranslator(vnoteTranslator.take());
  152. }
  153. // Load translation for vtextedit from resource.
  154. QScopedPointer<QTranslator> vtexteditTranslator(new QTranslator(&p_app));
  155. if (vtexteditTranslator->load(locale, "vtextedit", "_", resourceTranslationFolder)) {
  156. p_app.installTranslator(vtexteditTranslator.take());
  157. }
  158. }
  159. void initWebEngineSettings()
  160. {
  161. auto settings = QWebEngineSettings::defaultSettings();
  162. settings->setAttribute(QWebEngineSettings::LocalContentCanAccessRemoteUrls, true);
  163. }