settingsdialog.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*****************************************************************************
  2. * settingsdialog.cpp - QStarDict, a StarDict clone written with using Qt *
  3. * Copyright (C) 2007 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 "settingsdialog.h"
  20. #include <QFileDialog>
  21. #include <QMessageBox>
  22. #include <QStandardItemModel>
  23. #include <QHeaderView>
  24. #include <QInputDialog>
  25. #include <QSettings>
  26. #include <math.h>
  27. #include "dictcore.h"
  28. #include "mainwindow.h"
  29. #include "popupwindow.h"
  30. #include "application.h"
  31. #include "speaker.h"
  32. #include "trayicon.h"
  33. namespace
  34. {
  35. int toPercents(double value)
  36. {
  37. int integralValue = static_cast<int>(value * 100.0);
  38. if (value * 100.0 - 0.5 > integralValue)
  39. ++integralValue;
  40. return integralValue;
  41. }
  42. }
  43. namespace QStarDict {
  44. SettingsDialog::SettingsDialog(QWidget *parent)
  45. : QDialog(parent)
  46. {
  47. setupUi(this);
  48. DictCore *dict = Application::instance()->dictCore();
  49. m_oldPlugins = dict->loadedPlugins();
  50. m_oldDicts = dict->loadedDicts();
  51. m_pluginsModel = new QStandardItemModel(this);
  52. m_pluginsModel->setHorizontalHeaderLabels(
  53. QStringList() << tr("Enabled") << tr("Name"));
  54. loadPluginsList();
  55. pluginsTableView->setModel(m_pluginsModel);
  56. pluginsTableView->verticalHeader()->hide();
  57. pluginsTableView->setColumnWidth(0, 60);
  58. pluginsTableView->setColumnWidth(1, 320);
  59. m_dictsModel = new QStandardItemModel(this);
  60. m_dictsModel->setHorizontalHeaderLabels(QStringList() << tr("Enabled") << tr("Name") << tr("Plugin"));
  61. loadDictsList();
  62. dictsTableView->setModel(m_dictsModel);
  63. dictsTableView->verticalHeader()->hide();
  64. dictsTableView->setColumnWidth(0, 60);
  65. dictsTableView->setColumnWidth(1, 200);
  66. dictsTableView->setColumnWidth(2, 120);
  67. // Load global settings
  68. systemTrayBox->setChecked(Application::instance()->trayIcon()->isVisible());
  69. instantSearchBox->setChecked(Application::instance()->mainWindow()->isInstantSearch());
  70. speechCmdEdit->setText(Application::instance()->speaker()->speechCmd());
  71. #ifdef Q_OS_LINUX
  72. QFile desktop(QDir::homePath() + "/.config/autostart/qstardict.desktop");
  73. if (desktop.open(QIODevice::ReadOnly) && QString(desktop.readAll())
  74. .contains(QRegExp("\\bhidden\\s*=\\s*false", Qt::CaseInsensitive))) {
  75. autostartBox->setChecked(true);
  76. }
  77. #elif defined(Q_OS_WIN)
  78. QSettings reg("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\"
  79. "CurrentVersion\\Run", QSettings::NativeFormat);
  80. autostartBox->setChecked(
  81. reg.contains(QCoreApplication::applicationName()));
  82. #else
  83. autostartBox->setVisible(false);
  84. #endif
  85. // Load popup window settings
  86. PopupWindow *popup = Application::instance()->popupWindow();
  87. useScanBox->setChecked(popup->isScan());
  88. if (popup->modifierKey())
  89. {
  90. useScanModifierBox->setChecked(true);
  91. QString modifierName;
  92. switch (popup->modifierKey())
  93. {
  94. case Qt::ShiftModifier:
  95. modifierName = "Shift";
  96. break;
  97. case Qt::ControlModifier:
  98. modifierName = "Control";
  99. break;
  100. case Qt::AltModifier:
  101. modifierName = "Alt";
  102. break;
  103. case Qt::MetaModifier:
  104. modifierName = "Win";
  105. break;
  106. }
  107. modifierKeyBox->setCurrentIndex(modifierKeyBox->findText(modifierName));
  108. }
  109. showIfNotFoundBox->setChecked(popup->showIfNotFound());
  110. popupOpacitySpin->setValue(toPercents(popup->windowOpacity()));
  111. timeoutBeforeHideSpin->setValue(popup->timeoutBeforeHide() / 1000.0);
  112. popupDefaultWidthSpin->setValue(popup->defaultSize().width());
  113. popupDefaultHeightSpin->setValue(popup->defaultSize().height());
  114. pronounceWordBox->setChecked(popup->pronounceWord());
  115. // Load translations CSS
  116. QHash<QString, QString> cssAliases;
  117. cssAliases["body"] = tr("All translation");
  118. cssAliases["font.dict_name"] = tr("Dictionary name");
  119. cssAliases["font.title"] = tr("Title");
  120. cssAliases["font.explanation"] = tr("Explanation");
  121. cssAliases["font.abbreviature"] = tr("Abbreviation");
  122. cssAliases["font.example"] = tr("Example");
  123. cssAliases["font.transcription"] = tr("Transcription");
  124. appearanceCSSEdit->setElementsAliases(cssAliases);
  125. appearanceCSSEdit->setCSS(Application::instance()->mainWindow()->defaultStyleSheet());
  126. connect(m_pluginsModel, SIGNAL(itemChanged(QStandardItem*)),
  127. SLOT(pluginsItemChanged(QStandardItem*)));
  128. }
  129. void SettingsDialog::accept()
  130. {
  131. // Save dicts and plugins settings
  132. DictCore *dict = Application::instance()->dictCore();
  133. QStringList loadedPlugins;
  134. int rowCount = m_pluginsModel->rowCount();
  135. for (int i = 0; i < rowCount; ++i)
  136. if (m_pluginsModel->item(i, 0)->checkState() == Qt::Checked)
  137. loadedPlugins << m_pluginsModel->item(i, 1)->text();
  138. dict->setLoadedPlugins(loadedPlugins);
  139. QList<DictCore::Dictionary> loadedDicts;
  140. rowCount = m_dictsModel->rowCount();
  141. for (int i = 0; i < rowCount; ++i)
  142. if (m_dictsModel->item(i, 0)->checkState() == Qt::Checked)
  143. loadedDicts << DictCore::Dictionary(m_dictsModel->item(i, 2)->text(), m_dictsModel->item(i, 1)->text());
  144. dict->setLoadedDicts(loadedDicts);
  145. // Save global settings
  146. Application::instance()->trayIcon()->setVisible(systemTrayBox->isChecked());
  147. Application::instance()->mainWindow()->setInstantSearch(instantSearchBox->isChecked());
  148. Application::instance()->speaker()->setSpeechCmd(speechCmdEdit->text());
  149. #ifdef Q_OS_LINUX
  150. QDir home = QDir::home();
  151. if (!home.exists(".config/autostart")) {
  152. home.mkpath(".config/autostart");
  153. }
  154. QFile desktopFile(QSTARDICT_INSTALL_PREFIX "/share/applications/qstardict.desktop");
  155. if (desktopFile.open(QIODevice::ReadOnly)) {
  156. QByteArray contents = desktopFile.readAll();
  157. QFile f(home.absolutePath() +
  158. "/.config/autostart/qstardict.desktop");
  159. if (f.open(QIODevice::WriteOnly | QIODevice::Text)) {
  160. f.write(contents.trimmed());
  161. f.write(QString("\nHidden=%1").arg(autostartBox->isChecked()?
  162. "false\n":"true\n").toUtf8());
  163. }
  164. }
  165. #elif defined(Q_OS_WIN)
  166. QSettings reg("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\"
  167. "CurrentVersion\\Run", QSettings::NativeFormat);
  168. if(autostartBox->isChecked())
  169. reg.setValue(QCoreApplication::applicationName(), '"' +
  170. QDir::toNativeSeparators(QCoreApplication::
  171. applicationFilePath()) + '"');
  172. else
  173. reg.remove(QCoreApplication::applicationName());
  174. #endif
  175. // Save popup window settings
  176. PopupWindow *popup = Application::instance()->popupWindow();
  177. popup->setScan(useScanBox->isChecked());
  178. int modifierKey = 0;
  179. if (useScanModifierBox->isChecked())
  180. {
  181. if (modifierKeyBox->currentText() == "Shift")
  182. modifierKey = Qt::ShiftModifier;
  183. else if (modifierKeyBox->currentText() == "Control")
  184. modifierKey = Qt::ControlModifier;
  185. else if (modifierKeyBox->currentText() == "Alt")
  186. modifierKey = Qt::AltModifier;
  187. else if (modifierKeyBox->currentText() == "Win")
  188. modifierKey = Qt::MetaModifier;
  189. }
  190. popup->setShowIfNotFound(showIfNotFoundBox->isChecked());
  191. popup->setModifierKey(modifierKey);
  192. popup->setWindowOpacity(popupOpacitySpin->value() / 100.0);
  193. popup->setTimeoutBeforeHide(static_cast<int>(timeoutBeforeHideSpin->value() * 1000.0));
  194. popup->setDefaultSize(QSize(popupDefaultWidthSpin->value(), popupDefaultHeightSpin->value()));
  195. popup->setPronounceWord(pronounceWordBox->isChecked());
  196. // Save translations CSS
  197. Application::instance()->mainWindow()->setDefaultStyleSheet(appearanceCSSEdit->css());
  198. Application::instance()->popupWindow()->setDefaultStyleSheet(appearanceCSSEdit->css());
  199. if (! Application::instance()->trayIcon()->isVisible())
  200. Application::instance()->mainWindow()->show();
  201. Application::instance()->mainWindow()->reload();
  202. Application::instance()->dictCore()->saveSettings();
  203. Application::instance()->mainWindow()->saveSettings();
  204. Application::instance()->trayIcon()->saveSettings();
  205. Application::instance()->popupWindow()->saveSettings();
  206. QDialog::accept();
  207. }
  208. void SettingsDialog::reject()
  209. {
  210. DictCore *dict = Application::instance()->dictCore();
  211. dict->setLoadedPlugins(m_oldPlugins);
  212. dict->setLoadedDicts(m_oldDicts);
  213. QDialog::reject();
  214. }
  215. void SettingsDialog::loadDictsList()
  216. {
  217. int i;
  218. QList<DictCore::Dictionary> loadedDicts = Application::instance()->dictCore()->loadedDicts();
  219. m_dictsModel->setRowCount(0);
  220. for (i = 0; i < loadedDicts.size(); ++i)
  221. {
  222. QStandardItem *item = new QStandardItem();
  223. item->setCheckable(true);
  224. item->setCheckState(Qt::Checked);
  225. m_dictsModel->setItem(i, 0, item);
  226. m_dictsModel->setItem(i, 1, new QStandardItem(loadedDicts[i].name()));
  227. m_dictsModel->setItem(i, 2, new QStandardItem(loadedDicts[i].plugin()));
  228. }
  229. QList<DictCore::Dictionary> dicts = Application::instance()->dictCore()->availableDicts();
  230. for (QList<DictCore::Dictionary>::const_iterator iter = dicts.begin(); iter != dicts.end(); ++iter)
  231. {
  232. if (! loadedDicts.contains(*iter))
  233. {
  234. QStandardItem *item = new QStandardItem();
  235. item->setCheckable(true);
  236. item->setCheckState(Qt::Unchecked);
  237. m_dictsModel->setItem(i, 0, item);
  238. m_dictsModel->setItem(i, 1, new QStandardItem(iter->name()));
  239. m_dictsModel->setItem(i, 2, new QStandardItem(iter->plugin()));
  240. ++i;
  241. }
  242. }
  243. }
  244. void SettingsDialog::loadPluginsList()
  245. {
  246. m_pluginsModel->setRowCount(0);
  247. DictCore *dict = Application::instance()->dictCore();
  248. QStringList plugins = dict->availablePlugins();
  249. QStringList loaded = dict->loadedPlugins();
  250. for (int i = 0; i < plugins.size(); ++i)
  251. {
  252. QStandardItem *item = new QStandardItem();
  253. item->setCheckable(true);
  254. item->setCheckState(loaded.contains(plugins[i]) ? Qt::Checked : Qt::Unchecked);
  255. m_pluginsModel->setItem(i, 0, item);
  256. m_pluginsModel->setItem(i, 1, new QStandardItem(plugins[i]));
  257. }
  258. }
  259. void SettingsDialog::on_dictsMoveUpButton_clicked()
  260. {
  261. int currentRow = dictsTableView->currentIndex().row();
  262. if (currentRow > 0)
  263. {
  264. m_dictsModel->insertRow(currentRow - 1, m_dictsModel->takeRow(currentRow));
  265. dictsTableView->selectRow(currentRow - 1);
  266. }
  267. }
  268. void SettingsDialog::on_dictsMoveDownButton_clicked()
  269. {
  270. int currentRow = dictsTableView->currentIndex().row();
  271. if (currentRow < m_dictsModel->rowCount() - 1)
  272. {
  273. m_dictsModel->insertRow(currentRow + 1, m_dictsModel->takeRow(currentRow));
  274. dictsTableView->selectRow(currentRow + 1);
  275. }
  276. }
  277. void SettingsDialog::on_dictsShowInfoButton_clicked()
  278. {
  279. int currentRow = dictsTableView->currentIndex().row();
  280. if (currentRow == -1)
  281. return;
  282. QString dict = m_dictsModel->item(currentRow, 1)->text();
  283. QString plugin = m_dictsModel->item(currentRow, 2)->text();
  284. DictPlugin::DictInfo info = Application::instance()->dictCore()->plugin(plugin)->dictInfo(dict);
  285. QMessageBox::information(this,
  286. tr("Information about dictionary \"%1\"").arg(dict),
  287. tr("<b>Name:</b> %1<br>").arg(dict) +
  288. tr("<b>Plugin:</b> %1<br>").arg(plugin) +
  289. tr("<b>Author:</b> %1<br>").arg(info.author()) +
  290. tr("<b>Words count:</b> %1<br>").arg((info.wordsCount() == -1) ? tr("unknown") : QString::number(info.wordsCount())) +
  291. tr("<b>Description:</b> %1").arg(info.description()));
  292. }
  293. void SettingsDialog::on_pluginsShowInfoButton_clicked()
  294. {
  295. int currentRow = pluginsTableView->currentIndex().row();
  296. if (currentRow == -1)
  297. return;
  298. DictPlugin *plugin = Application::instance()->dictCore()->plugin(m_pluginsModel->item(currentRow, 1)->text());
  299. if (! plugin)
  300. return;
  301. QMessageBox::information(this,
  302. tr("Information about %1 plugin").arg(plugin->name()),
  303. tr("<b>Name:</b> %1<br>").arg(plugin->name()) +
  304. tr("<b>Version:</b> %1<br>").arg(plugin->version()) +
  305. tr("<b>Authors:</b> %1<br>").arg(plugin->authors().replaceInStrings("<", "&lt;").replaceInStrings(">", "&gt;").join(tr("<br>"))) +
  306. tr("<b>Can search similar words:</b> %1<br>").arg(plugin->features().testFlag(DictPlugin::SearchSimilar) ? tr("yes") : tr("no")) +
  307. tr("<b>Description:</b> %1").arg(plugin->description()));
  308. }
  309. void SettingsDialog::on_pluginsConfigureButton_clicked()
  310. {
  311. int currentRow = pluginsTableView->currentIndex().row();
  312. if (currentRow == -1)
  313. return;
  314. DictCore *dict = Application::instance()->dictCore();
  315. DictPlugin *plugin = dict->plugin(m_pluginsModel->item(currentRow, 1)->text());
  316. if (plugin && plugin->execSettingsDialog(this) == QDialog::Accepted)
  317. {
  318. dict->reloadDicts();
  319. loadDictsList();
  320. }
  321. }
  322. void SettingsDialog::pluginsItemChanged(QStandardItem *item)
  323. {
  324. if (item->isCheckable())
  325. {
  326. DictCore *dict = Application::instance()->dictCore();
  327. QStringList loadedPlugins;
  328. int rowCount = m_pluginsModel->rowCount();
  329. for (int i = 0; i < rowCount; ++i)
  330. if (m_pluginsModel->item(i, 0)->checkState() == Qt::Checked)
  331. loadedPlugins << m_pluginsModel->item(i, 1)->text();
  332. dict->setLoadedPlugins(loadedPlugins);
  333. dict->reloadDicts();
  334. loadDictsList();
  335. }
  336. }
  337. }
  338. // vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab cindent textwidth=120 formatoptions=tc