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