application.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*****************************************************************************
  2. * application.cpp - QStarDict, a dictionary for learning foreign languages *
  3. * Copyright (C) 2008-2023 Alexander Rodin *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License along *
  16. * with this program; if not, write to the Free Software Foundation, Inc., *
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
  18. *****************************************************************************/
  19. #include "application.h"
  20. #include <QCommandLineParser>
  21. #include <QSettings>
  22. #ifdef QSTARDICT_WITH_TRANSLATIONS
  23. #include <QLibraryInfo>
  24. #include <QLocale>
  25. #include <QTranslator>
  26. #include <QStringList>
  27. #endif // QSTARDICT_WITH_TRANSLATIONS
  28. #include <QKeySequence>
  29. #include "qxt/qxtglobalshortcut.h"
  30. #include "dictcore.h"
  31. #include "mainwindow.h"
  32. #include "popupwindow.h"
  33. #include "speaker.h"
  34. #include "pluginmanager.h"
  35. #ifdef QSTARDICT_WITH_TRAY_ICON
  36. #include "trayicon.h"
  37. #endif
  38. #ifdef QSTARDICT_WITH_DBUS
  39. #include "dbusadaptor.h"
  40. #endif // QSTARDICT_WITH_DBUS
  41. #ifdef Q_OS_MAC
  42. #include <QDebug>
  43. #include <objc/objc.h>
  44. #include <objc/message.h>
  45. void setupDockClickHandler();
  46. bool dockClickHandler(id self,SEL _cmd,...);
  47. #endif
  48. #ifdef Q_OS_MAC
  49. void setupDockClickHandler() {
  50. Class cls = objc_getClass("NSApplication");
  51. typedef objc_object* (*SendType)(void*, SEL);
  52. SendType casted_objc_msgSend = (SendType)(objc_msgSend);
  53. objc_object *appInst = casted_objc_msgSend(cls, sel_registerName("sharedApplication"));
  54. if(appInst != NULL) {
  55. objc_object* delegate = casted_objc_msgSend(appInst, sel_registerName("delegate"));
  56. Class delClass = (Class)casted_objc_msgSend(delegate, sel_registerName("class"));
  57. SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
  58. if (class_getInstanceMethod(delClass, shouldHandle)) {
  59. if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "B@:"))
  60. qDebug() << "Registered dock click handler (replaced original method)";
  61. else
  62. qWarning() << "Failed to replace method for dock click handler";
  63. }
  64. else {
  65. if (class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"B@:"))
  66. qDebug() << "Registered dock click handler";
  67. else
  68. qWarning() << "Failed to register dock click handler";
  69. }
  70. }
  71. }
  72. bool dockClickHandler(id self,SEL _cmd,...) {
  73. Q_UNUSED(self)
  74. Q_UNUSED(_cmd)
  75. // Do something fun here!
  76. ((QStarDict::Application*)qApp)->mainWindow()->show();
  77. // Return NO (false) to suppress the default OS X actions
  78. return false;
  79. }
  80. #endif
  81. namespace QStarDict
  82. {
  83. Application::Application(int &argc, char **argv)
  84. : QApplication(argc, argv)
  85. {
  86. setOrganizationName("qstardict");
  87. setApplicationName("qstardict");
  88. QSettings settings;
  89. setApplicationVersion(QSTARDICT_VERSION);
  90. setQuitOnLastWindowClosed(false);
  91. #ifdef QSTARDICT_WITH_TRANSLATIONS
  92. m_translator = new QTranslator;
  93. #ifdef Q_WS_MAC
  94. QString binPath = QCoreApplication::applicationDirPath();
  95. // navigate through mac's bundle tree structore
  96. m_translator->load("qstardict-" + QLocale::system().name(), binPath + "/../i18n/");
  97. #else
  98. m_translator->load("qstardict-" + QLocale::system().name(), QSTARDICT_TRANSLATIONS_DIR);
  99. #endif
  100. installTranslator(m_translator);
  101. m_qtTranslator = new QTranslator;
  102. m_qtTranslator->load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
  103. installTranslator(m_qtTranslator);
  104. #endif // QSTARDICT_WITH_TRANSLATIONS
  105. QCommandLineParser parser;
  106. parser.setApplicationDescription(tr("A dictionary application for learning foreign languages"));
  107. parser.addHelpOption();
  108. parser.addVersionOption();
  109. QCommandLineOption backgroundOption({"b", "background"}, tr("Start in background mode."));
  110. parser.addOption(backgroundOption);
  111. parser.process(*this);
  112. m_pluginManager = new PluginManager;
  113. m_pluginManager->loadPlugins();
  114. m_dictCore = new DictCore;
  115. m_popupWindow = new PopupWindow;
  116. m_popupWindow->setDict(m_dictCore);
  117. m_speaker = new Speaker;
  118. m_speaker->setSpeechCmd(settings.value("Speaker/speechCmd", "espeak").toString());
  119. m_espeakSpeaker = new Speaker;
  120. m_espeakSpeaker->setSpeechCmd(settings.value("Speaker/espeakCmd", "espeak").toString());
  121. #ifdef QSTARDICT_WITH_TRAY_ICON
  122. m_trayIcon = new TrayIcon;
  123. #endif
  124. m_popupShortcut = new QxtGlobalShortcut;
  125. m_switchScanningShortcut = new QxtGlobalShortcut;
  126. m_mainWindow = new MainWindow(nullptr, parser.isSet(backgroundOption));
  127. m_mainWindow->setDict(m_dictCore);
  128. #ifdef QSTARDICT_WITH_DBUS
  129. m_dbusAdaptor = new DBusAdaptor(m_mainWindow);
  130. #endif // QSTARDICT_WITH_DBUS
  131. #ifdef Q_OS_MAC
  132. setupDockClickHandler();
  133. #endif
  134. }
  135. Application::~Application()
  136. {
  137. QSettings settings;
  138. #ifdef QSTARDICT_WITH_TRAY_ICON
  139. delete m_trayIcon;
  140. #endif
  141. delete m_mainWindow;
  142. delete m_popupWindow;
  143. settings.setValue("Speaker/speechCmd", m_speaker->speechCmd());
  144. delete m_speaker;
  145. settings.setValue("Speaker/espeakCmd", m_espeakSpeaker->speechCmd());
  146. delete m_espeakSpeaker;
  147. delete m_dictCore;
  148. delete m_popupShortcut;
  149. delete m_switchScanningShortcut;
  150. #ifdef QSTARDICT_WITH_TRANSLATIONS
  151. removeTranslator(m_translator);
  152. delete m_translator;
  153. removeTranslator(m_qtTranslator);
  154. delete m_qtTranslator;
  155. delete m_pluginManager;
  156. #endif // QSTARDICT_WITH_TRANSLATIONS
  157. }
  158. int Application::exec()
  159. {
  160. QString text = commandLineText();
  161. if (text != QString::null)
  162. m_mainWindow->showTranslation(text);
  163. return QApplication::exec();
  164. }
  165. QString Application::commandLineText()
  166. {
  167. QStringList args(arguments());
  168. for(int i = 1; i < args.count(); ++i)
  169. {
  170. if(! args.at(i).startsWith('-'))
  171. return args.at(i);
  172. }
  173. return QString::null;
  174. }
  175. }
  176. // vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab cindent textwidth=120 formatoptions=tc