1 /* ============================================================
2 * QuiteRSS is a open-source cross-platform RSS/Atom news feeds reader
3 * Copyright (C) 2011-2020 QuiteRSS Team <quiterssteam@gmail.com>
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 3 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
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 * ============================================================ */
18 #include "optionsdialog.h"
19 
20 #include "mainapplication.h"
21 #include "labeldialog.h"
22 #include "settings.h"
23 #include "VersionNo.h"
24 
OptionsDialog(QWidget * parent)25 OptionsDialog::OptionsDialog(QWidget *parent)
26   : Dialog(parent)
27   , notificationWidget_(NULL)
28 {
29   setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
30   setWindowTitle(tr("Options"));
31 
32   db_ = QSqlDatabase::database();
33 
34   contentLabel_ = new QLabel();
35   contentLabel_->setObjectName("contentLabel_");
36   contentLabel_->setAlignment(Qt::AlignCenter);
37   contentLabel_->setStyleSheet(
38         QString("#contentLabel_ {border-bottom: 1px solid %1;}").
39         arg(qApp->palette().color(QPalette::Dark).name()));
40   contentLabel_->setMinimumHeight(36);
41   contentLabel_->setMargin(4);
42   QFont fontContentLabel = contentLabel_->font();
43   fontContentLabel.setBold(true);
44   fontContentLabel.setPointSize(fontContentLabel.pointSize()+2);
45   contentLabel_->setFont(fontContentLabel);
46   mainLayout->insertWidget(0, contentLabel_);
47 
48   categoriesTree_ = new QTreeWidget();
49   categoriesTree_->setObjectName("categoriesTree");
50   categoriesTree_->setStyleSheet("QTreeWidget::item { min-height: 20px; }"
51                                  "QTreeWidget { padding: 1px; }");
52   categoriesTree_->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
53   categoriesTree_->setHeaderHidden(true);
54   categoriesTree_->setColumnCount(3);
55   categoriesTree_->setColumnHidden(0, true);
56   categoriesTree_->header()->setStretchLastSection(false);
57   categoriesTree_->header()->resizeSection(2, 5);
58 #ifdef HAVE_QT5
59   categoriesTree_->header()->setSectionResizeMode(1, QHeaderView::Stretch);
60 #else
61   categoriesTree_->header()->setResizeMode(1, QHeaderView::Stretch);
62 #endif
63   categoriesTree_->setMinimumWidth(150);
64   QStringList treeItem;
65   treeItem << "0" << tr("General");
66   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
67   treeItem.clear();
68   treeItem << "1" << tr("System Tray");
69   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
70   treeItem.clear();
71   treeItem << "2" << tr("Network Connections");
72   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
73   treeItem.clear();
74   treeItem << "3" << tr("Browser");
75   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
76   treeItem.clear();
77   treeItem << "4" << tr("Feeds");
78   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
79   treeItem.clear();
80   treeItem << "5" << tr("Labels");
81   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
82   treeItem.clear();
83   treeItem << "6" << tr("Notifications");
84   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
85   treeItem.clear();
86   treeItem << "7" << tr("Passwords");
87   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
88   treeItem.clear();
89   treeItem << "8" << tr("Language");
90   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
91   treeItem.clear();
92   treeItem << "9" << tr("Fonts & Colors");
93   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
94   treeItem.clear();
95   treeItem << "10" << tr("Keyboard Shortcuts");
96   categoriesTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
97 
98   createGeneralWidget();
99 
100   createTraySystemWidget();
101 
102   createNetworkConnectionsWidget();
103 
104   createBrowserWidget();
105 
106   createFeedsWidget();
107 
108   createLabelsWidget();
109 
110   createNotifierWidget();
111 
112   createPasswordsWidget();
113 
114   createLanguageWidget();
115 
116   createFontsColorsWidget();
117 
118   createShortcutWidget();
119 
120   contentStack_ = new QStackedWidget();
121   contentStack_->setObjectName("contentStack_");
122   contentStack_->addWidget(generalWidget_);
123   contentStack_->addWidget(traySystemWidget_);
124   contentStack_->addWidget(networkConnectionsWidget_);
125   contentStack_->addWidget(browserWidget_);
126   contentStack_->addWidget(feedsWidget_);
127   contentStack_->addWidget(labelsWidget_);
128   contentStack_->addWidget(notifierWidget_);
129   contentStack_->addWidget(passwordsWidget_);
130   contentStack_->addWidget(languageWidget_);
131   contentStack_->addWidget(fontsColorsWidget_);
132   contentStack_->addWidget(shortcutWidget_);
133 
134   scrollArea_ = new QScrollArea(this);
135   scrollArea_->setWidgetResizable(true);
136   scrollArea_->setFrameStyle(QFrame::NoFrame);
137   scrollArea_->setWidget(contentStack_);
138 
139   QSplitter *splitter = new QSplitter();
140   splitter->setChildrenCollapsible(false);
141   splitter->addWidget(categoriesTree_);
142   splitter->addWidget(scrollArea_);
143   QList<int> sizes;
144   sizes << 150 << 600;
145   splitter->setSizes(sizes);
146 
147   pageLayout->addWidget(splitter, 1);
148   pageLayout->setContentsMargins(10, 5, 10, 5);
149 
150   buttonBox->addButton(QDialogButtonBox::Ok);
151   buttonBox->addButton(QDialogButtonBox::Cancel);
152   connect(buttonBox, SIGNAL(accepted()), this, SLOT(acceptDialog()));
153   connect(this, SIGNAL(finished(int)), this, SLOT(closeDialog()));
154 
155   connect(categoriesTree_, SIGNAL(itemPressed(QTreeWidgetItem*,int)),
156           this, SLOT(slotCategoriesItemClicked(QTreeWidgetItem*,int)));
157   connect(this, SIGNAL(signalCategoriesTreeKeyUpDownPressed()),
158           SLOT(slotCategoriesTreeKeyUpDownPressed()), Qt::QueuedConnection);
159 
160   categoriesTree_->installEventFilter(this);
161 
162   setMinimumSize(500, 400);
163   resize(700, 580);
164 
165   Settings settings;
166   restoreGeometry(settings.value("options/geometry").toByteArray());
167 }
168 
showEvent(QShowEvent * event)169 void OptionsDialog::showEvent(QShowEvent*event)
170 {
171   int desktopWidth = QApplication::desktop()->availableGeometry().width();
172   int desktopHeight = QApplication::desktop()->availableGeometry().height();
173   int maxWidth = desktopWidth - (frameSize().width() - width());
174   int maxHeight = desktopHeight - (frameSize().height() - height());
175 
176   setMaximumSize(maxWidth, maxHeight);
177 
178   if (frameSize().height() >= desktopHeight) {
179     QPoint point = QPoint(QApplication::desktop()->availableGeometry().topLeft().x(),
180                           QApplication::desktop()->availableGeometry().topLeft().y());
181     move(point);
182   }
183 
184   Dialog::showEvent(event);
185 }
186 
acceptDialog()187 void OptionsDialog::acceptDialog()
188 {
189 #if defined(Q_OS_WIN)
190   if (mainApp->isPortableAppsCom()) {
191     if (autoRunEnabled_->isChecked()) {
192       QFileInfo file(QCoreApplication::applicationDirPath() % "/../../QuiteRSSPortable.exe");
193       autoRunSettings_->setValue("QuiteRSSPortable", QDir::toNativeSeparators(file.absoluteFilePath()));
194     } else {
195       autoRunSettings_->remove("QuiteRSSPortable");
196     }
197   } else {
198     if (autoRunEnabled_->isChecked())
199       autoRunSettings_->setValue("QuiteRSS", QDir::toNativeSeparators(QCoreApplication::applicationFilePath()));
200     else
201       autoRunSettings_->remove("QuiteRSS");
202   }
203 #endif
204 
205   applyProxy();
206   applyWhitelist();
207   applyLabels();
208   applyNotifier();
209   applyPass();
210   accept();
211 }
212 
closeDialog()213 void OptionsDialog::closeDialog()
214 {
215   Settings settings;
216   settings.setValue("options/geometry", saveGeometry());
217 }
218 
eventFilter(QObject * obj,QEvent * event)219 bool OptionsDialog::eventFilter(QObject *obj, QEvent *event)
220 {
221   if (event->type() == QEvent::KeyPress) {
222     QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
223     if (obj != editShortcut_) {
224       if ((keyEvent->key() == Qt::Key_Up) ||
225           (keyEvent->key() == Qt::Key_Down)) {
226         if (obj == categoriesTree_)
227           emit signalCategoriesTreeKeyUpDownPressed();
228         else if (obj == shortcutTree_)
229           emit signalShortcutTreeUpDownPressed();
230       }
231     } else {
232       if ((keyEvent->key() < Qt::Key_Shift) ||
233           (keyEvent->key() > Qt::Key_Alt)) {
234         QString str;
235         if ((keyEvent->modifiers() & Qt::ShiftModifier) ||
236             (keyEvent->modifiers() & Qt::ControlModifier) ||
237             (keyEvent->modifiers() & Qt::AltModifier))
238           str.append(QKeySequence(keyEvent->modifiers()).toString());
239         if (keyEvent->key() == Qt::Key_Backtab)
240           str.append(QKeySequence(Qt::Key_Tab).toString());
241         else
242           str.append(QKeySequence(keyEvent->key()).toString());
243         editShortcut_->setText(str);
244 
245         QModelIndex index = shortcutProxyModel_->mapToSource(shortcutTree_->currentIndex());
246         int row = index.row();
247         QString shortcutStr = shortcutModel_->item(row, 2)->text();
248         QList<QStandardItem *> treeItems;
249         treeItems = shortcutModel_->findItems(shortcutStr, Qt::MatchFixedString, 2);
250           if (!shortcutStr.isEmpty()) {
251             for (int i = 0; i < treeItems.count(); i++) {
252               if ((treeItems.count() == 2) || (treeItems.at(i)->row() == row)) {
253                 treeItems.at(i)->setData(shortcutModel_->item(0, 1)->data(Qt::TextColorRole),
254                                          Qt::TextColorRole);
255               }
256             }
257           }
258 
259         shortcutModel_->item(row, 2)->setText(str);
260         shortcutModel_->item(row, 2)->setData(str);
261 
262         if (!str.isEmpty()) {
263           treeItems = shortcutModel_->findItems(str, Qt::MatchFixedString, 2);
264           if (treeItems.count() > 1) {
265             for (int i = 0; i < treeItems.count(); i++) {
266               if (treeItems.at(i)->row() != row) {
267                 warningShortcut_->setText(tr("Warning: key is already assigned to") +
268                                           " '" +
269                                           shortcutModel_->item(treeItems.at(i)->row(), 0)->text()
270                                           + "'");
271               }
272               treeItems.at(i)->setData(QColor(Qt::red), Qt::TextColorRole);
273             }
274           } else {
275             warningShortcut_->clear();
276           }
277         }
278       }
279       return true;
280     }
281     return false;
282   } else {
283     return QDialog::eventFilter(obj, event);
284   }
285 }
286 
287 /** @brief Create windget "General"
288  *----------------------------------------------------------------------------*/
createGeneralWidget()289 void OptionsDialog::createGeneralWidget()
290 {
291   showSplashScreen_ = new QCheckBox(tr("Show splash screen on startup"));
292   reopenFeedStartup_ = new QCheckBox(tr("Reopen last opened feeds on startup"));
293   openNewTabNextToActive_ = new QCheckBox(tr("Open new tab next to active"));
294   hideFeedsOpenTab_ = new QCheckBox(tr("Hide feeds tree when opening tabs"));
295   showToggleFeedsTree_ = new QCheckBox(tr("Show feeds tree toggle"));
296   defaultIconFeeds_ = new QCheckBox(tr("Show default rss-icon instead of favourite one"));
297   autocollapseFolder_ = new QCheckBox(tr("Automatically collapse folders"));
298   showCloseButtonTab_ = new QCheckBox(tr("Show close button on tab"));
299 
300   updateCheckEnabled_ = new QCheckBox(tr("Automatically check for updates"));
301   statisticsEnabled_ = new QCheckBox(tr("Help improve QuiteRSS by sending usage information"));
302   storeDBMemory_ = new QCheckBox(tr("Store a DB in memory (requires program restart)"));
303   storeDBMemory_->setChecked(false);
304   saveDBMemFileInterval_ = new QSpinBox();
305   saveDBMemFileInterval_->setRange(1, 999);
306 
307   QHBoxLayout *saveDBMemFileLayout = new QHBoxLayout();
308   saveDBMemFileLayout->setContentsMargins(15, 0, 0, 0);
309   saveDBMemFileLayout->addWidget(new QLabel(tr("Save DB stored in memory to file every")));
310   saveDBMemFileLayout->addWidget(saveDBMemFileInterval_);
311   saveDBMemFileLayout->addWidget(new QLabel(tr("minutes")));
312   saveDBMemFileLayout->addStretch();
313 
314   QWidget *saveDBMemFileWidget = new QWidget();
315   saveDBMemFileWidget->setEnabled(false);
316   saveDBMemFileWidget->setLayout(saveDBMemFileLayout);
317 
318   connect(storeDBMemory_, SIGNAL(toggled(bool)),
319           saveDBMemFileWidget, SLOT(setEnabled(bool)));
320 
321   QVBoxLayout *generalLayout = new QVBoxLayout();
322   generalLayout->addWidget(showSplashScreen_);
323   generalLayout->addWidget(reopenFeedStartup_);
324   generalLayout->addWidget(openNewTabNextToActive_);
325   generalLayout->addWidget(hideFeedsOpenTab_);
326   generalLayout->addWidget(showToggleFeedsTree_);
327   generalLayout->addWidget(defaultIconFeeds_);
328   generalLayout->addWidget(autocollapseFolder_);
329   generalLayout->addWidget(showCloseButtonTab_);
330   generalLayout->addSpacing(20);
331 
332 #if defined(Q_OS_WIN)
333   autoRunEnabled_ = new QCheckBox(tr("Run QuiteRSS at Windows startup"));
334   autoRunSettings_ = new QSettings("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
335                                    QSettings::NativeFormat);
336   bool isAutoRun;
337   if (mainApp->isPortableAppsCom())
338     isAutoRun = autoRunSettings_->value("QuiteRSSPortable", false).toBool();
339   else
340     isAutoRun = autoRunSettings_->value("QuiteRSS", false).toBool();
341   autoRunEnabled_->setChecked(isAutoRun);
342 
343   generalLayout->addWidget(autoRunEnabled_);
344 #endif
345 
346   generalLayout->addWidget(updateCheckEnabled_);
347   generalLayout->addWidget(statisticsEnabled_);
348   generalLayout->addWidget(storeDBMemory_);
349   generalLayout->addWidget(saveDBMemFileWidget);
350   generalLayout->addStretch(1);
351 
352   generalWidget_ = new QFrame();
353   generalWidget_->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
354   generalWidget_->setLayout(generalLayout);
355 }
356 
357 /** @brief Create widget "System tray"
358  *----------------------------------------------------------------------------*/
createTraySystemWidget()359 void OptionsDialog::createTraySystemWidget()
360 {
361   showTrayIconBox_ = new QGroupBox(tr("Show system tray icon"));
362   showTrayIconBox_->setCheckable(true);
363 
364   startingTray_ = new QCheckBox(tr("starting QuiteRSS"));
365   minimizingTray_ = new QCheckBox(tr("minimizing QuiteRSS"));
366   closingTray_ = new QCheckBox(tr("closing QuiteRSS"));
367   QVBoxLayout *moveTrayLayout = new QVBoxLayout();
368   moveTrayLayout->setContentsMargins(15, 0, 5, 10);
369   moveTrayLayout->addWidget(startingTray_);
370   moveTrayLayout->addWidget(minimizingTray_);
371   moveTrayLayout->addWidget(closingTray_);
372 
373   staticIconTray_ = new QRadioButton(tr("Show static icon"));
374   changeIconTray_ = new QRadioButton(tr("Change icon for incoming new news"));
375   newCountTray_ = new QRadioButton(tr("Show count of new news"));
376   unreadCountTray_ = new QRadioButton(tr("Show count of unread news"));
377   QVBoxLayout *behaviorLayout = new QVBoxLayout();
378   behaviorLayout->setContentsMargins(15, 0, 5, 10);
379   behaviorLayout->addWidget(staticIconTray_);
380   behaviorLayout->addWidget(changeIconTray_);
381   behaviorLayout->addWidget(newCountTray_);
382   behaviorLayout->addWidget(unreadCountTray_);
383 
384   singleClickTray_ = new QCheckBox(
385         tr("Single click instead of double click for show window"));
386   clearStatusNew_ = new QCheckBox(tr("Clear new status when minimize to tray"));
387   emptyWorking_ = new QCheckBox(tr("Empty working set on minimize to tray"));
388 
389   QVBoxLayout *trayLayout = new QVBoxLayout(showTrayIconBox_);
390 #ifndef Q_OS_MAC
391   trayLayout->addWidget(new QLabel(tr("Move to the system tray when:")));
392   trayLayout->addLayout(moveTrayLayout);
393 #endif
394   trayLayout->addWidget(new QLabel(tr("Tray icon behavior:")));
395   trayLayout->addLayout(behaviorLayout);
396 #ifndef Q_OS_MAC
397   trayLayout->addWidget(singleClickTray_);
398   trayLayout->addWidget(clearStatusNew_);
399 #endif
400 #if defined(Q_OS_WIN)
401   trayLayout->addWidget(emptyWorking_);
402 #endif
403   trayLayout->addStretch(1);
404 
405   QVBoxLayout *boxTrayLayout = new QVBoxLayout();
406   boxTrayLayout->addWidget(showTrayIconBox_);
407 
408   traySystemWidget_ = new QFrame();
409   traySystemWidget_->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
410   traySystemWidget_->setLayout(boxTrayLayout);
411 }
412 
413 /** @brief Create widget "Network connections"
414  *----------------------------------------------------------------------------*/
createNetworkConnectionsWidget()415 void OptionsDialog::createNetworkConnectionsWidget()
416 {
417   directConnectionButton_ = new QRadioButton(
418         tr("Direct connection to the Internet"));
419   systemProxyButton_ = new QRadioButton(
420         tr("System proxy configuration (if available)"));
421   manualProxyButton_ = new QRadioButton(tr("Manual proxy configuration:"));
422 
423   QVBoxLayout *networkConnectionsLayout = new QVBoxLayout();
424   networkConnectionsLayout->addWidget(directConnectionButton_);
425   networkConnectionsLayout->addWidget(systemProxyButton_);
426   networkConnectionsLayout->addWidget(manualProxyButton_);
427 
428   typeProxy_ = new QComboBox();
429   typeProxy_->addItems(QStringList() << "HTTP" << "SOCKS5");
430   editHost_ = new LineEdit();
431   editPort_ = new LineEdit();
432   editPort_->setFixedWidth(60);
433   editUser_ = new LineEdit();
434   editPassword_ = new LineEdit();
435   editPassword_->setEchoMode(QLineEdit::Password);
436 
437   QHBoxLayout *addrPortLayout = new QHBoxLayout();
438   addrPortLayout->setMargin(0);
439   addrPortLayout->addWidget(typeProxy_);
440   addrPortLayout->addWidget(new QLabel(tr("Proxy server:")));
441   addrPortLayout->addWidget(editHost_);
442   addrPortLayout->addWidget(new QLabel(tr("Port:")));
443   addrPortLayout->addWidget(editPort_);
444 
445   QWidget *addrPortWidget = new QWidget();
446   addrPortWidget->setLayout(addrPortLayout);
447 
448   QHBoxLayout *userPasswordLayout = new QHBoxLayout();
449   userPasswordLayout->setMargin(0);
450   userPasswordLayout->addWidget(new QLabel(tr("Username:")));
451   userPasswordLayout->addWidget(editUser_);
452   userPasswordLayout->addWidget(new QLabel(tr("Password:")));
453   userPasswordLayout->addWidget(editPassword_);
454 
455   QWidget *userPasswordWidget = new QWidget();
456   userPasswordWidget->setLayout(userPasswordLayout);
457 
458   QVBoxLayout *manualLayout = new QVBoxLayout();
459   manualLayout->setMargin(0);
460   manualLayout->addWidget(addrPortWidget);
461   manualLayout->addWidget(userPasswordWidget);
462   manualLayout->addStretch();
463 
464   manualWidget_ = new QWidget();
465   manualWidget_->setEnabled(false);  // cause proper radio-button isn't set on creation
466   manualWidget_->setLayout(manualLayout);
467 
468   networkConnectionsLayout->addWidget(manualWidget_);
469   networkConnectionsLayout->addSpacing(20);
470 
471   timeoutRequest_ = new QSpinBox();
472   timeoutRequest_->setRange(0, 300);
473   numberRequests_ = new QSpinBox();
474   numberRequests_->setRange(1, 10);
475   numberRepeats_ = new QSpinBox();
476   numberRepeats_->setRange(1, 10);
477 
478   QGridLayout *requestLayout = new QGridLayout();
479   requestLayout->setColumnStretch(1, 1);
480   requestLayout->setContentsMargins(15, 0, 5, 0);
481   requestLayout->addWidget(new QLabel(tr("Request timeout:")), 0, 0);
482   requestLayout->addWidget(timeoutRequest_, 0, 1, 1, 1, Qt::AlignLeft);
483   requestLayout->addWidget(new QLabel(tr("Number of requests:")), 1, 0);
484   requestLayout->addWidget(numberRequests_, 1, 1, 1, 1, Qt::AlignLeft);
485   requestLayout->addWidget(new QLabel(tr("Number of retries:")), 2, 0);
486   requestLayout->addWidget(numberRepeats_, 2, 1, 1, 1, Qt::AlignLeft);
487 
488   networkConnectionsLayout->addWidget(new QLabel(tr("Options network requests when updating feeds (requires program restart):")));
489   networkConnectionsLayout->addLayout(requestLayout);
490   networkConnectionsLayout->addStretch(1);
491 
492   networkConnectionsWidget_ = new QFrame();
493   networkConnectionsWidget_->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
494   networkConnectionsWidget_->setLayout(networkConnectionsLayout);
495 
496   connect(manualProxyButton_, SIGNAL(toggled(bool)),
497           this, SLOT(manualProxyToggle(bool)));
498 }
499 
500 /** @brief Create widget "Browser"
501  *----------------------------------------------------------------------------*/
createBrowserWidget()502 void OptionsDialog::createBrowserWidget()
503 {
504   //! tab "General"
505   embeddedBrowserOn_ = new QRadioButton(tr("Use embedded browser"));
506   externalBrowserOn_ = new QRadioButton(tr("Use external browser"));
507   defaultExternalBrowserOn_ = new QRadioButton(tr("Default external browser"));
508   otherExternalBrowserOn_ = new QRadioButton(tr("Following external browser:"));
509 
510   otherExternalBrowserEdit_ = new LineEdit();
511   otherExternalBrowserButton_ = new QPushButton(tr("Browse..."));
512 
513   autoLoadImages_ = new QCheckBox(tr("Load images"));
514   javaScriptEnable_ = new QCheckBox(tr("Enable JavaScript"));
515   pluginsEnable_ = new QCheckBox(tr("Enable plug-ins"));
516   defaultZoomPages_ = new QSpinBox();
517   defaultZoomPages_->setMaximum(300);
518   defaultZoomPages_->setMinimum(30);
519   defaultZoomPages_->setSuffix(" %");
520 
521   openLinkInBackgroundEmbedded_ = new QCheckBox(tr("Open links in embedded browser in background"));
522   openLinkInBackground_ = new QCheckBox(tr("Open links in external browser in background (experimental)"));
523 
524   userStyleBrowserEdit_ = new LineEdit();
525   QPushButton *userStyleBrowserButton = new QPushButton(tr("Browse..."));
526   connect(userStyleBrowserButton, SIGNAL(clicked()),
527           this, SLOT(selectionUserStyleBrowser()));
528 
529   QGridLayout *browserSelectionLayout = new QGridLayout();
530   browserSelectionLayout->setContentsMargins(15, 0, 5, 10);
531   browserSelectionLayout->addWidget(embeddedBrowserOn_, 0, 0);
532   browserSelectionLayout->addWidget(externalBrowserOn_, 1, 0);
533   QButtonGroup *browserSelectionBox = new QButtonGroup();
534   browserSelectionBox->addButton(embeddedBrowserOn_);
535   browserSelectionBox->addButton(externalBrowserOn_);
536 
537   QGridLayout *externalBrowserLayout = new QGridLayout();
538   externalBrowserLayout->setContentsMargins(15, 0, 5, 10);
539   externalBrowserLayout->addWidget(defaultExternalBrowserOn_, 0, 0);
540   externalBrowserLayout->addWidget(otherExternalBrowserOn_, 1, 0);
541   externalBrowserLayout->addWidget(otherExternalBrowserEdit_, 2, 0);
542   externalBrowserLayout->addWidget(otherExternalBrowserButton_, 2, 1, Qt::AlignRight);
543   QButtonGroup *externalBrowserBox = new QButtonGroup();
544   externalBrowserBox->addButton(defaultExternalBrowserOn_);
545   externalBrowserBox->addButton(otherExternalBrowserOn_);
546 
547   QHBoxLayout *zoomLayout = new QHBoxLayout();
548   zoomLayout->addWidget(new QLabel(tr("Default zoom on pages:")));
549   zoomLayout->addWidget(defaultZoomPages_);
550   zoomLayout->addStretch();
551 
552   QVBoxLayout *contentBrowserLayout = new QVBoxLayout();
553   contentBrowserLayout->setContentsMargins(15, 0, 5, 10);
554   contentBrowserLayout->addWidget(autoLoadImages_);
555   contentBrowserLayout->addWidget(javaScriptEnable_);
556   contentBrowserLayout->addWidget(pluginsEnable_);
557   contentBrowserLayout->addLayout(zoomLayout);
558 
559   QGridLayout *userStyleBrowserLayout = new QGridLayout();
560   userStyleBrowserLayout->setContentsMargins(15, 0, 5, 10);
561   userStyleBrowserLayout->addWidget(userStyleBrowserEdit_, 0, 0);
562   userStyleBrowserLayout->addWidget(userStyleBrowserButton, 0, 1, Qt::AlignRight);
563 
564   QVBoxLayout *browserLayoutV = new QVBoxLayout();
565   browserLayoutV->setMargin(10);
566   browserLayoutV->addWidget(new QLabel(tr("Browser selection:")));
567   browserLayoutV->addLayout(browserSelectionLayout);
568   browserLayoutV->addWidget(new QLabel(tr("External browser:")));
569   browserLayoutV->addLayout(externalBrowserLayout);
570   browserLayoutV->addWidget(new QLabel(tr("Content:")));
571   browserLayoutV->addLayout(contentBrowserLayout);
572   browserLayoutV->addWidget(new QLabel(tr("User style sheet:")));
573   browserLayoutV->addLayout(userStyleBrowserLayout);
574   browserLayoutV->addWidget(openLinkInBackgroundEmbedded_);
575   browserLayoutV->addWidget(openLinkInBackground_);
576   browserLayoutV->addStretch();
577 
578   QWidget *generalBrowserWidget = new QWidget();
579   generalBrowserWidget->setLayout(browserLayoutV);
580 
581   connect(otherExternalBrowserOn_, SIGNAL(toggled(bool)),
582           otherExternalBrowserEdit_, SLOT(setEnabled(bool)));
583   connect(otherExternalBrowserOn_, SIGNAL(toggled(bool)),
584           otherExternalBrowserButton_, SLOT(setEnabled(bool)));
585   otherExternalBrowserOn_->setChecked(true);
586 
587   connect(otherExternalBrowserButton_, SIGNAL(clicked()),
588           this, SLOT(selectionBrowser()));
589 
590 #if defined(Q_OS_OS2)
591   otherExternalBrowserOn_->setVisible(false);
592   otherExternalBrowserEdit_->setVisible(false);
593   otherExternalBrowserButton_->setVisible(false);
594 #endif
595 
596   //! tab "History"
597   maxPagesInCache_ = new QSpinBox();
598   maxPagesInCache_->setRange(0, 20);
599 
600   QHBoxLayout *historyLayout1 = new QHBoxLayout();
601   historyLayout1->addWidget(new QLabel(tr("Maximum pages in cache")));
602   historyLayout1->addWidget(maxPagesInCache_);
603   historyLayout1->addStretch();
604 
605   dirDiskCacheEdit_ = new LineEdit();
606   dirDiskCacheButton_ = new QPushButton(tr("Browse..."));
607 
608   connect(dirDiskCacheButton_, SIGNAL(clicked()),
609           this, SLOT(selectionDirDiskCache()));
610 
611   QHBoxLayout *historyLayout2 = new QHBoxLayout();
612   historyLayout2->addWidget(new QLabel(tr("Store cache in:")));
613   historyLayout2->addWidget(dirDiskCacheEdit_, 1);
614   historyLayout2->addWidget(dirDiskCacheButton_);
615 
616   maxDiskCache_ = new QSpinBox();
617   maxDiskCache_->setRange(10, 300);
618 
619   QHBoxLayout *historyLayout3 = new QHBoxLayout();
620   historyLayout3->addWidget(new QLabel(tr("Maximum size of disk cache")));
621   historyLayout3->addWidget(maxDiskCache_);
622   historyLayout3->addWidget(new QLabel(tr("MB")), 1);
623 
624   QVBoxLayout *historyLayout4 = new QVBoxLayout();
625   historyLayout4->addLayout(historyLayout2);
626   historyLayout4->addLayout(historyLayout3);
627 
628   diskCacheOn_ = new QGroupBox(tr("Use disk cache"));
629   diskCacheOn_->setCheckable(true);
630   diskCacheOn_->setChecked(false);
631   diskCacheOn_->setLayout(historyLayout4);
632 
633   saveCookies_ = new QRadioButton(tr("Allow local data to be set"));
634   deleteCookiesOnClose_ = new QRadioButton(tr("Keep local data only until quit application"));
635   blockCookies_ = new QRadioButton(tr("Block sites from setting any data"));
636   clearCookies_ = new QPushButton(tr("Clear"));
637   connect(clearCookies_, SIGNAL(clicked()), mainApp->cookieJar(), SLOT(clearCookies()));
638 
639   QGridLayout *cookiesLayout = new QGridLayout();
640   cookiesLayout->setContentsMargins(15, 0, 5, 10);
641   cookiesLayout->addWidget(saveCookies_, 0, 0);
642   cookiesLayout->addWidget(deleteCookiesOnClose_, 1, 0);
643   cookiesLayout->addWidget(blockCookies_, 2, 0);
644   cookiesLayout->addWidget(clearCookies_, 3, 0, Qt::AlignLeft);
645   QButtonGroup *cookiesBox = new QButtonGroup();
646   cookiesBox->addButton(saveCookies_);
647   cookiesBox->addButton(deleteCookiesOnClose_);
648   cookiesBox->addButton(blockCookies_);
649 
650   QVBoxLayout *historyMainLayout = new QVBoxLayout();
651   historyMainLayout->setMargin(10);
652   historyMainLayout->addLayout(historyLayout1);
653   historyMainLayout->addWidget(diskCacheOn_);
654   historyMainLayout->addSpacing(10);
655   historyMainLayout->addWidget(new QLabel(tr("Cookies:")));
656   historyMainLayout->addLayout(cookiesLayout);
657   historyMainLayout->addStretch();
658 
659   QWidget *historyBrowserWidget_ = new QWidget();
660   historyBrowserWidget_->setLayout(historyMainLayout);
661 
662 
663   //! tab "Click to Flash"
664   QLabel *c2fInfo = new QLabel(tr("Click To Flash is a plugin which blocks auto loading of "
665                                  "Flash content at page. You can always load it manually "
666                                  "by clicking on the Flash play icon."));
667   c2fInfo->setWordWrap(true);
668 
669   c2fEnabled_ = new QCheckBox(tr("Use Click to Flash"));
670   c2fEnabled_->setChecked(false);
671 
672   c2fWhitelist_ = new QTreeWidget(this);
673   c2fWhitelist_->setObjectName("c2fWhiteList_");
674   c2fWhitelist_->setRootIsDecorated(false);
675   c2fWhitelist_->setColumnCount(1);
676 
677   QStringList treeItem;
678   treeItem << "Whitelist";
679   c2fWhitelist_->setHeaderLabels(treeItem);
680 
681   QPushButton *addButton = new QPushButton(tr("Add..."), this);
682   connect(addButton, SIGNAL(clicked()), this, SLOT(addWhitelist()));
683   QPushButton *removeButton = new QPushButton(tr("Remove..."), this);
684   connect(removeButton, SIGNAL(clicked()), this, SLOT(removeWhitelist()));
685 
686   QVBoxLayout *click2FlashLayout1 = new QVBoxLayout();
687   click2FlashLayout1->addWidget(addButton);
688   click2FlashLayout1->addWidget(removeButton);
689   click2FlashLayout1->addStretch(1);
690 
691   QHBoxLayout *click2FlashLayout2 = new QHBoxLayout();
692   click2FlashLayout2->setMargin(0);
693   click2FlashLayout2->addWidget(c2fWhitelist_, 1);
694   click2FlashLayout2->addLayout(click2FlashLayout1);
695 
696   QWidget *c2fWhitelistWidget = new QWidget(this);
697   c2fWhitelistWidget->setLayout(click2FlashLayout2);
698   c2fWhitelistWidget->setEnabled(false);
699 
700   connect(c2fEnabled_, SIGNAL(toggled(bool)),
701           c2fWhitelistWidget, SLOT(setEnabled(bool)));
702 
703   QVBoxLayout *click2FlashLayout = new QVBoxLayout();
704   click2FlashLayout->setMargin(10);
705   click2FlashLayout->addWidget(c2fInfo);
706   click2FlashLayout->addWidget(c2fEnabled_);
707   click2FlashLayout->addWidget(c2fWhitelistWidget, 1);
708 
709   QWidget *click2FlashWidget_ = new QWidget(this);
710   click2FlashWidget_->setLayout(click2FlashLayout);
711 
712   c2fEnabled_->setChecked(mainApp->c2fIsEnabled());
713   foreach(const QString & site, mainApp->c2fGetWhitelist()) {
714     QTreeWidgetItem* item = new QTreeWidgetItem(c2fWhitelist_);
715     item->setText(0, site);
716   }
717 
718   //! tab "Downloads"
719   downloadLocationEdit_ = new LineEdit();
720   QPushButton *downloadLocationButton = new QPushButton(tr("Browse..."));
721   connect(downloadLocationButton, SIGNAL(clicked()),
722           this, SLOT(selectionDownloadLocation()));
723 
724   askDownloadLocation_ = new QCheckBox(tr("Ask where to save each file before downloading"));
725 
726   QGridLayout *downLocationLayout = new QGridLayout();
727   downLocationLayout->setContentsMargins(15, 0, 5, 10);
728   downLocationLayout->addWidget(downloadLocationEdit_, 0, 0);
729   downLocationLayout->addWidget(downloadLocationButton, 0, 1, Qt::AlignRight);
730   downLocationLayout->addWidget(askDownloadLocation_, 1, 0);
731 
732   QVBoxLayout *downloadsLayout = new QVBoxLayout();
733   downloadsLayout->setMargin(10);
734   downloadsLayout->addWidget(new QLabel(tr("Download location:")));
735   downloadsLayout->addLayout(downLocationLayout);
736   downloadsLayout->addStretch();
737 
738   QWidget *downloadsWidget = new QWidget(this);
739   downloadsWidget->setLayout(downloadsLayout);
740 
741   browserWidget_ = new QTabWidget();
742   browserWidget_->addTab(generalBrowserWidget, tr("General"));
743   browserWidget_->addTab(historyBrowserWidget_, tr("History"));
744 #if QT_VERSION < 0x050900
745   browserWidget_->addTab(click2FlashWidget_, tr("Click to Flash"));
746 #endif
747   browserWidget_->addTab(downloadsWidget, tr("Downloads"));
748 }
749 
750 /** @brief Create windet "Feeds"
751  *----------------------------------------------------------------------------*/
createFeedsWidget()752 void OptionsDialog::createFeedsWidget()
753 {
754 //! tab "General"
755   updateFeedsStartUp_ = new QCheckBox(
756         tr("Automatically update the feeds on startup"));
757   updateFeedsEnable_ = new QCheckBox(tr("Automatically update the feeds every"));
758   updateFeedsInterval_ = new QSpinBox();
759   updateFeedsInterval_->setEnabled(false);
760   updateFeedsInterval_->setRange(1, 9999);
761   connect(updateFeedsEnable_, SIGNAL(toggled(bool)),
762           updateFeedsInterval_, SLOT(setEnabled(bool)));
763 
764   updateIntervalType_ = new QComboBox(this);
765   updateIntervalType_->setEnabled(false);
766   QStringList intervalList;
767   intervalList << tr("seconds") << tr("minutes")  << tr("hours");
768   updateIntervalType_->addItems(intervalList);
769   connect(updateFeedsEnable_, SIGNAL(toggled(bool)),
770           updateIntervalType_, SLOT(setEnabled(bool)));
771 
772   QHBoxLayout *updateFeedsLayout = new QHBoxLayout();
773   updateFeedsLayout->setMargin(0);
774   updateFeedsLayout->addWidget(updateFeedsEnable_);
775   updateFeedsLayout->addWidget(updateFeedsInterval_);
776   updateFeedsLayout->addWidget(updateIntervalType_);
777   updateFeedsLayout->addStretch();
778 
779   positionLastNews_ = new QRadioButton(tr("Set focus on the last opened news"));
780   positionFirstNews_ = new QRadioButton(tr("Set focus at the top of news list"));
781   positionUnreadNews_ = new QRadioButton(tr("Set focus on the unread news"));
782   openNewsWebViewOn_ = new QCheckBox(tr("Open the news"));
783   nottoOpenNews_ = new QRadioButton(tr("Nothing to do"));
784   connect(nottoOpenNews_, SIGNAL(toggled(bool)),
785           openNewsWebViewOn_, SLOT(setDisabled(bool)));
786 
787   QGridLayout *openingFeedsLayout = new QGridLayout();
788   openingFeedsLayout->setContentsMargins(15, 0, 0, 10);
789   openingFeedsLayout->setColumnStretch(1, 1);
790   openingFeedsLayout->addWidget(positionLastNews_, 0, 0, 1, 1);
791   openingFeedsLayout->addWidget(openNewsWebViewOn_, 0, 1, 1, 1);
792   openingFeedsLayout->addWidget(positionFirstNews_, 1, 0, 1, 1);
793   openingFeedsLayout->addWidget(positionUnreadNews_, 2, 0, 1, 1);
794   openingFeedsLayout->addWidget(nottoOpenNews_, 3, 0, 1, 1);
795 
796   markIdenticalNewsRead_ = new QCheckBox(tr("Automatically mark identical news as read"));
797 
798   avoidedOldNewsDate_ = new QCalendarWidget();
799   avoidedOldNewsDate_->setSelectedDate(QDate::currentDate());
800   avoidedOldNewsDate_->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
801   avoidedOldNewsDate_->setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames);
802   QHBoxLayout *avoidedOldNewsDateLayout = new QHBoxLayout();
803   avoidedOldNewsDateLayout->setMargin(5);
804   avoidedOldNewsDateLayout->addWidget(avoidedOldNewsDate_);
805   avoidedOldNewsDateLayout->addStretch();
806 
807   avoidedOldNewsDateOn_ = new QGroupBox(tr("Avoid adding news before this date into the database:"));
808   avoidedOldNewsDateOn_->setCheckable(true);
809   avoidedOldNewsDateOn_->setChecked(false);
810   avoidedOldNewsDateOn_->setLayout(avoidedOldNewsDateLayout);
811 
812   QVBoxLayout *generalFeedsLayout = new QVBoxLayout();
813   generalFeedsLayout->addWidget(updateFeedsStartUp_);
814   generalFeedsLayout->addLayout(updateFeedsLayout);
815   generalFeedsLayout->addSpacing(10);
816   generalFeedsLayout->addWidget(new QLabel(tr("Action on feed opening:")));
817   generalFeedsLayout->addLayout(openingFeedsLayout);
818   generalFeedsLayout->addWidget(markIdenticalNewsRead_);
819   generalFeedsLayout->addSpacing(15);
820   generalFeedsLayout->addWidget(avoidedOldNewsDateOn_);
821   generalFeedsLayout->addStretch();
822 
823   QWidget *generalFeedsWidget = new QWidget();
824   generalFeedsWidget->setLayout(generalFeedsLayout);
825 
826 
827   //! tab "Display"
828   QStringList itemList;
829   itemList << "31.12.99" << "31.12.1999"
830            << QString("31. %1. 1999").arg(tr("Dec"))
831            << QString("31. %1 1999").arg(tr("December"))
832            << "99-12-31" << "1999-12-31" << "12/31/1999";
833   formatDate_ = new QComboBox(this);
834   formatDate_->addItems(itemList);
835   formatDate_->setItemData(0, "dd.MM.yy");
836   formatDate_->setItemData(1, "dd.MM.yyyy");
837   formatDate_->setItemData(2, "dd. MMM. yyyy");
838   formatDate_->setItemData(3, "dd. MMMM yyyy");
839   formatDate_->setItemData(4, "yy-MM-dd");
840   formatDate_->setItemData(5, "yyyy-MM-dd");
841   formatDate_->setItemData(6, "MM/dd/yyyy");
842 
843   itemList.clear();
844   itemList << "13:37"  << "13:37:09" << "01:37 PM"<< "01:37:09 PM";
845   formatTime_ = new QComboBox(this);
846   formatTime_->addItems(itemList);
847   formatTime_->setItemData(0, "hh:mm");
848   formatTime_->setItemData(1, "hh:mm:ss");
849   formatTime_->setItemData(2, "hh:mm AP");
850   formatTime_->setItemData(3, "hh:mm:ss AP");
851 
852   QHBoxLayout *formatDateLayout = new QHBoxLayout();
853   formatDateLayout->setMargin(0);
854   formatDateLayout->addWidget(new QLabel(tr("Display format for date:")));
855   formatDateLayout->addWidget(formatDate_);
856   formatDateLayout->addSpacing(10);
857   formatDateLayout->addWidget(new QLabel(tr("time:")));
858   formatDateLayout->addWidget(formatTime_);
859   formatDateLayout->addStretch();
860 
861   alternatingRowColorsNews_ = new QCheckBox(tr("Alternating row background colors"));
862   simplifiedDateTime_ = new QCheckBox(tr("Simplified representation of date and time"));
863 
864   itemList.clear();
865   itemList << tr("Show All")  << tr("Show New") << tr("Show Unread")
866            << tr("Show Starred") << tr("Show Not Starred")
867            << tr("Show Unread or Starred") << tr("Show Last Day")
868            << tr("Show Last 7 Days");
869   mainNewsFilter_ = new QComboBox(this);
870   mainNewsFilter_->addItems(itemList);
871   mainNewsFilter_->setItemData(0, "filterNewsAll_");
872   mainNewsFilter_->setItemData(1, "filterNewsNew_");
873   mainNewsFilter_->setItemData(2, "filterNewsUnread_");
874   mainNewsFilter_->setItemData(3, "filterNewsStar_");
875   mainNewsFilter_->setItemData(4, "filterNewsNotStarred_");
876   mainNewsFilter_->setItemData(5, "filterNewsUnreadStar_");
877   mainNewsFilter_->setItemData(6, "filterNewsLastDay_");
878   mainNewsFilter_->setItemData(7, "filterNewsLastWeek_");
879 
880   QHBoxLayout *mainNewsFilterLayout = new QHBoxLayout();
881   mainNewsFilterLayout->setMargin(0);
882   mainNewsFilterLayout->addWidget(new QLabel(tr("Default news filter:")));
883   mainNewsFilterLayout->addWidget(mainNewsFilter_);
884   mainNewsFilterLayout->addStretch();
885 
886   styleSheetNewsEdit_ = new LineEdit();
887   QPushButton *styleSheetNewsButton = new QPushButton(tr("Browse..."));
888   connect(styleSheetNewsButton, SIGNAL(clicked()),
889           this, SLOT(selectionUserStyleNews()));
890 
891   QGridLayout *styleSheetNewsLayout = new QGridLayout();
892   styleSheetNewsLayout->setContentsMargins(15, 0, 5, 10);
893   styleSheetNewsLayout->addWidget(styleSheetNewsEdit_, 0, 0);
894   styleSheetNewsLayout->addWidget(styleSheetNewsButton, 0, 1, Qt::AlignRight);
895 
896   showDescriptionNews_ = new QCheckBox(tr("Show news description instead of loading web page"));
897 
898   QVBoxLayout *displayFeedsLayout = new QVBoxLayout();
899   displayFeedsLayout->addWidget(alternatingRowColorsNews_);
900   displayFeedsLayout->addSpacing(10);
901   displayFeedsLayout->addWidget(simplifiedDateTime_);
902   displayFeedsLayout->addLayout(formatDateLayout);
903   displayFeedsLayout->addSpacing(10);
904   displayFeedsLayout->addLayout(mainNewsFilterLayout);
905   displayFeedsLayout->addSpacing(10);
906   displayFeedsLayout->addWidget(new QLabel(tr("Style sheet for news:")));
907   displayFeedsLayout->addLayout(styleSheetNewsLayout);
908   displayFeedsLayout->addWidget(showDescriptionNews_);
909   displayFeedsLayout->addStretch();
910 
911   QWidget *displayFeedsWidget = new QWidget();
912   displayFeedsWidget->setLayout(displayFeedsLayout);
913 
914 
915   //! tab "Reading"
916   QVBoxLayout* readingMainLayout = new QVBoxLayout();
917 
918   {
919     markNewsReadOn_ = new QGroupBox(tr("Mark news as read:"));
920 
921     markNewsReadOn_->setCheckable(true);
922 
923     {
924       QVBoxLayout* radioLayout = new QVBoxLayout();
925 
926       {
927         QHBoxLayout* curLayout = new QHBoxLayout();
928 
929         markCurNewsRead_ = new QRadioButton(tr("on selecting. With timeout"));
930 
931         markNewsReadTime_ = new QSpinBox();
932         markNewsReadTime_->setEnabled(false);
933         markNewsReadTime_->setRange(0, 100);
934         connect(markCurNewsRead_, SIGNAL(toggled(bool)),
935           markNewsReadTime_, SLOT(setEnabled(bool)));
936 
937         curLayout->setMargin(0);
938         curLayout->addWidget(markCurNewsRead_);
939         curLayout->addWidget(markNewsReadTime_);
940         curLayout->addWidget(new QLabel(tr("seconds")));
941         curLayout->addStretch();
942 
943         radioLayout->addLayout(curLayout);
944       }
945 
946       markPrevNewsRead_ = new QRadioButton(tr("after switching to another news"));
947 
948       radioLayout->addWidget(markPrevNewsRead_);
949       markNewsReadOn_->setLayout(radioLayout);
950     }
951 
952     markReadSwitchingFeed_ = new QCheckBox(tr("Mark displayed news as read when switching feeds"));
953     markReadClosingTab_ = new QCheckBox(tr("Mark displayed news as read when closing tab"));
954     markReadMinimize_ = new QCheckBox(tr("Mark displayed news as read on minimize"));
955 
956     QGridLayout* curLayout = new QGridLayout();
957 
958     notDeleteStarred_ = new QCheckBox(tr("starred news"));
959     notDeleteLabeled_ = new QCheckBox(tr("labeled news"));
960 
961     curLayout->setContentsMargins(15, 0, 0, 10);
962     curLayout->addWidget(notDeleteStarred_, 0, 0, 1, 1);
963     curLayout->addWidget(notDeleteLabeled_, 1, 0, 1, 1);
964 
965     changeBehaviorActionNUN_ = new QCheckBox(tr("Change behavior of action 'Next Unread News'"));
966 
967     readingMainLayout->addWidget(markNewsReadOn_);
968     readingMainLayout->addWidget(markReadSwitchingFeed_);
969     readingMainLayout->addWidget(markReadClosingTab_);
970     readingMainLayout->addWidget(markReadMinimize_);
971     readingMainLayout->addSpacing(10);
972     readingMainLayout->addWidget(new QLabel(tr("Prevent accidental deletion of:")));
973     readingMainLayout->addLayout(curLayout);
974     readingMainLayout->addWidget(changeBehaviorActionNUN_);
975     readingMainLayout->addStretch();
976   }
977 
978   QWidget* readingFeedsWidget = new QWidget();
979   readingFeedsWidget->setLayout(readingMainLayout);
980 
981 
982 //! tab "Clean Up"
983   QWidget *cleanUpFeedsWidget = new QWidget();
984 
985   cleanupOnShutdownBox_ = new QGroupBox(tr("Enable cleanup on shutdown"));
986   cleanupOnShutdownBox_->setCheckable(true);
987 
988   dayCleanUpOn_ = new QCheckBox(tr("Maximum age of news in days to keep:"));
989   maxDayCleanUp_ = new QSpinBox();
990   maxDayCleanUp_->setEnabled(false);
991   maxDayCleanUp_->setRange(0, 9999);
992   connect(dayCleanUpOn_, SIGNAL(toggled(bool)),
993           maxDayCleanUp_, SLOT(setEnabled(bool)));
994 
995   newsCleanUpOn_ = new QCheckBox(tr("Maximum number of news to keep:"));
996   maxNewsCleanUp_ = new QSpinBox();
997   maxNewsCleanUp_->setEnabled(false);
998   maxNewsCleanUp_->setRange(0, 9999);
999   connect(newsCleanUpOn_, SIGNAL(toggled(bool)),
1000           maxNewsCleanUp_, SLOT(setEnabled(bool)));
1001 
1002   readCleanUp_ = new QCheckBox(tr("Delete read news"));
1003   neverUnreadCleanUp_ = new QCheckBox(tr("Never delete unread news"));
1004   neverStarCleanUp_ = new QCheckBox(tr("Never delete starred news"));
1005   neverLabelCleanUp_ = new QCheckBox(tr("Never delete labeled news"));
1006 
1007   cleanUpDeleted_ = new QCheckBox(tr("Clean up 'Deleted'"));
1008   optimizeDB_ = new QCheckBox(tr("Enable DB optimization (slower shutdown)"));
1009 
1010   QGridLayout *cleanUpFeedsLayout = new QGridLayout();
1011   cleanUpFeedsLayout->setColumnStretch(1, 1);
1012   cleanUpFeedsLayout->addWidget(dayCleanUpOn_, 0, 0, 1, 1);
1013   cleanUpFeedsLayout->addWidget(maxDayCleanUp_, 0, 1, 1, 1, Qt::AlignLeft);
1014   cleanUpFeedsLayout->addWidget(newsCleanUpOn_, 1, 0, 1, 1);
1015   cleanUpFeedsLayout->addWidget(maxNewsCleanUp_, 1, 1, 1, 1, Qt::AlignLeft);
1016   cleanUpFeedsLayout->addWidget(readCleanUp_, 2, 0, 1, 1);
1017   cleanUpFeedsLayout->addWidget(neverUnreadCleanUp_, 3, 0, 1, 1);
1018   cleanUpFeedsLayout->addWidget(neverStarCleanUp_, 4, 0, 1, 1);
1019   cleanUpFeedsLayout->addWidget(neverLabelCleanUp_, 5, 0, 1, 1);
1020 
1021   QVBoxLayout *cleanUpFeedsLayout2 = new QVBoxLayout();
1022   cleanUpFeedsLayout2->addWidget(cleanUpDeleted_);
1023   cleanUpFeedsLayout2->addWidget(optimizeDB_);
1024 
1025   QVBoxLayout *cleanUpFeedsLayout3 = new QVBoxLayout(cleanupOnShutdownBox_);
1026   cleanUpFeedsLayout3->addLayout(cleanUpFeedsLayout);
1027   cleanUpFeedsLayout3->addSpacing(10);
1028   cleanUpFeedsLayout3->addLayout(cleanUpFeedsLayout2);
1029   cleanUpFeedsLayout3->addStretch();
1030 
1031   QVBoxLayout *boxCleanUpFeedsLayout = new QVBoxLayout(cleanUpFeedsWidget);
1032   boxCleanUpFeedsLayout->addWidget(cleanupOnShutdownBox_);
1033 
1034   feedsWidget_ = new QTabWidget();
1035   feedsWidget_->addTab(generalFeedsWidget, tr("General"));
1036   feedsWidget_->addTab(displayFeedsWidget, tr("Display"));
1037   feedsWidget_->addTab(readingFeedsWidget, tr("Reading"));
1038   feedsWidget_->addTab(cleanUpFeedsWidget, tr("Clean Up"));
1039 }
1040 
1041 /** @brief Create widget "Labels"
1042  *----------------------------------------------------------------------------*/
createLabelsWidget()1043 void OptionsDialog::createLabelsWidget()
1044 {
1045   labelsTree_ = new QTreeWidget(this);
1046   labelsTree_->setObjectName("labelsTree_");
1047   labelsTree_->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
1048   labelsTree_->setColumnCount(5);
1049   labelsTree_->setColumnHidden(0, true);
1050   labelsTree_->setColumnHidden(2, true);
1051   labelsTree_->setColumnHidden(3, true);
1052   labelsTree_->setColumnHidden(4, true);
1053   labelsTree_->header()->hide();
1054 
1055   newLabelButton_ = new QPushButton(tr("New..."), this);
1056   connect(newLabelButton_, SIGNAL(clicked()), this, SLOT(newLabel()));
1057   editLabelButton_ = new QPushButton(tr("Edit..."), this);
1058   editLabelButton_->setEnabled(false);
1059   connect(editLabelButton_, SIGNAL(clicked()), this, SLOT(editLabel()));
1060   deleteLabelButton_ = new QPushButton(tr("Delete..."), this);
1061   deleteLabelButton_->setEnabled(false);
1062   connect(deleteLabelButton_, SIGNAL(clicked()), this, SLOT(deleteLabel()));
1063 
1064   moveUpLabelButton_ = new QPushButton(tr("Move up"), this);
1065   moveUpLabelButton_->setEnabled(false);
1066   connect(moveUpLabelButton_, SIGNAL(clicked()), this, SLOT(moveUpLabel()));
1067   moveDownLabelButton_ = new QPushButton(tr("Move down"), this);
1068   moveDownLabelButton_->setEnabled(false);
1069   connect(moveDownLabelButton_, SIGNAL(clicked()), this, SLOT(moveDownLabel()));
1070 
1071   QVBoxLayout *buttonsLayout = new QVBoxLayout();
1072   buttonsLayout->addWidget(newLabelButton_);
1073   buttonsLayout->addWidget(editLabelButton_);
1074   buttonsLayout->addWidget(deleteLabelButton_);
1075   buttonsLayout->addSpacing(10);
1076   buttonsLayout->addWidget(moveUpLabelButton_);
1077   buttonsLayout->addWidget(moveDownLabelButton_);
1078   buttonsLayout->addStretch();
1079 
1080   QHBoxLayout *labelsLayout = new QHBoxLayout();
1081   labelsLayout->setMargin(0);
1082   labelsLayout->addWidget(labelsTree_);
1083   labelsLayout->addLayout(buttonsLayout);
1084 
1085   labelsWidget_ = new QWidget(this);
1086   labelsWidget_->setLayout(labelsLayout);
1087 
1088   connect(labelsTree_, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
1089           this, SLOT(slotCurrentLabelChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
1090   connect(labelsTree_, SIGNAL(doubleClicked(QModelIndex)),
1091           this, SLOT(editLabel()));
1092 
1093   loadLabelsOk_ = false;
1094 }
1095 
1096 /** @brief Create widget "Notifier"
1097  *----------------------------------------------------------------------------*/
createNotifierWidget()1098 void OptionsDialog::createNotifierWidget()
1099 {
1100   showNotifyOn_ = new QGroupBox(tr("Display notification for incoming news"));
1101   showNotifyOn_->setCheckable(true);
1102   showNotifyOn_->setChecked(false);
1103 
1104   screenNotify_ = new QComboBox();
1105   screenNotify_->addItem("-1");
1106   for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
1107     screenNotify_->addItem(QString::number(i));
1108   }
1109   screenNotify_->setCurrentIndex(1);
1110 
1111   positionNotify_ = new QComboBox();
1112   QStringList positionList;
1113   positionList << tr("Top Left") << tr("Top Right")
1114                << tr("Bottom Left") << tr("Bottom Right");
1115   positionNotify_->addItems(positionList);
1116 
1117   fullscreenModeNotify_ = new QCheckBox(tr("Do not show notification in fullscreen mode"));
1118 #if !defined(Q_OS_WIN)
1119   fullscreenModeNotify_->hide();
1120 #endif
1121   showNotifyInactiveApp_ = new QCheckBox(tr("Show when inactive main window"));
1122   closeNotify_ = new QCheckBox(tr("Close notification after opening news"));
1123 
1124   transparencyNotify_ = new QSpinBox();
1125   transparencyNotify_->setRange(0, 100);
1126   countShowNewsNotify_ = new QSpinBox();
1127   countShowNewsNotify_->setRange(1, 30);
1128   widthTitleNewsNotify_ = new QSpinBox();
1129   widthTitleNewsNotify_->setRange(50, 500);
1130   timeShowNewsNotify_ = new QSpinBox();
1131   timeShowNewsNotify_->setRange(0, 99999);
1132 
1133   QPushButton *showNotifer = new QPushButton(tr("Review"));
1134   connect(showNotifer, SIGNAL(clicked()), this, SLOT(showNotification()));
1135 
1136   QHBoxLayout *notifierLayout1 = new QHBoxLayout();
1137   notifierLayout1->addWidget(new QLabel(tr("Screen")));
1138   notifierLayout1->addWidget(screenNotify_);
1139   notifierLayout1->addSpacing(10);
1140   notifierLayout1->addWidget(new QLabel(tr("Position")));
1141   notifierLayout1->addWidget(positionNotify_);
1142   notifierLayout1->addStretch(1);
1143   notifierLayout1->addWidget(showNotifer);
1144 
1145   QGridLayout *notifierLayout2 = new QGridLayout();
1146   notifierLayout2->setColumnStretch(2, 1);
1147   notifierLayout2->addWidget(new QLabel(tr("Transparency")), 0, 0);
1148   notifierLayout2->addWidget(transparencyNotify_, 0, 1);
1149   notifierLayout2->addWidget(new QLabel("%"), 0, 2);
1150   notifierLayout2->addWidget(new QLabel(tr("Show maximum of")), 1, 0);
1151   notifierLayout2->addWidget(countShowNewsNotify_, 1, 1);
1152   notifierLayout2->addWidget(new QLabel(tr("item on page notification")), 1, 2);
1153   notifierLayout2->addWidget(new QLabel(tr("Width list items")), 2, 0);
1154   notifierLayout2->addWidget(widthTitleNewsNotify_, 2, 1);
1155   notifierLayout2->addWidget(new QLabel(tr("pixels")), 2, 2);
1156   notifierLayout2->addWidget(new QLabel(tr("Close notification after")), 3, 0);
1157   notifierLayout2->addWidget(timeShowNewsNotify_, 3, 1);
1158   notifierLayout2->addWidget(new QLabel(tr("seconds")), 3, 2);
1159 
1160 
1161   showTitlesFeedsNotify_ = new QCheckBox(tr("Show titles feeds"));
1162   showIconFeedNotify_ = new QCheckBox(tr("Show icon feed"));
1163   showButtonMarkAllNotify_ = new QCheckBox(tr("Show button 'Mark All News Read'"));
1164   showButtonMarkReadNotify_ = new QCheckBox(tr("Show button 'Mark Read/Unread'"));
1165   showButtonExBrowserNotify_ = new QCheckBox(tr("Show button 'Open in External Browser'"));
1166   showButtonDeleteNotify_ = new QCheckBox(tr("Show button 'Delete News'"));
1167 
1168   QVBoxLayout *notifierLayout3 = new QVBoxLayout();
1169   notifierLayout3->addWidget(showTitlesFeedsNotify_);
1170   notifierLayout3->addWidget(showIconFeedNotify_);
1171   notifierLayout3->addWidget(showButtonMarkAllNotify_);
1172   notifierLayout3->addWidget(showButtonMarkReadNotify_);
1173   notifierLayout3->addWidget(showButtonExBrowserNotify_);
1174   notifierLayout3->addWidget(showButtonDeleteNotify_);
1175 
1176   onlySelectedFeeds_ = new QCheckBox(tr("Only show selected feeds:"));
1177   QPushButton *feedsNotiferButton = new QPushButton(tr("Feeds"));
1178   feedsNotiferButton->setEnabled(false);
1179 
1180   QHBoxLayout *onlySelectedFeedsLayout = new QHBoxLayout();
1181   onlySelectedFeedsLayout->addWidget(onlySelectedFeeds_);
1182   onlySelectedFeedsLayout->addWidget(feedsNotiferButton);
1183   onlySelectedFeedsLayout->addStretch(1);
1184 
1185   createFeedsNotifierDlg();
1186 
1187   connect(onlySelectedFeeds_, SIGNAL(toggled(bool)),
1188           feedsNotiferButton, SLOT(setEnabled(bool)));
1189   connect(feedsNotiferButton, SIGNAL(clicked()),
1190           feedsNotifierDlg_, SLOT(exec()));
1191 
1192   QVBoxLayout *notificationLayoutV = new QVBoxLayout();
1193   notificationLayoutV->setMargin(10);
1194   notificationLayoutV->addLayout(notifierLayout1);
1195   notificationLayoutV->addWidget(fullscreenModeNotify_);
1196   notificationLayoutV->addWidget(showNotifyInactiveApp_);
1197   notificationLayoutV->addWidget(closeNotify_);
1198   notificationLayoutV->addSpacing(10);
1199   notificationLayoutV->addLayout(notifierLayout2);
1200   notificationLayoutV->addSpacing(10);
1201   notificationLayoutV->addLayout(notifierLayout3);
1202   notificationLayoutV->addSpacing(10);
1203   notificationLayoutV->addLayout(onlySelectedFeedsLayout);
1204   notificationLayoutV->addStretch(1);
1205 
1206   showNotifyOn_->setLayout(notificationLayoutV);
1207 
1208   QWidget *notificationWidget = new QWidget();
1209   QVBoxLayout *notificationLayout = new QVBoxLayout(notificationWidget);
1210   notificationLayout->addWidget(showNotifyOn_);
1211 
1212 
1213   soundNotifyBox_ = new QGroupBox(tr("Play sound for incoming new news"));
1214   soundNotifyBox_->setCheckable(true);
1215   soundNotifyBox_->setChecked(false);
1216 
1217   editSoundNotifer_ = new LineEdit();
1218   selectionSoundNotifer_ = new QPushButton(tr("Browse..."));
1219   playSoundNotifer_ = new QPushButton(tr("Play"));
1220 
1221   connect(selectionSoundNotifer_, SIGNAL(clicked()),
1222           this, SLOT(selectionSoundNotifer()));
1223   connect(playSoundNotifer_, SIGNAL(clicked()), this, SLOT(slotPlaySoundNotifer()));
1224   connect(this, SIGNAL(signalPlaySound(QString)), parent(), SLOT(slotPlaySound(QString)));
1225 
1226   QHBoxLayout *soundNotifyLayoutH = new QHBoxLayout();
1227   soundNotifyLayoutH->addWidget(editSoundNotifer_, 1);
1228   soundNotifyLayoutH->addWidget(selectionSoundNotifer_);
1229   soundNotifyLayoutH->addWidget(playSoundNotifer_);
1230 
1231   QVBoxLayout *soundNotifyLayout = new QVBoxLayout(soundNotifyBox_);
1232   soundNotifyLayout->setMargin(10);
1233   soundNotifyLayout->addLayout(soundNotifyLayoutH);
1234   soundNotifyLayout->addStretch(1);
1235 
1236   QWidget *soundNotifyWidget = new QWidget();
1237   QVBoxLayout *boxCleanUpFeedsLayout = new QVBoxLayout(soundNotifyWidget);
1238   boxCleanUpFeedsLayout->addWidget(soundNotifyBox_);
1239 
1240 
1241   notifierWidget_ = new QTabWidget();
1242   notifierWidget_->addTab(notificationWidget, tr("Notification"));
1243   notifierWidget_->addTab(soundNotifyWidget, tr("Sound"));
1244 
1245   loadNotifierOk_ = false;
1246 }
1247 
1248 /** @brief Create dialog "Feeds" for Notifier
1249  *----------------------------------------------------------------------------*/
createFeedsNotifierDlg()1250 void OptionsDialog::createFeedsNotifierDlg()
1251 {
1252   feedsNotifierDlg_ = new Dialog(this);
1253   feedsNotifierDlg_->setWindowFlags (windowFlags() & ~Qt::WindowContextHelpButtonHint);
1254   feedsNotifierDlg_->setWindowTitle(tr("Selection of feeds"));
1255   feedsNotifierDlg_->setMinimumSize(300, 300);
1256 
1257   feedsTreeNotify_ = new QTreeWidget(this);
1258   feedsTreeNotify_->setObjectName("feedsTreeNotify_");
1259   feedsTreeNotify_->setColumnCount(2);
1260   feedsTreeNotify_->setColumnHidden(1, true);
1261   feedsTreeNotify_->header()->hide();
1262 
1263   itemNotChecked_ = false;
1264 
1265   QStringList treeItem;
1266   treeItem << "Feeds" << "Id";
1267   feedsTreeNotify_->setHeaderLabels(treeItem);
1268 
1269   treeItem.clear();
1270   treeItem << tr("All Feeds") << "0";
1271   QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(treeItem);
1272   treeWidgetItem->setCheckState(0, Qt::Checked);
1273   feedsTreeNotify_->addTopLevelItem(treeWidgetItem);
1274 
1275   feedsNotifierDlg_->pageLayout->addWidget(feedsTreeNotify_);
1276   feedsNotifierDlg_->buttonBox->addButton(QDialogButtonBox::Close);
1277 
1278   connect(feedsTreeNotify_, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
1279           this, SLOT(feedsTreeNotifyItemChanged(QTreeWidgetItem*,int)));
1280 }
1281 
1282 /** @brief Create widget "Passwords"
1283  *----------------------------------------------------------------------------*/
createPasswordsWidget()1284 void OptionsDialog::createPasswordsWidget()
1285 {
1286   passTree_ = new QTreeWidget(this);
1287   passTree_->setObjectName("labelsTree_");
1288   passTree_->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
1289   passTree_->setColumnCount(4);
1290   passTree_->setColumnHidden(0, true);
1291   passTree_->setColumnHidden(3, true);
1292   passTree_->setColumnWidth(1, 250);
1293   passTree_->header()->setMinimumSectionSize(22);
1294 
1295   QStringList strTreeItem;
1296   strTreeItem.clear();
1297   strTreeItem << "Id" << tr("Site") << tr("User") << tr("Password");
1298   passTree_->setHeaderLabels(strTreeItem);
1299 
1300   QSqlQuery q;
1301   q.exec("SELECT id, server, username, password FROM passwords");
1302   while (q.next()) {
1303     QString id = q.value(0).toString();
1304     QString server = q.value(1).toString();
1305     QString user = q.value(2).toString();
1306     QString pass = QString::fromUtf8(QByteArray::fromBase64(q.value(3).toByteArray()));
1307 
1308     strTreeItem.clear();
1309     strTreeItem << id << server << user << pass;
1310     QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(strTreeItem);
1311     passTree_->addTopLevelItem(treeWidgetItem);
1312   }
1313 
1314   QPushButton *deletePass = new QPushButton(tr("Delete"));
1315   connect(deletePass, SIGNAL(clicked()), this, SLOT(slotDeletePass()));
1316   QPushButton *deleteAllPass = new QPushButton(tr("Delete All"));
1317   connect(deleteAllPass, SIGNAL(clicked()), this, SLOT(slotDeleteAllPass()));
1318   QPushButton *showPass = new QPushButton(tr("Show Passwords"));
1319   connect(showPass, SIGNAL(clicked()), this, SLOT(slotShowPass()));
1320   QVBoxLayout *passButtonLayout = new QVBoxLayout();
1321   passButtonLayout->addWidget(deletePass);
1322   passButtonLayout->addWidget(deleteAllPass);
1323   passButtonLayout->addSpacing(10);
1324   passButtonLayout->addWidget(showPass);
1325   passButtonLayout->addStretch(1);
1326 
1327   QHBoxLayout *passLayout = new QHBoxLayout();
1328   passLayout->setMargin(0);
1329   passLayout->addWidget(passTree_);
1330   passLayout->addLayout(passButtonLayout);
1331 
1332   passwordsWidget_ = new QWidget();
1333   passwordsWidget_->setLayout(passLayout);
1334 }
1335 
1336 /** @brief Create widget "Language"
1337  *----------------------------------------------------------------------------*/
createLanguageWidget()1338 void OptionsDialog::createLanguageWidget()
1339 {
1340   languageFileList_ = new QTreeWidget();
1341   languageFileList_->setObjectName("languageFileList_");
1342   languageFileList_->setColumnCount(5);
1343   languageFileList_->setColumnHidden(0, true);
1344   languageFileList_->setColumnWidth(1, 180);
1345   languageFileList_->setColumnWidth(2, 60);
1346   languageFileList_->setColumnWidth(3, 120);
1347 
1348   QStringList treeItem;
1349   treeItem.clear();
1350   treeItem << "Id" << tr("Language") << tr("Version")
1351            << tr("Author") << tr("Contact");
1352   languageFileList_->setHeaderLabels(treeItem);
1353 
1354   treeItem.clear();
1355   treeItem << "en" << QString::fromUtf8("English [EN]")
1356            << QString(STRPRODUCTVER)
1357            << "QuiteRSS Team" << "";
1358   QTreeWidgetItem *languageItem = new QTreeWidgetItem(treeItem);
1359   languageItem->setIcon(1, QIcon(":/flags/flag_EN"));
1360   languageFileList_->addTopLevelItem(languageItem);
1361 
1362   treeItem.clear();
1363   treeItem << "ar" << QString::fromUtf8("العربية [AR]")
1364            << "0.15.2"
1365            << "ahmadzxc" << "ahmad.almomani5@gmail.com";
1366   languageItem = new QTreeWidgetItem(treeItem);
1367   languageItem->setIcon(1, QIcon(":/flags/flag_AR"));
1368   languageFileList_->addTopLevelItem(languageItem);
1369 
1370   treeItem.clear();
1371   treeItem << "bg" << QString::fromUtf8("Български [BG]")
1372            << "0.19.4"
1373            << QString::fromUtf8("Nikolai Tsvetkov") << "koko@cybcom.net";
1374   languageItem = new QTreeWidgetItem(treeItem);
1375   languageItem->setIcon(1, QIcon(":/flags/flag_BG"));
1376   languageFileList_->addTopLevelItem(languageItem);
1377 
1378   treeItem.clear();
1379   treeItem << "cs" << QString::fromUtf8("Čeština [CS]")
1380            << "0.18.6"
1381            << QString::fromUtf8("Matej Szendi") << "matej.szendi@gmail.com";
1382   languageItem = new QTreeWidgetItem(treeItem);
1383   languageItem->setIcon(1, QIcon(":/flags/flag_CZ"));
1384   languageFileList_->addTopLevelItem(languageItem);
1385 
1386   treeItem.clear();
1387   treeItem << "de" << QString::fromUtf8("Deutsch [DE]")
1388            << "0.18.12"
1389            << "oxyd24" << "";
1390   languageItem = new QTreeWidgetItem(treeItem);
1391   languageItem->setIcon(1, QIcon(":/flags/flag_DE"));
1392   languageFileList_->addTopLevelItem(languageItem);
1393 
1394   treeItem.clear();
1395   treeItem << "el_GR" << QString::fromUtf8("Ελληνικά (Greece) [el_GR]")
1396            << QString(STRPRODUCTVER)
1397            << "Dimitris Siakavelis" << "";
1398   languageItem = new QTreeWidgetItem(treeItem);
1399   languageItem->setIcon(1, QIcon(":/flags/flag_GR"));
1400   languageFileList_->addTopLevelItem(languageItem);
1401 
1402   treeItem.clear();
1403   treeItem << "es" << QString::fromUtf8("Español [ES]")
1404            << "0.18.6"
1405            << QString::fromUtf8("Cesar Muñoz") << "csarg@live.com";
1406   languageItem = new QTreeWidgetItem(treeItem);
1407   languageItem->setIcon(1, QIcon(":/flags/flag_ES"));
1408   languageFileList_->addTopLevelItem(languageItem);
1409 
1410   treeItem.clear();
1411   treeItem << "fa" << QString::fromUtf8("فارسی [FA]")
1412            << "0.18.10"
1413            << "H.Mohamadi" << "";
1414   languageItem = new QTreeWidgetItem(treeItem);
1415   languageItem->setIcon(1, QIcon(":/flags/flag_FA"));
1416   languageFileList_->addTopLevelItem(languageItem);
1417 
1418   treeItem.clear();
1419   treeItem << "fi" << QString::fromUtf8("Suomi [FI]")
1420            << "0.18.12"
1421            << "J. S. Tuomisto" << "jstuomisto@gmail.com";
1422   languageItem = new QTreeWidgetItem(treeItem);
1423   languageItem->setIcon(1, QIcon(":/flags/flag_FI"));
1424   languageFileList_->addTopLevelItem(languageItem);
1425 
1426   treeItem.clear();
1427   treeItem << "fr" << QString::fromUtf8("Français [FR]")
1428            << "0.19.4"
1429            << "Glad Deschrijver" << "glad.deschrijver@gmail.com";
1430   languageItem = new QTreeWidgetItem(treeItem);
1431   languageItem->setIcon(1, QIcon(":/flags/flag_FR"));
1432   languageFileList_->addTopLevelItem(languageItem);
1433 
1434   treeItem.clear();
1435   treeItem << "gl" << QString::fromUtf8("Galego [GL]")
1436            << "0.18.12"
1437            << QString::fromUtf8("Xesús M. Mosquera Carregal") << "xesusmosquera@gmail.com";
1438   languageItem = new QTreeWidgetItem(treeItem);
1439   languageItem->setIcon(1, QIcon(":/flags/flag_GL"));
1440   languageFileList_->addTopLevelItem(languageItem);
1441 
1442   treeItem.clear();
1443   treeItem << "hi" << QString::fromUtf8("हिन्दी [HI]")
1444            << "0.16.0"
1445            << QString::fromUtf8("") << "";
1446   languageItem = new QTreeWidgetItem(treeItem);
1447   languageItem->setIcon(1, QIcon(":/flags/flag_HI"));
1448   languageFileList_->addTopLevelItem(languageItem);
1449 
1450   treeItem.clear();
1451   treeItem << "hu" << QString::fromUtf8("Magyar [HU]")
1452            << "0.19.4"
1453            << "ZityiSoft" << "zityisoft@gmail.com";
1454   languageItem = new QTreeWidgetItem(treeItem);
1455   languageItem->setIcon(1, QIcon(":/flags/flag_HU"));
1456   languageFileList_->addTopLevelItem(languageItem);
1457 
1458   treeItem.clear();
1459   treeItem << "it" << QString::fromUtf8("Italiano [IT]")
1460            << "0.19.4"
1461            << "ZeroWis" << "lightflash@hotmail.it";
1462   languageItem = new QTreeWidgetItem(treeItem);
1463   languageItem->setIcon(1, QIcon(":/flags/flag_IT"));
1464   languageFileList_->addTopLevelItem(languageItem);
1465 
1466   treeItem.clear();
1467   treeItem << "ja" << QString::fromUtf8("日本語 [JA]")
1468            << "0.19.4"
1469            << "Masato Hashimoto" << "cabezon.hashimoto@gmail.com";
1470   languageItem = new QTreeWidgetItem(treeItem);
1471   languageItem->setIcon(1, QIcon(":/flags/flag_JA"));
1472   languageFileList_->addTopLevelItem(languageItem);
1473 
1474   treeItem.clear();
1475   treeItem << "ko" << QString::fromUtf8("한국어 [KO]")
1476            << "0.19.4"
1477            << QString::fromUtf8("Yonghee Lee") << "v4321v@gmail.com";
1478   languageItem = new QTreeWidgetItem(treeItem);
1479   languageItem->setIcon(1, QIcon(":/flags/flag_KO"));
1480   languageFileList_->addTopLevelItem(languageItem);
1481 
1482   treeItem.clear();
1483   treeItem << "lt" << QString::fromUtf8("Lietuvių [LT]")
1484            << "0.18.6"
1485            << QString::fromUtf8("keturidu") << "";
1486   languageItem = new QTreeWidgetItem(treeItem);
1487   languageItem->setIcon(1, QIcon(":/flags/flag_LT"));
1488   languageFileList_->addTopLevelItem(languageItem);
1489 
1490   treeItem.clear();
1491   treeItem << "nl" << QString::fromUtf8("Nederlands [NL]")
1492            << "0.19.4"
1493            << "TeLLie" << "elbert.pol@gmail.com";
1494   languageItem = new QTreeWidgetItem(treeItem);
1495   languageItem->setIcon(1, QIcon(":/flags/flag_NL"));
1496   languageFileList_->addTopLevelItem(languageItem);
1497 
1498   treeItem.clear();
1499   treeItem << "pl" << QString::fromUtf8("Polski [PL]")
1500            << "0.18.12"
1501            << QString::fromUtf8("Piotr Pecka") << "piotr.pecka@outlook.com";
1502   languageItem = new QTreeWidgetItem(treeItem);
1503   languageItem->setIcon(1, QIcon(":/flags/flag_PL"));
1504   languageFileList_->addTopLevelItem(languageItem);
1505 
1506   treeItem.clear();
1507   treeItem << "pt_BR" << QString::fromUtf8("Português (Brazil) [pt_BR]")
1508            << "0.19.4"
1509            << QString::fromUtf8("Marcos M. Ribeiro") << "";
1510   languageItem = new QTreeWidgetItem(treeItem);
1511   languageItem->setIcon(1, QIcon(":/flags/flag_BR"));
1512   languageFileList_->addTopLevelItem(languageItem);
1513 
1514   treeItem.clear();
1515   treeItem << "pt_PT" << QString::fromUtf8("Português (Portugal) [pt_PT]")
1516            << "0.18.12"
1517            << QString::fromUtf8("Sérgio Marques") << "smarquespt@gmail.com";
1518   languageItem = new QTreeWidgetItem(treeItem);
1519   languageItem->setIcon(1, QIcon(":/flags/flag_PT"));
1520   languageFileList_->addTopLevelItem(languageItem);
1521 
1522   treeItem.clear();
1523   treeItem << "ro_RO" << QString::fromUtf8("Limba română [ro_RO]")
1524            << QString(STRPRODUCTVER)
1525            << QString::fromUtf8("Jaff (Oprea Nicolae)") << "Jaff2002@yahoo.com";
1526   languageItem = new QTreeWidgetItem(treeItem);
1527   languageItem->setIcon(1, QIcon(":/flags/flag_RO"));
1528   languageFileList_->addTopLevelItem(languageItem);
1529 
1530   treeItem.clear();
1531   treeItem << "ru" << QString::fromUtf8("Русский [RU]")
1532            << QString(STRPRODUCTVER)
1533            << "QuiteRSS Team" << "";
1534   languageItem = new QTreeWidgetItem(treeItem);
1535   languageItem->setIcon(1, QIcon(":/flags/flag_RU"));
1536   languageFileList_->addTopLevelItem(languageItem);
1537 
1538   treeItem.clear();
1539   treeItem << "sk" << QString::fromUtf8("Slovenčina [SK]")
1540            << "0.19.4"
1541            << QString::fromUtf8("DAG Software (Ďanovský Ján)") << "dagsoftware@yahoo.com";
1542   languageItem = new QTreeWidgetItem(treeItem);
1543   languageItem->setIcon(1, QIcon(":/flags/flag_SK"));
1544   languageFileList_->addTopLevelItem(languageItem);
1545 
1546   treeItem.clear();
1547   treeItem << "sr" << QString::fromUtf8("Српски [SR]")
1548            << "0.18.12"
1549            << "Ozzii" << "ozzii.translate@gmail.com";
1550   languageItem = new QTreeWidgetItem(treeItem);
1551   languageItem->setIcon(1, QIcon(":/flags/flag_SR"));
1552   languageFileList_->addTopLevelItem(languageItem);
1553 
1554   treeItem.clear();
1555   treeItem << "sv" << QString::fromUtf8("Svenska [SV]")
1556            << QString(STRPRODUCTVER)
1557            << QString::fromUtf8("Åke Engelbrektson") << "eson57@gmail.com";
1558   languageItem = new QTreeWidgetItem(treeItem);
1559   languageItem->setIcon(1, QIcon(":/flags/flag_SV"));
1560   languageFileList_->addTopLevelItem(languageItem);
1561 
1562   treeItem.clear();
1563   treeItem << "tg_TJ" << QString::fromUtf8("Тоҷикӣ [tg_TJ]")
1564            << "0.17.5"
1565            << QString::fromUtf8("Kobilov Iskandar") << "kabilov.iskandar@gmail.com";
1566   languageItem = new QTreeWidgetItem(treeItem);
1567   languageItem->setIcon(1, QIcon(":/flags/flag_TJ"));
1568   languageFileList_->addTopLevelItem(languageItem);
1569 
1570   treeItem.clear();
1571   treeItem << "tr" << QString::fromUtf8("Türkçe [TR]")
1572            << "0.19.4"
1573            << QString::fromUtf8("Mert Başaranoğlu") << "mertbasaranoglu@gmail.com";
1574   languageItem = new QTreeWidgetItem(treeItem);
1575   languageItem->setIcon(1, QIcon(":/flags/flag_TR"));
1576   languageFileList_->addTopLevelItem(languageItem);
1577 
1578   treeItem.clear();
1579   treeItem << "uk" << QString::fromUtf8("Українська [UK]")
1580            << "0.19.4"
1581            << QString::fromUtf8("Сергій Левицький") << "leon21sl@yandex.ua";
1582   languageItem = new QTreeWidgetItem(treeItem);
1583   languageItem->setIcon(1, QIcon(":/flags/flag_UK"));
1584   languageFileList_->addTopLevelItem(languageItem);
1585 
1586   treeItem.clear();
1587   treeItem << "vi" << QString::fromUtf8("Tiếng Việt [VI]")
1588            << "0.14.1"
1589            << QString::fromUtf8("Phan Anh") << "";
1590   languageItem = new QTreeWidgetItem(treeItem);
1591   languageItem->setIcon(1, QIcon(":/flags/flag_VI"));
1592   languageFileList_->addTopLevelItem(languageItem);
1593 
1594   treeItem.clear();
1595   treeItem << "zh_CN" << QString::fromUtf8("中文 (China) [zh_CN]")
1596            << "0.18.12"
1597            << QString::fromUtf8("wwj402") << "";
1598   languageItem = new QTreeWidgetItem(treeItem);
1599   languageItem->setIcon(1, QIcon(":/flags/flag_CN"));
1600   languageFileList_->addTopLevelItem(languageItem);
1601 
1602   treeItem.clear();
1603   treeItem << "zh_TW" << QString::fromUtf8("中文 (Taiwan) [zh_TW]")
1604            << "0.19.4"
1605            << QString::fromUtf8("Hulen (破滅刃)") << "shift0106@hotmail.com";
1606   languageItem = new QTreeWidgetItem(treeItem);
1607   languageItem->setIcon(1, QIcon(":/flags/flag_TW"));
1608   languageFileList_->addTopLevelItem(languageItem);
1609 
1610   QString linkWikiStr =
1611       QString("<a href='https://quiterss.org/en/development'>Link for translators</a>");
1612   QLabel *linkTranslators = new QLabel(linkWikiStr);
1613   linkTranslators->setOpenExternalLinks(true);
1614 
1615   QVBoxLayout *languageLayout = new QVBoxLayout();
1616   languageLayout->setMargin(0);
1617   languageLayout->addWidget(new QLabel(tr("Choose language:")));
1618   languageLayout->addWidget(languageFileList_);
1619   languageLayout->addWidget(linkTranslators);
1620 
1621   languageWidget_ = new QWidget();
1622   languageWidget_->setLayout(languageLayout);
1623 }
1624 
1625 /** @brief Create widget "Fonts and Colors"
1626  *----------------------------------------------------------------------------*/
createFontsColorsWidget()1627 void OptionsDialog::createFontsColorsWidget()
1628 {
1629   //! tab "Fonts"
1630 
1631   fontsTree_ = new QTreeWidget();
1632   fontsTree_->setObjectName("fontTree");
1633   fontsTree_->setColumnCount(3);
1634   fontsTree_->setColumnHidden(0, true);
1635   fontsTree_->setColumnWidth(1, 260);
1636 
1637   QStringList treeItem;
1638   treeItem << "Id" << tr("Type") << tr("Font");
1639   fontsTree_->setHeaderLabels(treeItem);
1640 
1641   treeItem.clear();
1642   treeItem << "0" << tr("Feeds list font");
1643   fontsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1644   treeItem.clear();
1645   treeItem << "1" << tr("News list font");
1646   fontsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1647   treeItem.clear();
1648   treeItem << "2" << tr("News title font");
1649   fontsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1650   treeItem.clear();
1651   treeItem << "3" << tr("News text font");
1652   fontsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1653   treeItem.clear();
1654   treeItem << "4" << tr("Notification font");
1655   fontsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1656 
1657   fontsTree_->setCurrentItem(fontsTree_->topLevelItem(0));
1658   connect(fontsTree_, SIGNAL(doubleClicked(QModelIndex)),
1659           this, SLOT(slotFontChange()));
1660 
1661   QPushButton *fontChange = new QPushButton(tr("Change..."));
1662   connect(fontChange, SIGNAL(clicked()), this, SLOT(slotFontChange()));
1663   QPushButton *fontReset = new QPushButton(tr("Reset"));
1664   connect(fontReset, SIGNAL(clicked()), this, SLOT(slotFontReset()));
1665   QVBoxLayout *fontsButtonLayout = new QVBoxLayout();
1666   fontsButtonLayout->addWidget(fontChange);
1667   fontsButtonLayout->addWidget(fontReset);
1668   fontsButtonLayout->addStretch(1);
1669 
1670   QHBoxLayout *mainFontsLayout = new QHBoxLayout();
1671   mainFontsLayout->addWidget(fontsTree_, 1);
1672   mainFontsLayout->addLayout(fontsButtonLayout);
1673 
1674   QWidget *fontsWidget = new QWidget();
1675   fontsWidget->setLayout(mainFontsLayout);
1676 
1677   //! tab "Colors"
1678 
1679   colorsTree_ = new QTreeWidget(this);
1680   colorsTree_->setObjectName("colorsTree_");
1681   colorsTree_->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
1682   colorsTree_->setRootIsDecorated(false);
1683   colorsTree_->setColumnCount(2);
1684   colorsTree_->setColumnHidden(1, true);
1685   colorsTree_->setHeaderHidden(true);
1686 
1687   treeItem.clear();
1688   treeItem << tr("Feeds list color");
1689   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1690   treeItem.clear();
1691   treeItem << tr("Feeds list background");
1692   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1693   treeItem.clear();
1694   treeItem << tr("News list color");
1695   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1696   treeItem.clear();
1697   treeItem << tr("News list background");
1698   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1699   treeItem.clear();
1700   treeItem << tr("Focused news color");
1701   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1702   treeItem.clear();
1703   treeItem << tr("Focused news background color");
1704   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1705   treeItem.clear();
1706   treeItem << tr("Link color");
1707   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1708   treeItem.clear();
1709   treeItem << tr("Title color");
1710   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1711   treeItem.clear();
1712   treeItem << tr("Date color");
1713   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1714   treeItem.clear();
1715   treeItem << tr("Author color");
1716   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1717   treeItem.clear();
1718   treeItem << tr("News text color");
1719   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1720   treeItem.clear();
1721   treeItem << tr("News title background");
1722   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1723   treeItem.clear();
1724   treeItem << tr("News background");
1725   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1726   treeItem.clear();
1727   treeItem << tr("Feed with new news");
1728   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1729   treeItem.clear();
1730   treeItem << tr("Count of unread news in feeds tree");
1731   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1732   treeItem.clear();
1733   treeItem << tr("Text color of new news");
1734   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1735   treeItem.clear();
1736   treeItem << tr("Text color of unread news");
1737   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1738   treeItem.clear();
1739   treeItem << tr("Focused feed color");
1740   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1741   treeItem.clear();
1742   treeItem << tr("Focused feed background color");
1743   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1744   treeItem.clear();
1745   treeItem << tr("Disabled feed");
1746   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1747   treeItem.clear();
1748   treeItem << tr("Alternating row colors");
1749   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1750   treeItem.clear();
1751   treeItem << tr("Notification text color");
1752   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1753   treeItem.clear();
1754   treeItem << tr("Notification background color");
1755   colorsTree_->addTopLevelItem(new QTreeWidgetItem(treeItem));
1756 
1757   colorsTree_->setCurrentItem(colorsTree_->topLevelItem(0));
1758 
1759   connect(colorsTree_, SIGNAL(doubleClicked(QModelIndex)),
1760           this, SLOT(slotColorChange()));
1761 
1762   QPushButton *colorChange = new QPushButton(tr("Change..."));
1763   connect(colorChange, SIGNAL(clicked()), this, SLOT(slotColorChange()));
1764   QPushButton *colorReset = new QPushButton(tr("Reset"));
1765   connect(colorReset, SIGNAL(clicked()), this, SLOT(slotColorReset()));
1766   QVBoxLayout *colorsButtonLayout = new QVBoxLayout();
1767   colorsButtonLayout->addWidget(colorChange);
1768   colorsButtonLayout->addWidget(colorReset);
1769   colorsButtonLayout->addStretch(1);
1770 
1771   QHBoxLayout *colorsLayout = new QHBoxLayout();
1772   colorsLayout->addWidget(colorsTree_);
1773   colorsLayout->addLayout(colorsButtonLayout);
1774 
1775   QWidget *colorsWidget_ = new QWidget(this);
1776   colorsWidget_->setLayout(colorsLayout);
1777 
1778   //! tab "Fonts Browser"
1779 
1780   browserStandardFont_ = new QFontComboBox();
1781   browserFixedFont_ = new QFontComboBox();
1782   browserSerifFont_ = new QFontComboBox();
1783   browserSansSerifFont_ = new QFontComboBox();
1784   browserCursiveFont_ = new QFontComboBox();
1785   browserFantasyFont_ = new QFontComboBox();
1786 
1787   QGridLayout *browserFontFamiliesLayout = new QGridLayout();
1788   browserFontFamiliesLayout->setColumnStretch(2, 1);
1789   browserFontFamiliesLayout->setContentsMargins(15, 0, 5, 10);
1790   browserFontFamiliesLayout->addWidget(new QLabel(tr("Standard")), 0, 0);
1791   browserFontFamiliesLayout->addWidget(browserStandardFont_, 0, 1);
1792   browserFontFamiliesLayout->addWidget(new QLabel(tr("Fixed")), 1, 0);
1793   browserFontFamiliesLayout->addWidget(browserFixedFont_, 1, 1);
1794   browserFontFamiliesLayout->addWidget(new QLabel(tr("Serif")), 2, 0);
1795   browserFontFamiliesLayout->addWidget(browserSerifFont_, 2, 1);
1796   browserFontFamiliesLayout->addWidget(new QLabel(tr("Sans Serif")), 3, 0);
1797   browserFontFamiliesLayout->addWidget(browserSansSerifFont_, 3, 1);
1798   browserFontFamiliesLayout->addWidget(new QLabel(tr("Cursive")), 4, 0);
1799   browserFontFamiliesLayout->addWidget(browserCursiveFont_, 4, 1);
1800   browserFontFamiliesLayout->addWidget(new QLabel(tr("Fantasy")), 5, 0);
1801   browserFontFamiliesLayout->addWidget(browserFantasyFont_, 5, 1);
1802 
1803   browserDefaultFontSize_ = new QSpinBox();
1804   browserDefaultFontSize_->setRange(0, 99);
1805   browserFixedFontSize_ = new QSpinBox();
1806   browserFixedFontSize_->setRange(0, 99);
1807   browserMinFontSize_ = new QSpinBox();
1808   browserMinFontSize_->setRange(0, 99);
1809   browserMinLogFontSize_ = new QSpinBox();
1810   browserMinLogFontSize_->setRange(0, 99);
1811 
1812   QGridLayout *browserFontSizesLayout = new QGridLayout();
1813   browserFontSizesLayout->setColumnStretch(2, 1);
1814   browserFontSizesLayout->setContentsMargins(15, 0, 5, 0);
1815   browserFontSizesLayout->addWidget(new QLabel(tr("Default font size")), 0, 0);
1816   browserFontSizesLayout->addWidget(browserDefaultFontSize_, 0, 1);
1817   browserFontSizesLayout->addWidget(new QLabel(tr("Fixed font size")), 1, 0);
1818   browserFontSizesLayout->addWidget(browserFixedFontSize_, 1, 1);
1819   browserFontSizesLayout->addWidget(new QLabel(tr("Minimum font size")), 2, 0);
1820   browserFontSizesLayout->addWidget(browserMinFontSize_, 2, 1);
1821   browserFontSizesLayout->addWidget(new QLabel(tr("Minimum logical font size")), 3, 0);
1822   browserFontSizesLayout->addWidget(browserMinLogFontSize_, 3, 1);
1823 
1824   QVBoxLayout *fontsBrowserLayout = new QVBoxLayout();
1825   fontsBrowserLayout->addWidget(new QLabel(tr("Font families:")));
1826   fontsBrowserLayout->addLayout(browserFontFamiliesLayout);
1827   fontsBrowserLayout->addWidget(new QLabel(tr("Font sizes:")));
1828   fontsBrowserLayout->addLayout(browserFontSizesLayout);
1829   fontsBrowserLayout->addStretch();
1830 
1831   QWidget *fontsBrowserWidget_ = new QWidget(this);
1832   fontsBrowserWidget_->setLayout(fontsBrowserLayout);
1833 
1834 
1835   fontsColorsWidget_ = new QTabWidget();
1836   fontsColorsWidget_->addTab(fontsWidget, tr("Fonts"));
1837   fontsColorsWidget_->addTab(fontsBrowserWidget_, tr("Fonts Browser"));
1838   fontsColorsWidget_->addTab(colorsWidget_, tr("Colors"));
1839 }
1840 
1841 /** @brief Create widget "Shortcuts"
1842  *----------------------------------------------------------------------------*/
createShortcutWidget()1843 void OptionsDialog::createShortcutWidget()
1844 {
1845   filterShortcut_ = new LineEdit(this, tr("Filter"));
1846 
1847   shortcutTree_ = new QTreeView(this);
1848   shortcutTree_->setObjectName("shortcutTree");
1849   shortcutTree_->setSortingEnabled(false);
1850   shortcutTree_->setSelectionBehavior(QAbstractItemView::SelectRows);
1851   shortcutTree_->setEditTriggers(QAbstractItemView::NoEditTriggers);
1852   shortcutTree_->setRootIsDecorated(false);
1853 
1854   shortcutModel_ = new QStandardItemModel();
1855   shortcutModel_->setColumnCount(5);
1856   shortcutProxyModel_ = new QSortFilterProxyModel();
1857   shortcutProxyModel_->setSourceModel(shortcutModel_);
1858   shortcutProxyModel_->setFilterKeyColumn(-1);
1859   shortcutProxyModel_->setFilterRole(Qt::UserRole + 1);
1860   shortcutProxyModel_->setFilterCaseSensitivity(Qt::CaseInsensitive);
1861   shortcutTree_->setModel(shortcutProxyModel_);
1862 
1863   shortcutTree_->hideColumn(3);
1864   shortcutTree_->hideColumn(4);
1865   shortcutTree_->header()->setStretchLastSection(true);
1866   shortcutTree_->setColumnWidth(0, 215);
1867   shortcutTree_->setColumnWidth(1, 165);
1868   shortcutTree_->setColumnWidth(2, 120);
1869 
1870   QStringList treeItem;
1871   treeItem << tr("Action") << tr("Description") << tr("Shortcut")
1872            << "ObjectName" << "Data";
1873   shortcutModel_->setHorizontalHeaderLabels(treeItem);
1874 
1875   editShortcut_ = new LineEdit();
1876   QPushButton *resetShortcutButton = new QPushButton(tr("Reset"));
1877 
1878   QHBoxLayout *editShortcutLayout = new QHBoxLayout();
1879   editShortcutLayout->addWidget(new QLabel(tr("Shortcut:")));
1880   editShortcutLayout->addWidget(editShortcut_, 1);
1881   editShortcutLayout->addWidget(resetShortcutButton);
1882 
1883   editShortcutBox = new QGroupBox();
1884   editShortcutBox->setEnabled(false);
1885   editShortcutBox->setLayout(editShortcutLayout);
1886 
1887   warningShortcut_ = new QLabel();
1888 
1889   QVBoxLayout *shortcutLayout = new QVBoxLayout();
1890   shortcutLayout->setMargin(0);
1891   shortcutLayout->addWidget(filterShortcut_);
1892   shortcutLayout->addWidget(shortcutTree_, 1);
1893   shortcutLayout->addWidget(warningShortcut_);
1894   shortcutLayout->addWidget(editShortcutBox);
1895 
1896   shortcutWidget_ = new QWidget();
1897   shortcutWidget_->setLayout(shortcutLayout);
1898 
1899   connect(shortcutTree_, SIGNAL(clicked(QModelIndex)),
1900           this, SLOT(shortcutTreeClicked(QModelIndex)));
1901   connect(this, SIGNAL(signalShortcutTreeUpDownPressed()),
1902           SLOT(slotShortcutTreeUpDownPressed()), Qt::QueuedConnection);
1903   connect(editShortcut_, SIGNAL(signalClear()),
1904           this, SLOT(slotClearShortcut()));
1905   connect(resetShortcutButton, SIGNAL(clicked()),
1906           this, SLOT(slotResetShortcut()));
1907   connect(filterShortcut_, SIGNAL(textChanged(QString)),
1908           this, SLOT(filterShortcutChanged(QString)));
1909 
1910   editShortcut_->installEventFilter(this);
1911 }
1912 //----------------------------------------------------------------------------
slotCategoriesTreeKeyUpDownPressed()1913 void OptionsDialog::slotCategoriesTreeKeyUpDownPressed()
1914 {
1915   slotCategoriesItemClicked(categoriesTree_->currentItem(), 1);
1916 }
1917 //----------------------------------------------------------------------------
slotCategoriesItemClicked(QTreeWidgetItem * item,int)1918 void OptionsDialog::slotCategoriesItemClicked(QTreeWidgetItem* item, int)
1919 {
1920   contentLabel_->setText(item->data(1, Qt::DisplayRole).toString());
1921   contentStack_->setCurrentIndex(item->data(0, Qt::DisplayRole).toInt());
1922 
1923   if (item->data(1, Qt::DisplayRole).toString() == tr("Labels")) {
1924     loadLabels();
1925   } else if (item->data(1, Qt::DisplayRole).toString() == tr("Notifications")) {
1926     loadNotifier();
1927   }
1928 }
1929 //----------------------------------------------------------------------------
currentIndex()1930 int OptionsDialog::currentIndex()
1931 {
1932   return categoriesTree_->currentItem()->text(0).toInt();
1933 }
1934 //----------------------------------------------------------------------------
setCurrentItem(int index)1935 void OptionsDialog::setCurrentItem(int index)
1936 {
1937   categoriesTree_->setCurrentItem(categoriesTree_->topLevelItem(index), 1);
1938   slotCategoriesTreeKeyUpDownPressed();
1939 }
1940 //----------------------------------------------------------------------------
manualProxyToggle(bool checked)1941 void OptionsDialog::manualProxyToggle(bool checked)
1942 {
1943   manualWidget_->setEnabled(checked);
1944 }
1945 //----------------------------------------------------------------------------
proxy()1946 QNetworkProxy OptionsDialog::proxy()
1947 {
1948   return networkProxy_;
1949 }
1950 //----------------------------------------------------------------------------
setProxy(const QNetworkProxy proxy)1951 void OptionsDialog::setProxy(const QNetworkProxy proxy)
1952 {
1953   networkProxy_ = proxy;
1954   updateProxy();
1955 }
1956 //----------------------------------------------------------------------------
updateProxy()1957 void OptionsDialog::updateProxy()
1958 {
1959   switch (networkProxy_.type()) {
1960   case QNetworkProxy::HttpProxy: case QNetworkProxy::Socks5Proxy:
1961     manualProxyButton_->setChecked(true);
1962     if (networkProxy_.type() == QNetworkProxy::Socks5Proxy)
1963       typeProxy_->setCurrentIndex(1);
1964     break;
1965   case QNetworkProxy::NoProxy:
1966     directConnectionButton_->setChecked(true);
1967     break;
1968   case QNetworkProxy::DefaultProxy:
1969   default:
1970     systemProxyButton_->setChecked(true);
1971   }
1972   editHost_->setText(networkProxy_.hostName());
1973   editPort_->setText(QVariant(networkProxy_.port()).toString());
1974   editUser_->setText(networkProxy_.user());
1975   editPassword_->setText(networkProxy_.password());
1976 }
1977 //----------------------------------------------------------------------------
applyProxy()1978 void OptionsDialog::applyProxy()
1979 {
1980   if (systemProxyButton_->isChecked()) {
1981     networkProxy_.setType(QNetworkProxy::DefaultProxy);
1982   } else if (manualProxyButton_->isChecked()) {
1983     if (typeProxy_->currentIndex() == 1)
1984       networkProxy_.setType(QNetworkProxy::Socks5Proxy);
1985     else
1986       networkProxy_.setType(QNetworkProxy::HttpProxy);
1987   } else {
1988     networkProxy_.setType(QNetworkProxy::NoProxy);
1989   }
1990   networkProxy_.setHostName(editHost_->text());
1991   networkProxy_.setPort(editPort_->text().toInt());
1992   networkProxy_.setUser(editUser_->text());
1993   networkProxy_.setPassword(editPassword_->text());
1994 }
1995 //----------------------------------------------------------------------------
language()1996 QString OptionsDialog::language()
1997 {
1998   QString langFileName = languageFileList_->currentItem()->data(0, Qt::DisplayRole).toString();
1999   return langFileName;
2000 }
2001 //----------------------------------------------------------------------------
setLanguage(const QString & langFileName)2002 void OptionsDialog::setLanguage(const QString &langFileName)
2003 {
2004   // Set focus on selected language-file
2005   QList<QTreeWidgetItem*> list =
2006       languageFileList_->findItems(langFileName, Qt::MatchFixedString, 0);
2007   if (list.count()) {
2008     languageFileList_->setCurrentItem(list.at(0));
2009   } else {
2010     // can't find file, choose english
2011     QList<QTreeWidgetItem*> list =
2012         languageFileList_->findItems("en", Qt::MatchFixedString, 0);
2013     languageFileList_->setCurrentItem(list.at(0));
2014   }
2015 }
2016 //----------------------------------------------------------------------------
slotFontChange()2017 void OptionsDialog::slotFontChange()
2018 {
2019   bool bOk;
2020   QFont curFont;
2021   curFont.setFamily(fontsTree_->currentItem()->text(2).section(", ", 0, 0));
2022   curFont.setPointSize(fontsTree_->currentItem()->text(2).section(", ", 1).toInt());
2023 
2024   QFont font = QFontDialog::getFont(&bOk, curFont);
2025   if (bOk) {
2026     QString strFont = QString("%1, %2").
2027         arg(font.family()).
2028         arg(font.pointSize());
2029     fontsTree_->currentItem()->setText(2, strFont);
2030   }
2031 }
2032 //----------------------------------------------------------------------------
slotFontReset()2033 void OptionsDialog::slotFontReset()
2034 {
2035   switch (fontsTree_->currentItem()->text(0).toInt()) {
2036   case 2: case 3: fontsTree_->currentItem()->setText(
2037           2, QString("%1, %2").arg(qApp->font().family()).arg(qApp->font().pointSize()+2));
2038     break;
2039   default: fontsTree_->currentItem()->setText(
2040           2, QString("%1, %2").arg(qApp->font().family()).arg(qApp->font().pointSize()));
2041   }
2042 }
2043 //----------------------------------------------------------------------------
slotColorChange()2044 void OptionsDialog::slotColorChange()
2045 {
2046   QString colorStr = colorsTree_->currentItem()->text(1);
2047   QColorDialog *colorDialog = new QColorDialog(QColor(colorStr), this);
2048   if (colorDialog->exec() == QDialog::Rejected) {
2049     delete colorDialog;
2050     return;
2051   }
2052   QColor color = colorDialog->selectedColor();
2053   delete colorDialog;
2054 
2055   QPixmap pixmapColor(14, 14);
2056   pixmapColor.fill(color.name());
2057   colorsTree_->currentItem()->setIcon(0, pixmapColor);
2058   colorsTree_->currentItem()->setText(1, color.name());
2059 }
2060 //----------------------------------------------------------------------------
slotColorReset()2061 void OptionsDialog::slotColorReset()
2062 {
2063   QString colorName;
2064   int row = colorsTree_->currentIndex().row();
2065   switch (row) {
2066   case 1: case 3: case 5: case 18:
2067     colorName = "";
2068     break;
2069   case 6: case 7:
2070     colorName = "#0066CC";
2071     break;
2072   case 8: case 9:
2073     colorName = "#666666";
2074     break;
2075   case 10:
2076     colorName = "#000000";
2077     break;
2078   case 11: case 12: case 22:
2079     colorName = "#FFFFFF";
2080     break;
2081   case 13: case 14:
2082     colorName = qApp->palette().brush(QPalette::Link).color().name();
2083     break;
2084   case 19:
2085     colorName = "#999999";
2086     break;
2087   case 20:
2088     colorName = qApp->palette().color(QPalette::AlternateBase).name();
2089     break;
2090   default:
2091     colorName = qApp->palette().brush(QPalette::WindowText).color().name();
2092   }
2093   QPixmap pixmapColor(14, 14);
2094   if (colorName.isEmpty())
2095     pixmapColor.fill(QColor(0, 0, 0, 0));
2096   else
2097     pixmapColor.fill(colorName);
2098   colorsTree_->currentItem()->setIcon(0, pixmapColor);
2099   colorsTree_->currentItem()->setText(1, colorName);
2100 }
2101 //----------------------------------------------------------------------------
setBehaviorIconTray(int behavior)2102 void OptionsDialog::setBehaviorIconTray(int behavior)
2103 {
2104   switch (behavior) {
2105   case CHANGE_ICON_TRAY:       changeIconTray_->setChecked(true);  break;
2106   case NEW_COUNT_ICON_TRAY:    newCountTray_->setChecked(true);    break;
2107   case UNREAD_COUNT_ICON_TRAY: unreadCountTray_->setChecked(true); break;
2108   default: staticIconTray_->setChecked(true);
2109   }
2110 }
2111 //----------------------------------------------------------------------------
behaviorIconTray()2112 int OptionsDialog::behaviorIconTray()
2113 {
2114   if (staticIconTray_->isChecked())       return STATIC_ICON_TRAY;
2115   else if (changeIconTray_->isChecked())  return CHANGE_ICON_TRAY;
2116   else if (newCountTray_->isChecked())    return NEW_COUNT_ICON_TRAY;
2117   else if (unreadCountTray_->isChecked()) return UNREAD_COUNT_ICON_TRAY;
2118   else return STATIC_ICON_TRAY;
2119 }
2120 //----------------------------------------------------------------------------
loadActionShortcut(QList<QAction * > actions,QStringList * list)2121 void OptionsDialog::loadActionShortcut(QList<QAction *> actions, QStringList *list)
2122 {
2123   QListIterator<QAction *> iter(actions);
2124   while (iter.hasNext()) {
2125     QAction *pAction = iter.next();
2126 
2127     QStringList treeItem;
2128     treeItem << pAction->text().remove("&")
2129              << pAction->toolTip() << pAction->shortcut().toString()
2130              << pAction->objectName() << pAction->data().toString();
2131 
2132     QList<QStandardItem *> treeItems;
2133     for (int i = 0; i < treeItem.count(); i++) {
2134       QStandardItem *item = new QStandardItem(treeItem.at(i));
2135       if (i == 0) {
2136         if (pAction->icon().isNull())
2137           item->setIcon(QIcon(":/images/images/noicon.png"));
2138         else {
2139           if (pAction->objectName() == "autoLoadImagesToggle") {
2140             item->setIcon(QIcon(":/images/imagesOn"));
2141             item->setText(tr("Load images"));
2142           } else item->setIcon(pAction->icon());
2143         }
2144       } else if (i == 1) {
2145         if (pAction->objectName() == "autoLoadImagesToggle") {
2146           item->setText(tr("Auto load images in news view"));
2147         }
2148       }
2149       if (i >= 0 && i <= 2) {
2150         item->setData(treeItem.at(i));
2151       }
2152       treeItems.append(item);
2153     }
2154     shortcutModel_->appendRow(treeItems);
2155 
2156     QString str = pAction->shortcut().toString();
2157     treeItems = shortcutModel_->findItems(str, Qt::MatchFixedString, 2);
2158     if ((treeItems.count() > 1) && !str.isEmpty()) {
2159       for (int i = 0; i < treeItems.count(); i++) {
2160         treeItems.at(i)->setData(QColor(Qt::red), Qt::TextColorRole);
2161       }
2162     }
2163   }
2164 
2165   listDefaultShortcut_ = list;
2166 }
2167 //----------------------------------------------------------------------------
saveActionShortcut(QList<QAction * > actions,QActionGroup * labelGroup)2168 void OptionsDialog::saveActionShortcut(QList<QAction *> actions, QActionGroup *labelGroup)
2169 {
2170   for (int i = 0; i < shortcutModel_->rowCount(); i++) {
2171     QString objectName = shortcutModel_->item(i, 3)->text();
2172     if (objectName.contains("labelAction_")) {
2173       QAction *action = new QAction(parent());
2174       action->setIcon(shortcutModel_->item(i, 0)->icon());
2175       action->setText(shortcutModel_->item(i, 0)->text());
2176       action->setShortcut(QKeySequence(shortcutModel_->item(i, 2)->text()));
2177       action->setObjectName(shortcutModel_->item(i, 3)->text());
2178       action->setCheckable(true);
2179       action->setData(shortcutModel_->item(i, 4)->text());
2180       labelGroup->addAction(action);
2181       actions.append(action);
2182     } else {
2183       actions.at(i)->setShortcut(
2184             QKeySequence(shortcutModel_->item(i, 2)->text()));
2185     }
2186   }
2187 }
2188 //----------------------------------------------------------------------------
slotShortcutTreeUpDownPressed()2189 void OptionsDialog::slotShortcutTreeUpDownPressed()
2190 {
2191   shortcutTreeClicked(shortcutTree_->currentIndex());
2192 }
2193 //----------------------------------------------------------------------------
shortcutTreeClicked(const QModelIndex & index)2194 void OptionsDialog::shortcutTreeClicked(const QModelIndex &index)
2195 {
2196   QModelIndex indexCur = shortcutProxyModel_->mapToSource(index);
2197   editShortcut_->setText(shortcutModel_->item(indexCur.row(), 2)->text());
2198   editShortcutBox->setEnabled(true);
2199   editShortcut_->setFocus();
2200   warningShortcut_->clear();
2201 }
2202 //----------------------------------------------------------------------------
slotClearShortcut()2203 void OptionsDialog::slotClearShortcut()
2204 {
2205   QModelIndex index = shortcutProxyModel_->mapToSource(shortcutTree_->currentIndex());
2206   int row = index.row();
2207   QString str = shortcutModel_->item(row, 2)->text();
2208   QList<QStandardItem *> treeItems;
2209   treeItems = shortcutModel_->findItems(str, Qt::MatchFixedString, 2);
2210   if ((treeItems.count() > 1) && !str.isEmpty()) {
2211     for (int i = 0; i < treeItems.count(); i++) {
2212       if ((treeItems.count() == 2) || (treeItems.at(i)->row() == row)) {
2213         treeItems.at(i)->setData(shortcutModel_->item(0, 1)->data(Qt::TextColorRole),
2214                                  Qt::TextColorRole);
2215       }
2216     }
2217   }
2218 
2219   editShortcut_->clear();
2220   shortcutModel_->item(row, 2)->setText("");
2221   shortcutModel_->item(row, 2)->setData("");
2222   warningShortcut_->clear();
2223 }
2224 //----------------------------------------------------------------------------
slotResetShortcut()2225 void OptionsDialog::slotResetShortcut()
2226 {
2227   QModelIndex index = shortcutProxyModel_->mapToSource(shortcutTree_->currentIndex());
2228   int row = index.row();
2229   QString objectName = shortcutModel_->item(row, 3)->text();
2230   if (objectName.contains("labelAction_"))
2231     return;
2232 
2233   QString str = shortcutModel_->item(row, 2)->text();
2234   QList<QStandardItem *> treeItems;
2235   treeItems = shortcutModel_->findItems(str, Qt::MatchFixedString, 2);
2236   if (!str.isEmpty()) {
2237     for (int i = 0; i < treeItems.count(); i++) {
2238       if ((treeItems.count() == 2) || (treeItems.at(i)->row() == row)) {
2239         treeItems.at(i)->setData(shortcutModel_->item(0, 1)->data(Qt::TextColorRole),
2240                                  Qt::TextColorRole);
2241       }
2242     }
2243   }
2244 
2245   str = listDefaultShortcut_->at(row);
2246   editShortcut_->setText(str);
2247   shortcutModel_->item(row, 2)->setText(str);
2248   shortcutModel_->item(row, 2)->setData(str);
2249   warningShortcut_->clear();
2250 
2251   if (!str.isEmpty()) {
2252     treeItems = shortcutModel_->findItems(str, Qt::MatchFixedString, 2);
2253     for (int i = 0; i < treeItems.count(); i++) {
2254       if (treeItems.at(i)->row() != row) {
2255         warningShortcut_->setText(tr("Warning: key is already assigned to") +
2256                                   " '" +
2257                                   shortcutModel_->item(treeItems.at(i)->row(), 0)->text() +
2258                                   "'");
2259       }
2260       if (treeItems.count() > 1) {
2261         treeItems.at(i)->setData(QColor(Qt::red), Qt::TextColorRole);
2262       }
2263     }
2264   }
2265 }
2266 //----------------------------------------------------------------------------
filterShortcutChanged(const QString & text)2267 void OptionsDialog::filterShortcutChanged(const QString & text)
2268 {
2269   shortcutProxyModel_->setFilterFixedString(text);
2270 
2271   if (shortcutTree_->currentIndex().isValid()) {
2272     QModelIndex indexCur = shortcutProxyModel_->mapToSource(shortcutTree_->currentIndex());
2273     editShortcut_->setText(shortcutModel_->item(indexCur.row(), 2)->text());
2274     editShortcutBox->setEnabled(true);
2275   } else {
2276     editShortcut_->setText("");
2277     editShortcutBox->setEnabled(false);
2278   }
2279   warningShortcut_->clear();
2280 }
2281 //----------------------------------------------------------------------------
setOpeningFeed(int action)2282 void OptionsDialog::setOpeningFeed(int action)
2283 {
2284   switch (action) {
2285   case 1: positionFirstNews_->setChecked(true); break;
2286   case 2: nottoOpenNews_->setChecked(true); break;
2287   case 3: positionUnreadNews_->setChecked(true); break;
2288   default: positionLastNews_->setChecked(true);
2289   }
2290 }
2291 //----------------------------------------------------------------------------
getOpeningFeed()2292 int OptionsDialog::getOpeningFeed()
2293 {
2294   if (positionLastNews_->isChecked())     return 0;
2295   else if (positionFirstNews_->isChecked()) return 1;
2296   else if (nottoOpenNews_->isChecked()) return 2;
2297   else if (positionUnreadNews_->isChecked()) return 3;
2298   else return 0;
2299 }
2300 //----------------------------------------------------------------------------
selectionBrowser()2301 void OptionsDialog::selectionBrowser()
2302 {
2303   QString path;
2304 
2305   QFileInfo file(otherExternalBrowserEdit_->text());
2306   if (file.isFile()) path = otherExternalBrowserEdit_->text();
2307   else path = file.path();
2308 
2309   QString fileName = QFileDialog::getOpenFileName(this,
2310                                                   tr("Open File..."),
2311                                                   path);
2312   if (!fileName.isEmpty())
2313     otherExternalBrowserEdit_->setText(fileName);
2314 }
2315 //----------------------------------------------------------------------------
applyWhitelist()2316 void OptionsDialog::applyWhitelist()
2317 {
2318   mainApp->c2fSetEnabled(c2fEnabled_->isChecked());
2319   QStringList whitelist;
2320   for (int i = 0; i < c2fWhitelist_->topLevelItemCount(); i++) {
2321     whitelist.append(c2fWhitelist_->topLevelItem(i)->text(0));
2322   }
2323   mainApp->c2fSetWhitelist(whitelist);
2324 }
2325 //----------------------------------------------------------------------------
selectionUserStyleNews()2326 void OptionsDialog::selectionUserStyleNews()
2327 {
2328   QString path(mainApp->resourcesDir() % "/style");
2329   QString fileName = QFileDialog::getOpenFileName(this,
2330                                                   tr("Select Style Sheet File"),
2331                                                   path, "*.css");
2332   if (!fileName.isEmpty())
2333     styleSheetNewsEdit_->setText(fileName);
2334 }
2335 //----------------------------------------------------------------------------
selectionSoundNotifer()2336 void OptionsDialog::selectionSoundNotifer()
2337 {
2338   QString path;
2339 
2340   QFileInfo file(editSoundNotifer_->text());
2341   if (file.isFile()) path = editSoundNotifer_->text();
2342   else path = file.path();
2343 
2344   QString fileName = QFileDialog::getOpenFileName(this,
2345                                                   tr("Open File..."),
2346                                                   path, "*.wav");
2347   if (!fileName.isEmpty())
2348     editSoundNotifer_->setText(fileName);
2349 }
2350 
slotPlaySoundNotifer()2351 void OptionsDialog::slotPlaySoundNotifer()
2352 {
2353   if (!editSoundNotifer_->text().isEmpty())
2354     emit signalPlaySound(editSoundNotifer_->text());
2355 }
2356 
2357 //----------------------------------------------------------------------------
feedsTreeNotifyItemChanged(QTreeWidgetItem * item,int column)2358 void OptionsDialog::feedsTreeNotifyItemChanged(QTreeWidgetItem *item, int column)
2359 {
2360   if ((column != 0) || itemNotChecked_) return;
2361 
2362   itemNotChecked_ = true;
2363   if (item->checkState(0) == Qt::Unchecked) {
2364     setCheckStateItem(item, Qt::Unchecked);
2365 
2366     QTreeWidgetItem *parentItem = item->parent();
2367     while (parentItem) {
2368       parentItem->setCheckState(0, Qt::Unchecked);
2369       parentItem = parentItem->parent();
2370     }
2371   } else {
2372     setCheckStateItem(item, Qt::Checked);
2373   }
2374   itemNotChecked_ = false;
2375 }
2376 //----------------------------------------------------------------------------
setCheckStateItem(QTreeWidgetItem * item,Qt::CheckState state)2377 void OptionsDialog::setCheckStateItem(QTreeWidgetItem *item, Qt::CheckState state)
2378 {
2379   for (int i = 0; i < item->childCount(); ++i) {
2380     QTreeWidgetItem *childItem = item->child(i);
2381     childItem->setCheckState(0, state);
2382     setCheckStateItem(childItem, state);
2383   }
2384 }
2385 //----------------------------------------------------------------------------
loadLabels()2386 void OptionsDialog::loadLabels()
2387 {
2388   if (loadLabelsOk_) return;
2389   loadLabelsOk_ = true;
2390 
2391   idLabels_.clear();
2392 
2393   QSqlQuery q;
2394   q.exec("SELECT id, name, image, color_text, color_bg, num FROM labels ORDER BY num");
2395   while (q.next()) {
2396     int idLabel = q.value(0).toInt();
2397     QString nameLabel = q.value(1).toString();
2398     if ((idLabel <= 6) && (MainWindow::nameLabels().at(idLabel-1) == nameLabel)) {
2399       nameLabel = MainWindow::trNameLabels().at(idLabel-1);
2400     }
2401     QByteArray byteArray = q.value(2).toByteArray();
2402     QString colorText = q.value(3).toString();
2403     QString colorBg = q.value(4).toString();
2404     int numLabel = q.value(5).toInt();
2405     QPixmap imageLabel;
2406     if (!byteArray.isNull())
2407       imageLabel.loadFromData(byteArray);
2408     QStringList strTreeItem;
2409     strTreeItem << QString::number(idLabel) << nameLabel
2410                 << colorText << colorBg << QString::number(numLabel);
2411     QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(strTreeItem);
2412     treeWidgetItem->setIcon(1, QIcon(imageLabel));
2413     if (!colorText.isEmpty())
2414       treeWidgetItem->setTextColor(1, QColor(colorText));
2415     if (!colorBg.isEmpty())
2416       treeWidgetItem->setBackgroundColor(1, QColor(colorBg));
2417     labelsTree_->addTopLevelItem(treeWidgetItem);
2418   }
2419 }
2420 //----------------------------------------------------------------------------
newLabel()2421 void OptionsDialog::newLabel()
2422 {
2423   LabelDialog *labelDialog = new LabelDialog(this);
2424 
2425   if (labelDialog->exec() == QDialog::Rejected) {
2426     delete labelDialog;
2427     return;
2428   }
2429 
2430   QString nameLabel = labelDialog->nameEdit_->text();
2431   QString colorText = labelDialog->colorTextStr_;
2432   QString colorBg = labelDialog->colorBgStr_;
2433 
2434   int idLabel = 0;
2435   for (int i = 0; i < labelsTree_->topLevelItemCount(); i++) {
2436     QString str = labelsTree_->topLevelItem(i)->text(0);
2437     if (idLabel < str.toInt())
2438       idLabel = str.toInt();
2439   }
2440   idLabel = idLabel + 1;
2441 
2442   QStringList itemStr;
2443   itemStr << QString::number(idLabel) << nameLabel
2444               << colorText << colorBg
2445               << QString::number(idLabel);
2446   QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(itemStr);
2447   treeWidgetItem->setIcon(1, labelDialog->icon_);
2448   if (!colorText.isEmpty())
2449     treeWidgetItem->setTextColor(1, QColor(colorText));
2450   if (!colorBg.isEmpty())
2451     treeWidgetItem->setBackgroundColor(1, QColor(colorBg));
2452   labelsTree_->addTopLevelItem(treeWidgetItem);
2453   addIdLabelList(treeWidgetItem->text(0));
2454 
2455   itemStr.clear();
2456   itemStr << nameLabel << nameLabel << ""
2457           << QString("labelAction_%1").arg(idLabel) << QString::number(idLabel);
2458   QList<QStandardItem *> treeItems;
2459   for (int i = 0; i < itemStr.count(); i++) {
2460     QStandardItem *item = new QStandardItem(itemStr.at(i));
2461     if (i == 0) {
2462       item->setIcon(labelDialog->icon_);
2463     }
2464     if (i >= 0 && i <= 2) {
2465       item->setData(itemStr.at(i));
2466     }
2467     treeItems.append(item);
2468   }
2469   shortcutModel_->appendRow(treeItems);
2470 
2471   delete labelDialog;
2472 }
2473 //----------------------------------------------------------------------------
editLabel()2474 void OptionsDialog::editLabel()
2475 {
2476   QTreeWidgetItem *treeWidgetItem = labelsTree_->currentItem();
2477 
2478   QString idLabelStr = treeWidgetItem->text(0);
2479   QString nameLabel = treeWidgetItem->text(1);
2480   QString colorText = treeWidgetItem->text(2);
2481   QString colorBg = treeWidgetItem->text(3);
2482 
2483   LabelDialog *labelDialog = new LabelDialog(this);
2484 
2485   labelDialog->nameEdit_->setText(nameLabel);
2486   labelDialog->icon_ = treeWidgetItem->icon(1);
2487   labelDialog->colorTextStr_ = colorText;
2488   labelDialog->colorBgStr_ = colorBg;
2489   labelDialog->loadData();
2490 
2491   if (labelDialog->exec() == QDialog::Rejected) {
2492     delete labelDialog;
2493     return;
2494   }
2495 
2496   nameLabel = labelDialog->nameEdit_->text();
2497   colorText = labelDialog->colorTextStr_;
2498   colorBg = labelDialog->colorBgStr_;
2499 
2500   treeWidgetItem->setText(1, nameLabel);
2501   treeWidgetItem->setText(2, colorText);
2502   treeWidgetItem->setText(3, colorBg);
2503   treeWidgetItem->setIcon(1, labelDialog->icon_);
2504   if (!colorText.isEmpty())
2505     treeWidgetItem->setTextColor(1, QColor(colorText));
2506   if (!colorBg.isEmpty())
2507     treeWidgetItem->setBackgroundColor(1, QColor(colorBg));
2508   addIdLabelList(idLabelStr);
2509 
2510   QList<QStandardItem *> treeItems;
2511   treeItems = shortcutModel_->findItems(idLabelStr, Qt::MatchFixedString, 4);
2512   QStandardItem *item = treeItems.first();
2513   shortcutModel_->item(item->row(), 0)->setIcon(labelDialog->icon_);
2514   shortcutModel_->item(item->row(), 0)->setText(nameLabel);
2515   shortcutModel_->item(item->row(), 0)->setData(nameLabel);
2516 
2517   delete labelDialog;
2518 }
2519 //----------------------------------------------------------------------------
deleteLabel()2520 void OptionsDialog::deleteLabel()
2521 {
2522   int labelRow = labelsTree_->currentIndex().row();
2523   addIdLabelList(labelsTree_->topLevelItem(labelRow)->text(0));
2524 
2525   QString idLabelStr = labelsTree_->topLevelItem(labelRow)->text(0);
2526   QList<QStandardItem *> treeItems;
2527   treeItems = shortcutModel_->findItems(idLabelStr, Qt::MatchFixedString, 4);
2528   QStandardItem *item = treeItems.first();
2529   shortcutModel_->removeRow(item->row());
2530 
2531   QTreeWidgetItem *treeItem = labelsTree_->takeTopLevelItem(labelRow);
2532   delete treeItem;
2533 }
2534 //----------------------------------------------------------------------------
moveUpLabel()2535 void OptionsDialog::moveUpLabel()
2536 {
2537   int labelRow = labelsTree_->currentIndex().row();
2538 
2539   addIdLabelList(labelsTree_->topLevelItem(labelRow)->text(0));
2540   addIdLabelList(labelsTree_->topLevelItem(labelRow-1)->text(0));
2541 
2542   QString idLabelStr = labelsTree_->topLevelItem(labelRow)->text(0);
2543   QList<QStandardItem *> treeItems;
2544   treeItems = shortcutModel_->findItems(idLabelStr, Qt::MatchFixedString, 4);
2545   int row = treeItems.first()->row();
2546   treeItems = shortcutModel_->takeRow(row-1);
2547   shortcutModel_->insertRow(row, treeItems);
2548 
2549   int num1 = labelsTree_->topLevelItem(labelRow)->text(4).toInt();
2550   int num2 = labelsTree_->topLevelItem(labelRow-1)->text(4).toInt();
2551   labelsTree_->topLevelItem(labelRow-1)->setText(4, QString::number(num1));
2552   labelsTree_->topLevelItem(labelRow)->setText(4, QString::number(num2));
2553 
2554   QTreeWidgetItem *treeItem = labelsTree_->takeTopLevelItem(labelRow-1);
2555   labelsTree_->insertTopLevelItem(labelRow, treeItem);
2556 
2557   if (labelsTree_->currentIndex().row() == 0)
2558     moveUpLabelButton_->setEnabled(false);
2559   if (labelsTree_->currentIndex().row() != (labelsTree_->topLevelItemCount()-1))
2560     moveDownLabelButton_->setEnabled(true);
2561 }
2562 //----------------------------------------------------------------------------
moveDownLabel()2563 void OptionsDialog::moveDownLabel()
2564 {
2565   int labelRow = labelsTree_->currentIndex().row();
2566 
2567   addIdLabelList(labelsTree_->topLevelItem(labelRow)->text(0));
2568   addIdLabelList(labelsTree_->topLevelItem(labelRow+1)->text(0));
2569 
2570   QString idLabelStr = labelsTree_->topLevelItem(labelRow)->text(0);
2571   QList<QStandardItem *> treeItems;
2572   treeItems = shortcutModel_->findItems(idLabelStr, Qt::MatchFixedString, 4);
2573   int row = treeItems.first()->row();
2574   treeItems = shortcutModel_->takeRow(row+1);
2575   shortcutModel_->insertRow(row, treeItems);
2576 
2577   int num1 = labelsTree_->topLevelItem(labelRow)->text(4).toInt();
2578   int num2 = labelsTree_->topLevelItem(labelRow+1)->text(4).toInt();
2579   labelsTree_->topLevelItem(labelRow+1)->setText(4, QString::number(num1));
2580   labelsTree_->topLevelItem(labelRow)->setText(4, QString::number(num2));
2581 
2582   QTreeWidgetItem *treeItem = labelsTree_->takeTopLevelItem(labelRow+1);
2583   labelsTree_->insertTopLevelItem(labelRow, treeItem);
2584 
2585   if (labelsTree_->currentIndex().row() == (labelsTree_->topLevelItemCount()-1))
2586     moveDownLabelButton_->setEnabled(false);
2587   if (labelsTree_->currentIndex().row() != 0)
2588     moveUpLabelButton_->setEnabled(true);
2589 }
2590 //----------------------------------------------------------------------------
slotCurrentLabelChanged(QTreeWidgetItem * current,QTreeWidgetItem *)2591 void OptionsDialog::slotCurrentLabelChanged(QTreeWidgetItem *current,
2592                                            QTreeWidgetItem *)
2593 {
2594   if (labelsTree_->indexOfTopLevelItem(current) == 0)
2595     moveUpLabelButton_->setEnabled(false);
2596   else moveUpLabelButton_->setEnabled(true);
2597 
2598   if (labelsTree_->indexOfTopLevelItem(current) == (labelsTree_->topLevelItemCount()-1))
2599     moveDownLabelButton_->setEnabled(false);
2600   else moveDownLabelButton_->setEnabled(true);
2601 
2602   if (labelsTree_->indexOfTopLevelItem(current) < 0) {
2603     editLabelButton_->setEnabled(false);
2604     deleteLabelButton_->setEnabled(false);
2605     moveUpLabelButton_->setEnabled(false);
2606     moveDownLabelButton_->setEnabled(false);
2607   } else {
2608     editLabelButton_->setEnabled(true);
2609     deleteLabelButton_->setEnabled(true);
2610   }
2611 }
2612 //----------------------------------------------------------------------------
applyLabels()2613 void OptionsDialog::applyLabels()
2614 {
2615   db_.transaction();
2616   QSqlQuery q;
2617 
2618   foreach (QString idLabel, idLabels_) {
2619     QList<QTreeWidgetItem *> treeItems =
2620         labelsTree_->findItems(idLabel, Qt::MatchFixedString, 0);
2621     if (treeItems.count() == 0) {
2622       q.exec(QString("DELETE FROM labels WHERE id=='%1'").arg(idLabel));
2623       q.exec(QString("SELECT id, label FROM news WHERE label LIKE '%,%1,%'").arg(idLabel));
2624       while (q.next()) {
2625         QString strIdLabels = q.value(1).toString();
2626         strIdLabels.replace(QString(",%1,").arg(idLabel), ",");
2627         QSqlQuery q1;
2628         q1.exec(QString("UPDATE news SET label='%1' WHERE id=='%2'").
2629                arg(strIdLabels).arg(q.value(0).toInt()));
2630       }
2631     } else {
2632       QString nameLabel = treeItems.at(0)->text(1);
2633       if ((idLabel.toInt() <= 6) && (MainWindow::trNameLabels().at(idLabel.toInt()-1) == nameLabel)) {
2634         nameLabel = MainWindow::nameLabels().at(idLabel.toInt()-1);
2635       }
2636       QPixmap icon = treeItems.at(0)->icon(1).pixmap(16, 16);
2637       QByteArray iconData;
2638       QBuffer    buffer(&iconData);
2639       buffer.open(QIODevice::WriteOnly);
2640       icon.save(&buffer, "PNG");
2641       buffer.close();
2642       QString colorText = treeItems.at(0)->text(2);
2643       QString colorBg = treeItems.at(0)->text(3);
2644       int numLabel = treeItems.at(0)->text(4).toInt();
2645 
2646       q.exec(QString("SELECT * FROM labels WHERE id=='%1'").arg(idLabel));
2647       if (q.next()) {
2648         q.prepare("UPDATE labels SET name=?, image=?, color_text=?, color_bg=?, num=? "
2649                   "WHERE id=?");
2650         q.addBindValue(nameLabel);
2651         q.addBindValue(iconData);
2652         q.addBindValue(colorText);
2653         q.addBindValue(colorBg);
2654         q.addBindValue(numLabel);
2655         q.addBindValue(idLabel);
2656         q.exec();
2657       } else {
2658         q.prepare("INSERT INTO labels(name, image, color_text, color_bg, num) "
2659                   "VALUES (:name, :image, :color_text, :color_bg, :num)");
2660         q.bindValue(":name", nameLabel);
2661         q.bindValue(":image", iconData);
2662         q.bindValue(":color_text", colorText);
2663         q.bindValue(":color_bg", colorBg);
2664         q.bindValue(":num", numLabel);
2665         q.exec();
2666       }
2667     }
2668   }
2669 
2670   db_.commit();
2671 }
2672 
2673 /** @brief Add id for editing label
2674  * @param idLabel id for label
2675  *----------------------------------------------------------------------------*/
addIdLabelList(const QString & idLabel)2676 void OptionsDialog::addIdLabelList(const QString &idLabel)
2677 {
2678   if (!idLabels_.contains(idLabel)) idLabels_.append(idLabel);
2679 }
2680 //----------------------------------------------------------------------------
loadNotifier()2681 void OptionsDialog::loadNotifier()
2682 {
2683   if (loadNotifierOk_) return;
2684   loadNotifierOk_ = true;
2685 
2686   itemNotChecked_ = true;
2687 
2688   QSqlQuery q;
2689   QQueue<int> parentIds;
2690   parentIds.enqueue(0);
2691   while (!parentIds.empty()) {
2692     int parentId = parentIds.dequeue();
2693     QString qStr = QString("SELECT text, id, image, xmlUrl FROM feeds WHERE parentId='%1' ORDER BY rowToParent").
2694         arg(parentId);
2695     q.exec(qStr);
2696     while (q.next()) {
2697       QString feedText = q.value(0).toString();
2698       QString feedId = q.value(1).toString();
2699       QByteArray byteArray = q.value(2).toByteArray();
2700       QString xmlUrl = q.value(3).toString();
2701 
2702       QStringList treeItem;
2703       treeItem << feedText << feedId;
2704       QTreeWidgetItem *treeWidgetItem = new QTreeWidgetItem(treeItem);
2705 
2706       treeWidgetItem->setCheckState(0, Qt::Unchecked);
2707       QSqlQuery q1;
2708       qStr = QString("SELECT value FROM feeds_ex WHERE feedId='%1' AND name='showNotification'").
2709           arg(feedId);
2710       q1.exec(qStr);
2711       if (q1.next()) {
2712         if (q1.value(0).toInt() == 1)
2713           treeWidgetItem->setCheckState(0, Qt::Checked);
2714       } else {
2715         qStr = QString("INSERT INTO feeds_ex(feedId, name, value) VALUES ('%1', 'showNotification', '0')").
2716             arg(feedId);
2717         q1.exec(qStr);
2718       }
2719       if (treeWidgetItem->checkState(0) == Qt::Unchecked)
2720         feedsTreeNotify_->topLevelItem(0)->setCheckState(0, Qt::Unchecked);
2721 
2722       QPixmap iconItem;
2723       if (xmlUrl.isEmpty()) {
2724         iconItem.load(":/images/folder");
2725       } else {
2726         if (byteArray.isNull() || mainApp->mainWindow()->defaultIconFeeds_) {
2727           iconItem.load(":/images/feed");
2728         } else {
2729           iconItem.loadFromData(QByteArray::fromBase64(byteArray));
2730         }
2731       }
2732       treeWidgetItem->setIcon(0, iconItem);
2733 
2734       QList<QTreeWidgetItem *> treeItems =
2735             feedsTreeNotify_->findItems(QString::number(parentId),
2736                                                        Qt::MatchFixedString | Qt::MatchRecursive,
2737                                                        1);
2738       treeItems.at(0)->addChild(treeWidgetItem);
2739       if (xmlUrl.isEmpty())
2740         parentIds.enqueue(feedId.toInt());
2741     }
2742   }
2743   feedsTreeNotify_->expandAll();
2744   itemNotChecked_ = false;
2745 }
2746 //----------------------------------------------------------------------------
applyNotifier()2747 void OptionsDialog::applyNotifier()
2748 {
2749   mainApp->mainWindow()->idFeedsNotifyList_.clear();
2750 
2751   feedsTreeNotify_->expandAll();
2752   QTreeWidgetItem *treeWidgetItem =
2753       feedsTreeNotify_->itemBelow(feedsTreeNotify_->topLevelItem(0));
2754   db_.transaction();
2755   while (treeWidgetItem) {
2756     int check = 0;
2757     if (treeWidgetItem->checkState(0) == Qt::Checked)
2758       check = 1;
2759     QSqlQuery q;
2760     QString qStr = QString("UPDATE feeds_ex SET value='%1' WHERE feedId='%2' AND name='showNotification'").
2761         arg(check).arg(treeWidgetItem->text(1).toInt());
2762     q.exec(qStr);
2763 
2764     if (check && onlySelectedFeeds_->isChecked())
2765       mainApp->mainWindow()->idFeedsNotifyList_.append(treeWidgetItem->text(1).toInt());
2766 
2767     treeWidgetItem = feedsTreeNotify_->itemBelow(treeWidgetItem);
2768   }
2769   db_.commit();
2770 }
2771 
2772 /** @brief Show notifier test window
2773  *----------------------------------------------------------------------------*/
showNotification()2774 void OptionsDialog::showNotification()
2775 {
2776   if (notificationWidget_) delete notificationWidget_;
2777   QList<int> idFeedList;
2778   QList<int> cntNewNewsList;
2779   QList<int> idColorList;
2780   QStringList colorList;
2781   notificationWidget_ = new NotificationWidget(idFeedList, cntNewNewsList,
2782                                                idColorList, colorList,
2783                                                this, this);
2784 
2785   connect(notificationWidget_, SIGNAL(signalClose()),
2786           this, SLOT(deleteNotification()));
2787 
2788   notificationWidget_->show();
2789 }
2790 
2791 /** @brief Destroy notifier test window
2792  *----------------------------------------------------------------------------*/
deleteNotification()2793 void OptionsDialog::deleteNotification()
2794 {
2795   notificationWidget_->deleteLater();
2796   notificationWidget_ = NULL;
2797 }
2798 //----------------------------------------------------------------------------
slotDeletePass()2799 void OptionsDialog::slotDeletePass()
2800 {
2801   if (passTree_->topLevelItemCount())
2802     passTree_->currentItem()->setHidden(true);
2803 }
2804 //----------------------------------------------------------------------------
slotDeleteAllPass()2805 void OptionsDialog::slotDeleteAllPass()
2806 {
2807   for (int i = 0; i < passTree_->topLevelItemCount(); i++) {
2808     passTree_->topLevelItem(i)->setHidden(true);
2809   }
2810 }
2811 //----------------------------------------------------------------------------
slotShowPass()2812 void OptionsDialog::slotShowPass()
2813 {
2814   if (passTree_->isColumnHidden(3)) {
2815     passTree_->showColumn(3);
2816     passTree_->setColumnWidth(1, passTree_->columnWidth(1) - passTree_->columnWidth(3));
2817   }
2818 }
2819 //----------------------------------------------------------------------------
applyPass()2820 void OptionsDialog::applyPass()
2821 {
2822   db_.transaction();
2823   QSqlQuery q;
2824   for (int i = 0; i < passTree_->topLevelItemCount(); i++) {
2825     if (passTree_->isItemHidden(passTree_->topLevelItem(i))) {
2826       QString id = passTree_->topLevelItem(i)->text(0);
2827       q.exec(QString("DELETE FROM passwords WHERE id=='%1'").arg(id));
2828     }
2829   }
2830   db_.commit();
2831 }
2832 //----------------------------------------------------------------------------
selectionUserStyleBrowser()2833 void OptionsDialog::selectionUserStyleBrowser()
2834 {
2835   QString path;
2836 
2837   QFileInfo file(userStyleBrowserEdit_->text());
2838   if (file.isFile()) path = userStyleBrowserEdit_->text();
2839   else path = file.path();
2840 
2841   QString fileName = QFileDialog::getOpenFileName(this,
2842                                                   tr("Select Style Sheet File"),
2843                                                   path, "*.css");
2844 
2845   if (!fileName.isEmpty())
2846     userStyleBrowserEdit_->setText(fileName);
2847 }
2848 //----------------------------------------------------------------------------
selectionDirDiskCache()2849 void OptionsDialog::selectionDirDiskCache()
2850 {
2851   QString dirStr = QFileDialog::getExistingDirectory(this, tr("Open Directory..."),
2852                                                        dirDiskCacheEdit_->text(),
2853                                                        QFileDialog::ShowDirsOnly
2854                                                        | QFileDialog::DontResolveSymlinks);
2855   if (!dirStr.isEmpty())
2856     dirDiskCacheEdit_->setText(dirStr);
2857 }
2858 //----------------------------------------------------------------------------
addWhitelist()2859 void OptionsDialog::addWhitelist()
2860 {
2861   QString site = QInputDialog::getText(this, tr("Add site to whitelist"),
2862                                        tr("Site without 'http://' (ex. youtube.com)"));
2863   if (site.isEmpty())
2864     return;
2865 
2866   c2fWhitelist_->insertTopLevelItem(0, new QTreeWidgetItem(QStringList(site)));
2867 }
2868 //----------------------------------------------------------------------------
removeWhitelist()2869 void OptionsDialog::removeWhitelist()
2870 {
2871   QTreeWidgetItem* item = c2fWhitelist_->currentItem();
2872   if (!item)
2873     return;
2874 
2875   delete item;
2876 }
2877 //----------------------------------------------------------------------------
selectionDownloadLocation()2878 void OptionsDialog::selectionDownloadLocation()
2879 {
2880   QString dirStr = QFileDialog::getExistingDirectory(this, tr("Open Directory..."),
2881                                                      downloadLocationEdit_->text(),
2882                                                      QFileDialog::ShowDirsOnly
2883                                                      | QFileDialog::DontResolveSymlinks);
2884   if (!dirStr.isEmpty())
2885     downloadLocationEdit_->setText(dirStr);
2886 }
2887