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 "mainwindow.h"
19
20 #include "common.h"
21 #include "mainapplication.h"
22 #include "database.h"
23 #include "aboutdialog.h"
24 #include "adblockmanager.h"
25 #include "adblockicon.h"
26 #include "addfeedwizard.h"
27 #include "addfolderdialog.h"
28 #include "cleanupwizard.h"
29 #include "customizetoolbardialog.h"
30 #include "feedpropertiesdialog.h"
31 #include "filterrulesdialog.h"
32 #include "newsfiltersdialog.h"
33 #include "webpage.h"
34 #include "settings.h"
35
36 #if defined(Q_OS_WIN)
37 #include <windows.h>
38 #include <psapi.h>
39 #endif
40 #include <QMainWindow>
41 #include <QStatusBar>
42 #include <qzregexp.h>
43
44 // ---------------------------------------------------------------------------
MainWindow(QWidget * parent)45 MainWindow::MainWindow(QWidget *parent)
46 : QMainWindow(parent)
47 , isMinimizeToTray_(true)
48 , currentNewsTab(NULL)
49 , isOpeningLink_(false)
50 , openNewsTab_(0)
51 , feedsFilterAction_(NULL)
52 , newsFilterAction_(NULL)
53 , newsView_(NULL)
54 , updateTimeCount_(0)
55 #if defined(HAVE_QT5) || defined(HAVE_PHONON)
56 , mediaPlayer_(NULL)
57 #endif
58 , updateAppDialog_(NULL)
59 , notificationWidget(NULL)
60 , feedIdOld_(-2)
61 , isStartImportFeed_(false)
62 , recountCategoryCountsOn_(false)
63 , optionsDialog_(NULL)
64 {
65 setObjectName("mainWindow");
66 setWindowTitle("QuiteRSS");
67 setContextMenuPolicy(Qt::CustomContextMenu);
68
69 if (mainApp->analytics())
70 mainApp->analytics()->sendScreenview("MainWindow");
71
72 db_ = QSqlDatabase::database();
73
74 createFeedsWidget();
75 createToolBarNull();
76
77 createActions();
78 createShortcut();
79 createMenu();
80 createToolBar();
81
82 createStatusBar();
83 createTray();
84
85 createTabBarWidget();
86 createCentralWidget();
87
88 loadSettingsFeeds();
89
90 setStyleSheet("QMainWindow::separator { width: 1px; }");
91
92 loadSettings();
93
94 addOurFeed();
95
96 initUpdateFeeds();
97
98 QTimer::singleShot(5000, this, SLOT(slotUpdateAppCheck()));
99
100 connect(this, SIGNAL(signalShowNotification(bool)),
101 SLOT(showNotification(bool)), Qt::QueuedConnection);
102 connect(this, SIGNAL(signalPlaySoundNewNews()),
103 SLOT(slotPlaySoundNewNews()), Qt::QueuedConnection);
104
105 connect(&timerLinkOpening_, SIGNAL(timeout()),
106 this, SLOT(slotTimerLinkOpening()));
107
108 connect(mainApp->downloadManager(), SIGNAL(signalShowDownloads(bool)),
109 this, SLOT(showDownloadManager(bool)));
110 connect(mainApp->downloadManager(), SIGNAL(signalUpdateInfo(QString)),
111 this, SLOT(updateInfoDownloads(QString)));
112
113 connect(&timerTrayOpenNotify, SIGNAL(timeout()), this, SLOT(slotTrayOpenNotifyTimer()));
114 timerTrayOpenNotify.setSingleShot(true);
115
116 retranslateStrings();
117
118 installEventFilter(this);
119 }
120
121 // ---------------------------------------------------------------------------
~MainWindow()122 MainWindow::~MainWindow()
123 {
124
125 }
126
127 // ---------------------------------------------------------------------------
closeEvent(QCloseEvent * event)128 void MainWindow::closeEvent(QCloseEvent *event)
129 {
130 if (mainApp->isClosing())
131 return;
132
133 if (closingTray_ && showTrayIcon_) {
134 event->ignore();
135 isOpeningLink_ = false;
136
137 oldState = windowState();
138 emit signalPlaceToTray();
139 } else {
140 #if defined(Q_OS_MAC)
141 event->ignore();
142 #endif
143 quitApp();
144 }
145 }
146
147 /** @brief Process quit application
148 *---------------------------------------------------------------------------*/
quitApp()149 void MainWindow::quitApp()
150 {
151 mainApp->setClosing();
152 isMinimizeToTray_ = true;
153 disconnect(this);
154 if (updateAppDialog_) {
155 updateAppDialog_->disconnectObjects();
156 updateAppDialog_->deleteLater();
157 }
158 if (optionsDialog_) {
159 optionsDialog_->close();
160 }
161
162 mainApp->showClosingWidget();
163
164 hide();
165 traySystem->hide();
166
167 saveSettings();
168
169 for (int i = 0; i < stackedWidget_->count(); i++) {
170 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
171 widget->disconnectObjects();
172 }
173
174 mainApp->networkManager()->disconnect(mainApp->networkManager());
175 mainApp->updateFeeds()->disconnectObjects();
176 emit signalQuitApp();
177 }
178
179 // ---------------------------------------------------------------------------
eventFilter(QObject * obj,QEvent * event)180 bool MainWindow::eventFilter(QObject *obj, QEvent *event)
181 {
182 static int deactivateState = 0;
183
184 if (obj == this) {
185 if (event->type() == QEvent::KeyPress) {
186 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
187 if ((keyEvent->key() == Qt::Key_Up) ||
188 (keyEvent->key() == Qt::Key_Down) ||
189 (keyEvent->key() == Qt::Key_Left) ||
190 (keyEvent->key() == Qt::Key_Right)) {
191 QListIterator<QAction *> iter(listActions_);
192 while (iter.hasNext()) {
193 QAction *pAction = iter.next();
194 if (pAction->shortcut() == QKeySequence(keyEvent->key())) {
195 pAction->activate(QAction::Trigger);
196 break;
197 }
198 }
199 }
200 }
201 }
202
203 if (obj == statusBar()) {
204 if (event->type() == QEvent::MouseButtonRelease) {
205 if (windowState() & Qt::WindowMaximized) {
206 QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
207 if ((mouseEvent->pos().x() > (statusBar()->width()-statusBar()->height())) &&
208 (mouseEvent->pos().y() > 0)) {
209 setFullScreen();
210 }
211 }
212 }
213 return false;
214 } else if (obj == categoriesLabel_) {
215 if (event->type() == QEvent::MouseButtonRelease) {
216 showNewsCategoriesTree();
217 }
218 return false;
219 } else if (obj == categoriesTree_) {
220 if (event->type() == QEvent::Show) {
221 recountCategoryCounts();
222 }
223 }
224 else if (event->type() == QEvent::WindowActivate) {
225 activationStateChangedTime_ = QDateTime::currentMSecsSinceEpoch();
226 }
227 // Process open link in browser in background
228 else if (event->type() == QEvent::WindowDeactivate) {
229 if (isOpeningLink_ && openLinkInBackground_) {
230 isOpeningLink_ = false;
231 timerLinkOpening_.start(openingLinkTimeout_);
232 deactivateState = 1;
233 }
234 activationStateChangedTime_ = QDateTime::currentMSecsSinceEpoch();
235 }
236 // deactivation has painted
237 else if ((event->type() == QEvent::Paint) && (deactivateState == 1)) {
238 deactivateState = 2;
239 }
240 // deactivation in done. Reactivating
241 else if ((deactivateState == 2) && timerLinkOpening_.isActive()) {
242 deactivateState = 3;
243 if (!isActiveWindow()) {
244 setWindowState(windowState() & ~Qt::WindowActive);
245 show();
246 raise();
247 activateWindow();
248 }
249 }
250 // activating had painted
251 else if ((deactivateState == 3) && (event->type() == QEvent::Paint)) {
252 deactivateState = 0;
253 } else if (event->type() == QEvent::Hide) {
254 if (minimizingTray_ && showTrayIcon_ && !isMinimizeToTray_) {
255 emit signalPlaceToTray();
256 }
257 }
258
259 // pass the event on to the parent class
260 return QMainWindow::eventFilter(obj, event);
261 }
262
263 /** @brief Process send link to external browser in background
264 *---------------------------------------------------------------------------*/
slotTimerLinkOpening()265 void MainWindow::slotTimerLinkOpening()
266 {
267 timerLinkOpening_.stop();
268 if (!isActiveWindow()) {
269 setWindowState(windowState() & ~Qt::WindowActive);
270 show();
271 raise();
272 activateWindow();
273 }
274 }
275
276 /** @brief Process changing window state
277 *---------------------------------------------------------------------------*/
changeEvent(QEvent * event)278 void MainWindow::changeEvent(QEvent *event)
279 {
280 if (event->type() == QEvent::WindowStateChange) {
281 isOpeningLink_ = false;
282 if (isMinimized()) {
283 oldState = ((QWindowStateChangeEvent*)event)->oldState();
284 } else {
285 oldState = windowState();
286 }
287 } else if (event->type() == QEvent::ActivationChange) {
288 if (isActiveWindow() && (behaviorIconTray_ == CHANGE_ICON_TRAY)) {
289 traySystem->setIcon(QIcon(":/images/quiterss128"));
290 }
291 } else if (event->type() == QEvent::LanguageChange) {
292 retranslateStrings();
293 }
294 QMainWindow::changeEvent(event);
295 }
296
297 /** @brief Process placing to tray event
298 *---------------------------------------------------------------------------*/
slotPlaceToTray()299 void MainWindow::slotPlaceToTray()
300 {
301 isMinimizeToTray_ = true;
302 hide();
303
304 if (emptyWorking_)
305 QTimer::singleShot(10000, this, SLOT(myEmptyWorkingSet()));
306 if (markReadMinimize_)
307 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_, FeedReadPlaceToTray, currentNewsTab);
308 if (clearStatusNew_)
309 QTimer::singleShot(0, this, SIGNAL(signalMarkAllFeedsOld()));
310 clearNotification(true);
311
312 saveSettings();
313
314 mainApp->updateFeeds()->saveMemoryDatabase();
315
316 isMinimizeToTray_ = false;
317 }
318
319 /** @brief Process tray event
320 *---------------------------------------------------------------------------*/
slotActivationTray(QSystemTrayIcon::ActivationReason reason)321 void MainWindow::slotActivationTray(QSystemTrayIcon::ActivationReason reason)
322 {
323 bool activated = false;
324
325 switch (reason) {
326 case QSystemTrayIcon::Unknown:
327 break;
328 case QSystemTrayIcon::Context:
329 trayMenu_->activateWindow();
330 break;
331
332 case QSystemTrayIcon::DoubleClick:
333 {
334 if (!singleClickTray_)
335 {
336 timerTrayOpenNotify.stop();
337
338 if ((QDateTime::currentMSecsSinceEpoch() - activationStateChangedTime_ < 300) || isActiveWindow())
339 {
340 activated = true;
341 }
342
343 showWindows(activated);
344 }
345
346 break;
347 }
348
349 case QSystemTrayIcon::Trigger:
350 {
351 if (singleClickTray_)
352 {
353 qint64 lastActiveChangeTime = QDateTime::currentMSecsSinceEpoch() - activationStateChangedTime_;
354
355 if (isActiveWindow() ? (lastActiveChangeTime >= 200) : (lastActiveChangeTime < 200))
356 {
357 activated = true;
358 }
359
360 showWindows(activated);
361 }
362 else
363 {
364 if (notificationWidget == NULL)
365 {
366 if (!timerTrayOpenNotify.isActive())
367 {
368 timerTrayOpenNotify.start(400);
369 }
370 }
371 else
372 {
373 delete notificationWidget;
374 notificationWidget = NULL;
375 }
376 }
377
378 break;
379 }
380
381 case QSystemTrayIcon::MiddleClick:
382 break;
383 }
384 }
slotTrayOpenNotifyTimer()385 void MainWindow::slotTrayOpenNotifyTimer()
386 {
387 emit signalShowNotification(true);
388 }
389
390 /** @brief Show window on event
391 *---------------------------------------------------------------------------*/
showWindows(bool trayClick)392 void MainWindow::showWindows(bool trayClick)
393 {
394 if (!trayClick || isHidden()) {
395 if (oldState & Qt::WindowFullScreen) {
396 show();
397 } else if (oldState & Qt::WindowMaximized) {
398 showMaximized();
399 } else {
400 showNormal();
401 Settings settings;
402 restoreGeometry(settings.value("GeometryState").toByteArray());
403 }
404 activateWindow();
405 } else {
406 if (minimizingTray_)
407 emit signalPlaceToTray();
408 else
409 showMinimized();
410 }
411 }
412 // ---------------------------------------------------------------------------
createFeedsWidget()413 void MainWindow::createFeedsWidget()
414 {
415 feedsModel_ = new FeedsModel(this);
416
417 feedsProxyModel_ = new FeedsProxyModel(feedsModel_);
418 feedsProxyModel_->setSourceModel(feedsModel_);
419
420 feedsView_ = new FeedsView(this);
421 feedsView_->setModel(feedsProxyModel_);
422 feedsView_->setSourceModel(feedsModel_);
423 feedsModel_->setView(feedsView_);
424
425 for (int i = 0; i < feedsView_->model()->columnCount(); ++i)
426 feedsView_->hideColumn(i);
427 feedsView_->showColumn(feedsView_->columnIndex("text"));
428 #ifdef HAVE_QT5
429 feedsView_->header()->setSectionResizeMode(feedsView_->columnIndex("text"), QHeaderView::Stretch);
430 feedsView_->header()->setSectionResizeMode(feedsView_->columnIndex("unread"), QHeaderView::ResizeToContents);
431 feedsView_->header()->setSectionResizeMode(feedsView_->columnIndex("undeleteCount"), QHeaderView::ResizeToContents);
432 feedsView_->header()->setSectionResizeMode(feedsView_->columnIndex("updated"), QHeaderView::ResizeToContents);
433 #else
434 feedsView_->header()->setResizeMode(feedsView_->columnIndex("text"), QHeaderView::Stretch);
435 feedsView_->header()->setResizeMode(feedsView_->columnIndex("unread"), QHeaderView::ResizeToContents);
436 feedsView_->header()->setResizeMode(feedsView_->columnIndex("undeleteCount"), QHeaderView::ResizeToContents);
437 feedsView_->header()->setResizeMode(feedsView_->columnIndex("updated"), QHeaderView::ResizeToContents);
438 #endif
439
440 feedsToolBar_ = new QToolBar(this);
441 feedsToolBar_->setObjectName("feedsToolBar");
442 feedsToolBar_->setStyleSheet("QToolBar { border: none; padding: 0px; }");
443
444 QHBoxLayout *feedsPanelLayout = new QHBoxLayout();
445 feedsPanelLayout->setMargin(2);
446 feedsPanelLayout->addWidget(feedsToolBar_, 1);
447
448 feedsPanel_ = new QWidget(this);
449 feedsPanel_->setObjectName("feedsPanel_");
450 feedsPanel_->setStyleSheet(
451 QString("#feedsPanel_ {border-bottom: 1px solid %1;}").
452 arg(qApp->palette().color(QPalette::Dark).name()));
453 feedsPanel_->setLayout(feedsPanelLayout);
454
455 findFeeds_ = new FindFeed(this);
456 QVBoxLayout *findFeedsLayout = new QVBoxLayout();
457 findFeedsLayout->setMargin(2);
458 findFeedsLayout->addWidget(findFeeds_);
459 findFeedsWidget_ = new QWidget(this);
460 findFeedsWidget_->hide();
461 findFeedsWidget_->setLayout(findFeedsLayout);
462
463 categoriesTree_ = new CategoriesTreeWidget(this);
464
465 categoriesLabel_ = new QLabel(this);
466 categoriesLabel_->setObjectName("categoriesLabel_");
467
468 showCategoriesButton_ = new ToolButton(this);
469 showCategoriesButton_->setFocusPolicy(Qt::NoFocus);
470 showCategoriesButton_->setMaximumSize(16, 16);
471 showCategoriesButton_->setAutoRaise(true);
472
473 QHBoxLayout *categoriesPanelLayout = new QHBoxLayout();
474 categoriesPanelLayout->setMargin(2);
475 categoriesPanelLayout->addSpacing(2);
476 categoriesPanelLayout->addWidget(categoriesLabel_, 1);
477 categoriesPanelLayout->addWidget(showCategoriesButton_);
478
479 categoriesPanel_ = new QWidget(this);
480 categoriesPanel_->setObjectName("categoriesPanel_");
481 categoriesPanel_->setLayout(categoriesPanelLayout);
482
483 QVBoxLayout *categoriesLayout = new QVBoxLayout();
484 categoriesLayout->setMargin(0);
485 categoriesLayout->setSpacing(0);
486 categoriesLayout->addWidget(categoriesPanel_);
487 categoriesLayout->addWidget(categoriesTree_, 1);
488
489 categoriesWidget_ = new QWidget(this);
490 categoriesWidget_->setLayout(categoriesLayout);
491
492 feedsSplitter_ = new QSplitter(Qt::Vertical);
493 feedsSplitter_->setChildrenCollapsible(false);
494 feedsSplitter_->setHandleWidth(1);
495 feedsSplitter_->setStyleSheet(
496 QString("QSplitter::handle {background: %1;}").
497 arg(qApp->palette().color(QPalette::Dark).name()));
498 feedsSplitter_->addWidget(feedsView_);
499 feedsSplitter_->addWidget(categoriesWidget_);
500 feedsSplitter_->setStretchFactor(0, 1);
501
502 #define CATEGORIES_HEIGHT 210
503 QList <int> sizes;
504 sizes << QApplication::desktop()->height() << CATEGORIES_HEIGHT;
505 feedsSplitter_->setSizes(sizes);
506
507 QVBoxLayout *feedsLayout = new QVBoxLayout();
508 feedsLayout->setMargin(0);
509 feedsLayout->setSpacing(0);
510 feedsLayout->addWidget(feedsPanel_);
511 feedsLayout->addWidget(findFeedsWidget_);
512 feedsLayout->addWidget(feedsSplitter_, 1);
513
514 feedsWidget_ = new QFrame(this);
515 feedsWidget_->setFrameStyle(QFrame::NoFrame);
516 feedsWidget_->setLayout(feedsLayout);
517
518 connect(feedsView_, SIGNAL(pressed(QModelIndex)),
519 this, SLOT(slotFeedClicked(QModelIndex)));
520 connect(feedsView_, SIGNAL(signalMiddleClicked()),
521 this, SLOT(slotOpenFeedNewTab()));
522 connect(feedsView_, SIGNAL(signalDoubleClicked()),
523 this, SLOT(slotGetFeed()));
524 connect(feedsView_, SIGNAL(pressKeyUp()), this, SLOT(slotFeedUpPressed()));
525 connect(feedsView_, SIGNAL(pressKeyDown()), this, SLOT(slotFeedDownPressed()));
526 connect(feedsView_, SIGNAL(pressKeyHome()), this, SLOT(slotFeedHomePressed()));
527 connect(feedsView_, SIGNAL(pressKeyEnd()), this, SLOT(slotFeedEndPressed()));
528 connect(feedsView_, SIGNAL(pressKeyPageUp()), this, SLOT(slotFeedPageUpPressed()));
529 connect(feedsView_, SIGNAL(pressKeyPageDown()), this, SLOT(slotFeedPageDownPressed()));
530 connect(feedsView_, SIGNAL(signalDropped(QModelIndex,int)),
531 this, SLOT(slotMoveIndex(QModelIndex,int)));
532 connect(feedsView_, SIGNAL(customContextMenuRequested(QPoint)),
533 this, SLOT(showContextMenuFeed(const QPoint &)));
534
535 connect(findFeeds_, SIGNAL(textChanged(QString)),
536 this, SLOT(slotFindFeeds(QString)));
537 connect(findFeeds_, SIGNAL(signalSelectFind()),
538 this, SLOT(slotSelectFind()));
539 connect(findFeeds_, SIGNAL(returnPressed()),
540 this, SLOT(slotSelectFind()));
541 connect(findFeeds_, SIGNAL(signalVisible(bool)),
542 this, SLOT(findFeedVisible(bool)));
543
544 connect(categoriesTree_, SIGNAL(itemPressed(QTreeWidgetItem*,int)),
545 this, SLOT(slotCategoriesClicked(QTreeWidgetItem*,int)));
546 connect(categoriesTree_, SIGNAL(signalMiddleClicked()),
547 this, SLOT(slotOpenCategoryNewTab()));
548 connect(categoriesTree_, SIGNAL(signalClearDeleted()),
549 this, SLOT(clearDeleted()));
550 connect(categoriesTree_, SIGNAL(signalMarkRead(QTreeWidgetItem*)),
551 this, SLOT(slotMarkReadCategory(QTreeWidgetItem*)));
552 connect(showCategoriesButton_, SIGNAL(clicked()),
553 this, SLOT(showNewsCategoriesTree()));
554 connect(feedsSplitter_, SIGNAL(splitterMoved(int,int)),
555 this, SLOT(feedsSplitterMoved(int,int)));
556
557 categoriesLabel_->installEventFilter(this);
558 categoriesTree_->installEventFilter(this);
559 }
560 // ---------------------------------------------------------------------------
createToolBarNull()561 void MainWindow::createToolBarNull()
562 {
563 pushButtonNull_ = new QPushButton(this);
564 pushButtonNull_->setObjectName("pushButtonNull");
565 pushButtonNull_->setIcon(QIcon(":/images/images/triangleR.png"));
566 pushButtonNull_->setFixedWidth(6);
567 pushButtonNull_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
568 pushButtonNull_->setFocusPolicy(Qt::NoFocus);
569 }
570 // ---------------------------------------------------------------------------
createNewsTab(int index)571 void MainWindow::createNewsTab(int index)
572 {
573 currentNewsTab = (NewsTabWidget*)stackedWidget_->widget(index);
574 currentNewsTab->setSettings();
575 currentNewsTab->retranslateStrings();
576 currentNewsTab->setBrowserPosition();
577
578 newsModel_ = currentNewsTab->newsModel_;
579 newsView_ = currentNewsTab->newsView_;
580 }
581 // ---------------------------------------------------------------------------
createStatusBar()582 void MainWindow::createStatusBar()
583 {
584 #if defined(HAVE_X11) || defined(Q_OS_MAC)
585 statusBar()->setStyleSheet(QString("QStatusBar::item {border-right: 1px solid %1;"
586 "margin: 1px;}").
587 arg(qApp->palette().color(QPalette::Dark).name()));
588 #endif
589
590 progressBar_ = new QProgressBar(this);
591 progressBar_->setObjectName("progressBar_");
592 progressBar_->setFormat("%p%");
593 progressBar_->setAlignment(Qt::AlignCenter);
594 progressBar_->setFixedWidth(100);
595 progressBar_->setFixedHeight(15);
596 progressBar_->setMinimum(0);
597 progressBar_->setMaximum(0);
598 progressBar_->setValue(0);
599 progressBar_->setVisible(false);
600
601 QToolButton *stopUpdateButton_ = new QToolButton(progressBar_);
602 stopUpdateButton_->setFocusPolicy(Qt::NoFocus);
603 stopUpdateButton_->setToolButtonStyle(Qt::ToolButtonIconOnly);
604 stopUpdateButton_->setFixedSize(15, 15);
605 stopUpdateButton_->setCursor(Qt::ArrowCursor);
606 stopUpdateButton_->setDefaultAction(stopUpdateAct_);
607 stopUpdateButton_->setStyleSheet(
608 "QToolButton { border: none; padding: 0px; background: none; }"
609 "QToolButton:hover { background: rgba(150, 150, 150, 60) }"
610 );
611 stopUpdateButton_->move(progressBar_->rect().right() - stopUpdateButton_->sizeHint().width(),
612 progressBar_->rect().top());
613
614
615 adblockIcon_ = new AdBlockIcon(this);
616
617 QToolButton *loadImagesButton = new QToolButton(this);
618 loadImagesButton->setFocusPolicy(Qt::NoFocus);
619 loadImagesButton->setIconSize(QSize(16,16));
620 loadImagesButton->setDefaultAction(autoLoadImagesToggle_);
621 loadImagesButton->setStyleSheet("QToolButton { border: none; padding: 0px; background: none; }");
622
623 QToolButton *fullScreenButton = new QToolButton(this);
624 fullScreenButton->setFocusPolicy(Qt::NoFocus);
625 loadImagesButton->setIconSize(QSize(16,16));
626 fullScreenButton->setDefaultAction(fullScreenAct_);
627 fullScreenButton->setStyleSheet("QToolButton { border: none; padding: 0px; background: none; }");
628 statusBar()->installEventFilter(this);
629
630 statusBar()->addPermanentWidget(progressBar_);
631 statusUnread_ = new QLabel(this);
632 statusUnread_->hide();
633 statusBar()->addPermanentWidget(statusUnread_);
634 statusAll_ = new QLabel(this);
635 statusAll_->hide();
636 statusBar()->addPermanentWidget(statusAll_);
637 statusBar()->addPermanentWidget(adblockIcon_);
638 statusBar()->addPermanentWidget(loadImagesButton);
639 statusBar()->addPermanentWidget(fullScreenButton);
640 statusBar()->setVisible(true);
641 }
642 // ---------------------------------------------------------------------------
createTray()643 void MainWindow::createTray()
644 {
645 traySystem = new QSystemTrayIcon(QIcon(":/images/quiterss128"), this);
646 traySystem->setToolTip("QuiteRSS");
647
648 #ifndef Q_OS_MAC
649 connect(traySystem,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
650 this, SLOT(slotActivationTray(QSystemTrayIcon::ActivationReason)));
651 connect(this, SIGNAL(signalPlaceToTray()),
652 this, SLOT(slotPlaceToTray()), Qt::QueuedConnection);
653 #endif
654
655 createTrayMenu();
656 }
657
658 /** @brief Create tabbar widget
659 *---------------------------------------------------------------------------*/
createTabBarWidget()660 void MainWindow::createTabBarWidget()
661 {
662 mainMenuButton_ = new ToolButton(this);
663 mainMenuButton_->setObjectName("mainMenuButton");
664 mainMenuButton_->setIcon(QIcon(":/images/menu"));
665
666 tabBar_ = new TabBar();
667
668 QHBoxLayout *tabBarLayout = new QHBoxLayout();
669 tabBarLayout->setContentsMargins(0, 0, 0, 0);
670 tabBarLayout->setSpacing(0);
671 tabBarLayout->addWidget(mainMenuButton_);
672 tabBarLayout->addSpacing(5);
673 tabBarLayout->addWidget(tabBar_, 1);
674
675 tabBarWidget_ = new QWidget(this);
676 tabBarWidget_->setObjectName("tabBarWidget");
677 tabBarWidget_->setMinimumHeight(1);
678 tabBarWidget_->setLayout(tabBarLayout);
679
680 connect(mainMenuButton_, SIGNAL(clicked()), this, SLOT(showMainMenu()));
681 connect(tabBar_, SIGNAL(closeTab(int)),
682 this, SLOT(slotCloseTab(int)));
683 connect(tabBar_, SIGNAL(currentChanged(int)),
684 this, SLOT(slotTabCurrentChanged(int)), Qt::QueuedConnection);
685 connect(tabBar_, SIGNAL(tabMoved(int,int)),
686 SLOT(slotTabMoved(int,int)));
687 connect(this, SIGNAL(signalSetCurrentTab(int,bool)),
688 SLOT(setCurrentTab(int,bool)), Qt::QueuedConnection);
689
690 connect(closeTabAct_, SIGNAL(triggered()), tabBar_, SLOT(slotCloseTab()));
691 connect(closeOtherTabsAct_, SIGNAL(triggered()),
692 tabBar_, SLOT(slotCloseOtherTabs()));
693 connect(closeAllTabsAct_, SIGNAL(triggered()),
694 tabBar_, SLOT(slotCloseAllTab()));
695 connect(nextTabAct_, SIGNAL(triggered()), tabBar_, SLOT(slotNextTab()));
696 connect(prevTabAct_, SIGNAL(triggered()), tabBar_, SLOT(slotPrevTab()));
697 }
698
createCentralWidget()699 void MainWindow::createCentralWidget()
700 {
701 stackedWidget_ = new QStackedWidget(this);
702 stackedWidget_->setObjectName("stackedWidget_");
703 stackedWidget_->setFrameStyle(QFrame::NoFrame);
704
705 mainSplitter_ = new QSplitter(this);
706 mainSplitter_ ->setFrameStyle(QFrame::NoFrame);
707 mainSplitter_->setHandleWidth(1);
708 mainSplitter_->setStyleSheet(
709 QString("QSplitter::handle {background: qlineargradient("
710 "x1: 0, y1: 0, x2: 0, y2: 1,"
711 "stop: 0 %1, stop: 0.07 %2);}").
712 arg(feedsPanel_->palette().background().color().name()).
713 arg(qApp->palette().color(QPalette::Dark).name()));
714 mainSplitter_->setChildrenCollapsible(false);
715 mainSplitter_->addWidget(feedsWidget_);
716 mainSplitter_->addWidget(stackedWidget_);
717 mainSplitter_->setStretchFactor(1, 1);
718
719 #define FEEDS_WIDTH 180
720 QList <int> sizes;
721 sizes << FEEDS_WIDTH << QApplication::desktop()->width();
722 mainSplitter_->setSizes(sizes);
723
724 QHBoxLayout *mainLayout1 = new QHBoxLayout();
725 mainLayout1->addWidget(pushButtonNull_);
726 mainLayout1->addWidget(mainSplitter_, 1);
727
728 QVBoxLayout *mainLayout = new QVBoxLayout();
729 mainLayout->setMargin(0);
730 mainLayout->setSpacing(0);
731 mainLayout->addWidget(tabBarWidget_);
732 mainLayout->addLayout(mainLayout1, 1);
733
734 centralWidget_ = new QWidget(this);
735 centralWidget_->setLayout(mainLayout);
736
737 setCentralWidget(centralWidget_);
738 }
739
740 /** @brief Create actions for main menu and toolbar
741 *---------------------------------------------------------------------------*/
createActions()742 void MainWindow::createActions()
743 {
744 addAct_ = new QAction(this);
745 addAct_->setObjectName("newAct");
746 addAct_->setIcon(QIcon(":/images/add"));
747 this->addAction(addAct_);
748 connect(addAct_, SIGNAL(triggered()), this, SLOT(addFeed()));
749
750 addFeedAct_ = new QAction(this);
751 addFeedAct_->setObjectName("addFeedAct");
752 addFeedAct_->setIcon(QIcon(":/images/feed"));
753 this->addAction(addFeedAct_);
754 connect(addFeedAct_, SIGNAL(triggered()), this, SLOT(addFeed()));
755
756 addFeedTrayAct_ = new QAction(this);
757 addFeedTrayAct_->setIcon(QIcon(":/images/feed"));
758 connect(addFeedTrayAct_, SIGNAL(triggered()), this, SLOT(addFeed()));
759
760 addFolderAct_ = new QAction(this);
761 addFolderAct_->setObjectName("addFolderAct");
762 addFolderAct_->setIcon(QIcon(":/images/folder"));
763 this->addAction(addFolderAct_);
764 connect(addFolderAct_, SIGNAL(triggered()), this, SLOT(addFolder()));
765
766 openFeedNewTabAct_ = new QAction(this);
767 openFeedNewTabAct_->setObjectName("openNewTabAct");
768 this->addAction(openFeedNewTabAct_);
769 connect(openFeedNewTabAct_, SIGNAL(triggered()), this, SLOT(slotOpenFeedNewTab()));
770
771 deleteFeedAct_ = new QAction(this);
772 deleteFeedAct_->setObjectName("deleteFeedAct");
773 deleteFeedAct_->setIcon(QIcon(":/images/delete"));
774 this->addAction(deleteFeedAct_);
775 connect(deleteFeedAct_, SIGNAL(triggered()), this, SLOT(deleteItemFeedsTree()));
776
777 importFeedsAct_ = new QAction(this);
778 importFeedsAct_->setObjectName("importFeedsAct");
779 importFeedsAct_->setIcon(QIcon(":/images/importFeeds"));
780 this->addAction(importFeedsAct_);
781 connect(importFeedsAct_, SIGNAL(triggered()), this, SLOT(slotImportFeeds()));
782
783 exportFeedsAct_ = new QAction(this);
784 exportFeedsAct_->setObjectName("exportFeedsAct");
785 exportFeedsAct_->setIcon(QIcon(":/images/exportFeeds"));
786 this->addAction(exportFeedsAct_);
787 connect(exportFeedsAct_, SIGNAL(triggered()), this, SLOT(slotExportFeeds()));
788
789 createBackupAct_ = new QAction(this);
790 createBackupAct_->setObjectName("createBackupAct");
791 createBackupAct_->setIcon(QIcon(":/images/backup"));
792 this->addAction(createBackupAct_);
793 connect(createBackupAct_, SIGNAL(triggered()), this, SLOT(createBackup()));
794
795 showMenuBarAct_ = new QAction(this);
796 showMenuBarAct_->setCheckable(true);
797 connect(showMenuBarAct_, SIGNAL(triggered()), this, SLOT(showMenuBar()));
798
799 exitAct_ = new QAction(this);
800 exitAct_->setObjectName("exitAct");
801 this->addAction(exitAct_);
802 connect(exitAct_, SIGNAL(triggered()), this, SLOT(quitApp()));
803
804 mainToolbarToggle_ = new QAction(this);
805 mainToolbarToggle_->setCheckable(true);
806 feedsToolbarToggle_ = new QAction(this);
807 feedsToolbarToggle_->setCheckable(true);
808 newsToolbarToggle_ = new QAction(this);
809 newsToolbarToggle_->setCheckable(true);
810 browserToolbarToggle_ = new QAction(this);
811 browserToolbarToggle_->setCheckable(true);
812 categoriesPanelToggle_ = new QAction(this);
813 categoriesPanelToggle_->setCheckable(true);
814 statusBarToggle_ = new QAction(this);
815 statusBarToggle_->setCheckable(true);
816
817 connect(feedsToolbarToggle_, SIGNAL(toggled(bool)),
818 feedsPanel_, SLOT(setVisible(bool)));
819 connect(categoriesPanelToggle_, SIGNAL(toggled(bool)),
820 categoriesWidget_, SLOT(setVisible(bool)));
821 connect(statusBarToggle_, SIGNAL(toggled(bool)),
822 statusBar(), SLOT(setVisible(bool)));
823
824 customizeMainToolbarAct_ = new QAction(this);
825 customizeMainToolbarAct_->setObjectName("customizeMainToolbarAct");
826 customizeMainToolbarAct2_ = new QAction(this);
827 connect(customizeMainToolbarAct2_, SIGNAL(triggered()),
828 this, SLOT(customizeMainToolbar()));
829
830 toolBarLockAct_ = new QAction(this);
831 toolBarLockAct_->setCheckable(true);
832 toolBarHideAct_ = new QAction(this);
833
834 customizeFeedsToolbarAct_ = new QAction(this);
835 customizeFeedsToolbarAct_->setObjectName("customizeFeedsToolbarAct");
836
837 customizeNewsToolbarAct_ = new QAction(this);
838 customizeNewsToolbarAct_->setObjectName("customizeNewsToolbarAct");
839
840 classicLayoutAct_ = new QAction(this);
841 classicLayoutAct_->setObjectName("classicLayoutAct_");
842 classicLayoutAct_->setIcon(QIcon(":/images/layout_classic"));
843 classicLayoutAct_->setCheckable(true);
844 classicLayoutAct_->setData(0);
845 newspaperLayoutAct_ = new QAction(this);
846 newspaperLayoutAct_->setObjectName("newspaperLayoutAct_");
847 newspaperLayoutAct_->setIcon(QIcon(":/images/layout_newspaper"));
848 newspaperLayoutAct_->setCheckable(true);
849 newspaperLayoutAct_->setData(1);
850 layoutToggle_ = new QAction(this);
851 layoutToggle_->setObjectName("layoutToggle");
852 layoutToggle_->setIcon(QIcon(":/images/layout_classic"));
853 this->addAction(layoutToggle_);
854 connect(layoutToggle_, SIGNAL(triggered()),
855 this, SLOT(setNewsLayout()));
856
857 systemStyle_ = new QAction(this);
858 systemStyle_->setObjectName("systemStyle_");
859 systemStyle_->setCheckable(true);
860 system2Style_ = new QAction(this);
861 system2Style_->setObjectName("system2Style_");
862 system2Style_->setCheckable(true);
863 darkStyle_ = new QAction(this);
864 darkStyle_->setObjectName("darkStyle_");
865 darkStyle_->setCheckable(true);
866 greenStyle_ = new QAction(this);
867 greenStyle_->setObjectName("greenStyle_");
868 greenStyle_->setCheckable(true);
869 greenStyle_->setChecked(true);
870 orangeStyle_ = new QAction(this);
871 orangeStyle_->setObjectName("orangeStyle_");
872 orangeStyle_->setCheckable(true);
873 purpleStyle_ = new QAction(this);
874 purpleStyle_->setObjectName("purpleStyle_");
875 purpleStyle_->setCheckable(true);
876 pinkStyle_ = new QAction(this);
877 pinkStyle_->setObjectName("pinkStyle_");
878 pinkStyle_->setCheckable(true);
879 grayStyle_ = new QAction(this);
880 grayStyle_->setObjectName("grayStyle_");
881 grayStyle_->setCheckable(true);
882
883 topBrowserPositionAct_ = new QAction(this);
884 topBrowserPositionAct_->setCheckable(true);
885 topBrowserPositionAct_->setData(TOP_POSITION);
886 bottomBrowserPositionAct_ = new QAction(this);
887 bottomBrowserPositionAct_->setCheckable(true);
888 bottomBrowserPositionAct_->setData(BOTTOM_POSITION);
889 rightBrowserPositionAct_ = new QAction(this);
890 rightBrowserPositionAct_->setCheckable(true);
891 rightBrowserPositionAct_->setData(RIGHT_POSITION);
892 leftBrowserPositionAct_ = new QAction(this);
893 leftBrowserPositionAct_->setCheckable(true);
894 leftBrowserPositionAct_->setData(LEFT_POSITION);
895
896 autoLoadImagesToggle_ = new QAction(this);
897 autoLoadImagesToggle_->setObjectName("autoLoadImagesToggle");
898 autoLoadImagesToggle_->setIcon(QIcon(":/images/imagesOn"));
899 this->addAction(autoLoadImagesToggle_);
900
901 printAct_ = new QAction(this);
902 printAct_->setObjectName("printAct");
903 printAct_->setIcon(QIcon(":/images/printer"));
904 this->addAction(printAct_);
905 connect(printAct_, SIGNAL(triggered()), this, SLOT(slotPrint()));
906 printPreviewAct_ = new QAction(this);
907 printPreviewAct_->setObjectName("printPreviewAct");
908 printPreviewAct_->setIcon(QIcon(":/images/printer"));
909 this->addAction(printPreviewAct_);
910 connect(printPreviewAct_, SIGNAL(triggered()), this, SLOT(slotPrintPreview()));
911
912 savePageAsAct_ = new QAction(this);
913 savePageAsAct_->setObjectName("savePageAsAct");
914 savePageAsAct_->setIcon(QIcon(":/images/save_as"));
915 this->addAction(savePageAsAct_);
916 connect(savePageAsAct_, SIGNAL(triggered()), this, SLOT(slotSavePageAs()));
917
918 savePageAsDescriptAct_ = new QAction(this);
919 savePageAsDescriptAct_->setObjectName("savePageAsDescriptAct");
920 savePageAsDescriptAct_->setIcon(QIcon(":/images/save_as"));
921 this->addAction(savePageAsDescriptAct_);
922 connect(savePageAsDescriptAct_, SIGNAL(triggered()),
923 this, SLOT(slotSavePageAsDescript()));
924
925 zoomInAct_ = new QAction(this);
926 zoomInAct_->setObjectName("zoomInAct");
927 zoomInAct_->setIcon(QIcon(":/images/zoomIn"));
928 this->addAction(zoomInAct_);
929 zoomOutAct_ = new QAction(this);
930 zoomOutAct_->setObjectName("zoomOutAct");
931 zoomOutAct_->setIcon(QIcon(":/images/zoomOut"));
932 this->addAction(zoomOutAct_);
933 zoomTo100Act_ = new QAction(this);
934 zoomTo100Act_->setObjectName("zoomTo100Act");
935 this->addAction(zoomTo100Act_);
936
937 updateFeedAct_ = new QAction(this);
938 updateFeedAct_->setObjectName("updateFeedAct");
939 updateFeedAct_->setIcon(QIcon(":/images/updateFeed"));
940 this->addAction(updateFeedAct_);
941 connect(updateFeedAct_, SIGNAL(triggered()), this, SLOT(slotGetFeed()));
942
943 updateAllFeedsAct_ = new QAction(this);
944 updateAllFeedsAct_->setObjectName("updateAllFeedsAct");
945 updateAllFeedsAct_->setIcon(QIcon(":/images/updateAllFeeds"));
946 this->addAction(updateAllFeedsAct_);
947 connect(updateAllFeedsAct_, SIGNAL(triggered()), this, SLOT(slotGetAllFeeds()));
948
949 stopUpdateAct_ = new QAction(this);
950 stopUpdateAct_->setObjectName("stopUpdateAct");
951 stopUpdateAct_->setIcon(QIcon(":/images/close"));
952 this->addAction(stopUpdateAct_);
953 connect(stopUpdateAct_, SIGNAL(triggered()), this, SLOT(slotStopUpdate()));
954
955 markAllFeedsRead_ = new QAction(this);
956 markAllFeedsRead_->setObjectName("markAllFeedRead");
957 markAllFeedsRead_->setIcon(QIcon(":/images/markReadAll"));
958 this->addAction(markAllFeedsRead_);
959 connect(markAllFeedsRead_, SIGNAL(triggered()), this, SIGNAL(signalMarkAllFeedsRead()));
960
961 indentationFeedsTreeAct_ = new QAction(this);
962 indentationFeedsTreeAct_->setCheckable(true);
963 connect(indentationFeedsTreeAct_, SIGNAL(triggered()),
964 this, SLOT(slotIndentationFeedsTree()));
965
966 sortedByTitleFeedsTreeAct_ = new QAction(this);
967 connect(sortedByTitleFeedsTreeAct_, SIGNAL(triggered()),
968 this, SLOT(sortedByTitleFeedsTree()));
969
970 collapseAllFoldersAct_ = new QAction(this);
971 collapseAllFoldersAct_->setObjectName("collapseAllFolderAct");
972 collapseAllFoldersAct_->setIcon(QIcon(":/images/bulletMinus"));
973 this->addAction(collapseAllFoldersAct_);
974 connect(collapseAllFoldersAct_, SIGNAL(triggered()),
975 feedsView_, SLOT(collapseAll()));
976
977 expandAllFoldersAct_ = new QAction(this);
978 expandAllFoldersAct_->setObjectName("expandAllFolderAct");
979 expandAllFoldersAct_->setIcon(QIcon(":/images/bulletPlus"));
980 this->addAction(expandAllFoldersAct_);
981 connect(expandAllFoldersAct_, SIGNAL(triggered()),
982 feedsView_, SLOT(expandAll()));
983
984 markNewsRead_ = new QAction(this);
985 markNewsRead_->setObjectName("markNewsRead");
986 markNewsRead_->setIcon(QIcon(":/images/markRead"));
987 this->addAction(markNewsRead_);
988
989 markAllNewsRead_ = new QAction(this);
990 markAllNewsRead_->setObjectName("markAllNewsRead");
991 markAllNewsRead_->setIcon(QIcon(":/images/markReadAll"));
992 this->addAction(markAllNewsRead_);
993
994 showDownloadManagerAct_ = new QAction(this);
995 showDownloadManagerAct_->setObjectName("showDownloadManagerAct");
996 showDownloadManagerAct_->setIcon(QIcon(":/images/download"));
997 this->addAction(showDownloadManagerAct_);
998 connect(showDownloadManagerAct_, SIGNAL(triggered()), this, SLOT(showDownloadManager()));
999
1000 showCleanUpWizardAct_ = new QAction(this);
1001 showCleanUpWizardAct_->setObjectName("showCleanUpWizardAct");
1002 showCleanUpWizardAct_->setIcon(QIcon(":/images/cleanup"));
1003 this->addAction(showCleanUpWizardAct_);
1004 connect(showCleanUpWizardAct_, SIGNAL(triggered()), this, SLOT(cleanUp()));
1005
1006 setNewsFiltersAct_ = new QAction(this);
1007 setNewsFiltersAct_->setObjectName("setNewsFiltersAct");
1008 setNewsFiltersAct_->setIcon(QIcon(":/images/filterOff"));
1009 this->addAction(setNewsFiltersAct_);
1010 connect(setNewsFiltersAct_, SIGNAL(triggered()), this, SLOT(showNewsFiltersDlg()));
1011 setFilterNewsAct_ = new QAction(this);
1012 setFilterNewsAct_->setObjectName("setFilterNewsAct");
1013 setFilterNewsAct_->setIcon(QIcon(":/images/filterOff"));
1014 this->addAction(setFilterNewsAct_);
1015 connect(setFilterNewsAct_, SIGNAL(triggered()), this, SLOT(showFilterRulesDlg()));
1016
1017 optionsAct_ = new QAction(this);
1018 optionsAct_->setObjectName("optionsAct");
1019 optionsAct_->setIcon(QIcon(":/images/options"));
1020 this->addAction(optionsAct_);
1021 connect(optionsAct_, SIGNAL(triggered()), this, SLOT(showOptionDlg()));
1022
1023 feedsFilter_ = new QAction(this);
1024 feedsFilter_->setObjectName("feedsFilter");
1025 feedsFilter_->setIcon(QIcon(":/images/filterOff"));
1026 this->addAction(feedsFilter_);
1027 filterFeedsAll_ = new QAction(this);
1028 filterFeedsAll_->setObjectName("filterFeedsAll_");
1029 filterFeedsAll_->setCheckable(true);
1030 filterFeedsAll_->setChecked(true);
1031 filterFeedsNew_ = new QAction(this);
1032 filterFeedsNew_->setObjectName("filterFeedsNew_");
1033 filterFeedsNew_->setCheckable(true);
1034 filterFeedsUnread_ = new QAction(this);
1035 filterFeedsUnread_->setObjectName("filterFeedsUnread_");
1036 filterFeedsUnread_->setCheckable(true);
1037 filterFeedsStarred_ = new QAction(this);
1038 filterFeedsStarred_->setObjectName("filterFeedsStarred_");
1039 filterFeedsStarred_->setCheckable(true);
1040 filterFeedsError_ = new QAction(this);
1041 filterFeedsError_->setObjectName("filterFeedsError_");
1042 filterFeedsError_->setCheckable(true);
1043
1044 newsFilter_ = new QAction(this);
1045 newsFilter_->setObjectName("newsFilter");
1046 newsFilter_->setIcon(QIcon(":/images/filterOff"));
1047 this->addAction(newsFilter_);
1048 filterNewsAll_ = new QAction(this);
1049 filterNewsAll_->setObjectName("filterNewsAll_");
1050 filterNewsAll_->setCheckable(true);
1051 filterNewsAll_->setChecked(true);
1052 filterNewsNew_ = new QAction(this);
1053 filterNewsNew_->setObjectName("filterNewsNew_");
1054 filterNewsNew_->setCheckable(true);
1055 filterNewsUnread_ = new QAction(this);
1056 filterNewsUnread_->setObjectName("filterNewsUnread_");
1057 filterNewsUnread_->setCheckable(true);
1058 filterNewsStar_ = new QAction(this);
1059 filterNewsStar_->setObjectName("filterNewsStar_");
1060 filterNewsStar_->setCheckable(true);
1061 filterNewsNotStarred_ = new QAction(this);
1062 filterNewsNotStarred_->setObjectName("filterNewsNotStarred_");
1063 filterNewsNotStarred_->setCheckable(true);
1064 filterNewsUnreadStar_ = new QAction(this);
1065 filterNewsUnreadStar_->setObjectName("filterNewsUnreadStar_");
1066 filterNewsUnreadStar_->setCheckable(true);
1067 filterNewsLastDay_ = new QAction(this);
1068 filterNewsLastDay_->setObjectName("filterNewsLastDay_");
1069 filterNewsLastDay_->setCheckable(true);
1070 filterNewsLastWeek_ = new QAction(this);
1071 filterNewsLastWeek_->setObjectName("filterNewsLastWeek_");
1072 filterNewsLastWeek_->setCheckable(true);
1073
1074 newsSortByColumnGroup_ = new QActionGroup(this);
1075 newsSortByColumnGroup_->setExclusive(true);
1076 connect(newsSortByColumnGroup_, SIGNAL(triggered(QAction*)),
1077 this, SLOT(setNewsSortByColumn()));
1078
1079 newsSortOrderGroup_ = new QActionGroup(this);
1080 newsSortOrderGroup_->setExclusive(true);
1081 QStringList listAct;
1082 listAct << "sortOrderAsc" << "sortOrderDesc";
1083 foreach (QString actionStr, listAct) {
1084 QAction *newsSortOrderAct = new QAction(this);
1085 newsSortOrderAct->setObjectName(actionStr);
1086 newsSortOrderAct->setCheckable(true);
1087 newsSortOrderGroup_->addAction(newsSortOrderAct);
1088 }
1089 connect(newsSortOrderGroup_, SIGNAL(triggered(QAction*)),
1090 this, SLOT(setNewsSortByColumn()));
1091
1092 aboutAct_ = new QAction(this);
1093 aboutAct_->setObjectName("AboutAct_");
1094 connect(aboutAct_, SIGNAL(triggered()), this, SLOT(slotShowAboutDlg()));
1095
1096 updateAppAct_ = new QAction(this);
1097 updateAppAct_->setObjectName("UpdateApp_");
1098 connect(updateAppAct_, SIGNAL(triggered()), this, SLOT(slotShowUpdateAppDlg()));
1099
1100 reportProblemAct_ = new QAction(this);
1101 reportProblemAct_->setObjectName("reportProblemAct_");
1102 connect(reportProblemAct_, SIGNAL(triggered()), this, SLOT(slotReportProblem()));
1103
1104 openInBrowserAct_ = new QAction(this);
1105 openInBrowserAct_->setObjectName("openInBrowserAct");
1106 this->addAction(openInBrowserAct_);
1107
1108 openInExternalBrowserAct_ = new QAction(this);
1109 openInExternalBrowserAct_->setObjectName("openInExternalBrowserAct");
1110 openInExternalBrowserAct_->setIcon(QIcon(":/images/openBrowser"));
1111 this->addAction(openInExternalBrowserAct_);
1112
1113 openNewsNewTabAct_ = new QAction(this);
1114 openNewsNewTabAct_->setObjectName("openInNewTabAct");
1115 openNewsNewTabAct_->setIcon(QIcon(":/images/images/tab_go.png"));
1116 this->addAction(openNewsNewTabAct_);
1117 openNewsBackgroundTabAct_ = new QAction(this);
1118 openNewsBackgroundTabAct_->setObjectName("openInBackgroundTabAct");
1119 this->addAction(openNewsBackgroundTabAct_);
1120
1121 markStarAct_ = new QAction(this);
1122 markStarAct_->setObjectName("markStarAct");
1123 markStarAct_->setIcon(QIcon(":/images/starOn"));
1124 this->addAction(markStarAct_);
1125
1126 deleteNewsAct_ = new QAction(this);
1127 deleteNewsAct_->setObjectName("deleteNewsAct");
1128 deleteNewsAct_->setIcon(QIcon(":/images/delete"));
1129 this->addAction(deleteNewsAct_);
1130 deleteAllNewsAct_ = new QAction(this);
1131 deleteAllNewsAct_->setObjectName("deleteAllNewsAct");
1132 this->addAction(deleteAllNewsAct_);
1133
1134 restoreNewsAct_ = new QAction(this);
1135 restoreNewsAct_->setObjectName("restoreNewsAct");
1136 restoreNewsAct_->setIcon(QIcon(":/images/images/arrow_turn_left.png"));
1137
1138 restoreLastNewsAct_ = new QAction(this);
1139 restoreLastNewsAct_->setObjectName("restoreLastNewsAct");
1140 restoreLastNewsAct_->setIcon(QIcon(":/images/images/arrow_turn_left.png"));
1141 this->addAction(restoreLastNewsAct_);
1142 connect(restoreLastNewsAct_, SIGNAL(triggered()), this, SLOT(restoreLastNews()));
1143
1144 markFeedRead_ = new QAction(this);
1145 markFeedRead_->setObjectName("markFeedRead");
1146 markFeedRead_->setIcon(QIcon(":/images/markRead"));
1147 this->addAction(markFeedRead_);
1148 connect(markFeedRead_, SIGNAL(triggered()), this, SLOT(markFeedRead()));
1149
1150 feedProperties_ = new QAction(this);
1151 feedProperties_->setObjectName("feedProperties");
1152 feedProperties_->setIcon(QIcon(":/images/preferencesFeed"));
1153 this->addAction(feedProperties_);
1154 connect(feedProperties_, SIGNAL(triggered()), this, SLOT(showFeedPropertiesDlg()));
1155
1156 feedKeyUpAct_ = new QAction(this);
1157 feedKeyUpAct_->setObjectName("feedKeyUp");
1158 connect(feedKeyUpAct_, SIGNAL(triggered()), this, SLOT(slotFeedPrevious()));
1159 this->addAction(feedKeyUpAct_);
1160
1161 feedKeyDownAct_ = new QAction(this);
1162 feedKeyDownAct_->setObjectName("feedKeyDownAct");
1163 connect(feedKeyDownAct_, SIGNAL(triggered()), this, SLOT(slotFeedNext()));
1164 this->addAction(feedKeyDownAct_);
1165
1166 newsKeyUpAct_ = new QAction(this);
1167 newsKeyUpAct_->setObjectName("newsKeyUpAct");
1168 this->addAction(newsKeyUpAct_);
1169 newsKeyDownAct_ = new QAction(this);
1170 newsKeyDownAct_->setObjectName("newsKeyDownAct");
1171 this->addAction(newsKeyDownAct_);
1172 newsKeyPageUpAct_ = new QAction(this);
1173 newsKeyPageUpAct_->setObjectName("newsKeyPageUpAct");
1174 this->addAction(newsKeyPageUpAct_);
1175 newsKeyPageDownAct_ = new QAction(this);
1176 newsKeyPageDownAct_->setObjectName("newsKeyPageDownAct");
1177 this->addAction(newsKeyPageDownAct_);
1178
1179 switchFocusAct_ = new QAction(this);
1180 switchFocusAct_->setObjectName("switchFocusAct");
1181 connect(switchFocusAct_, SIGNAL(triggered()), this, SLOT(slotSwitchFocus()));
1182 this->addAction(switchFocusAct_);
1183 switchFocusPrevAct_ = new QAction(this);
1184 switchFocusPrevAct_->setObjectName("switchFocusPrevAct");
1185 connect(switchFocusPrevAct_, SIGNAL(triggered()), this, SLOT(slotSwitchPrevFocus()));
1186 this->addAction(switchFocusPrevAct_);
1187
1188 feedsWidgetVisibleAct_ = new QAction(this);
1189 feedsWidgetVisibleAct_->setObjectName("visibleFeedsWidgetAct");
1190 feedsWidgetVisibleAct_->setCheckable(true);
1191 connect(feedsWidgetVisibleAct_, SIGNAL(triggered()), this, SLOT(slotVisibledFeedsWidget()));
1192 connect(pushButtonNull_, SIGNAL(clicked()), feedsWidgetVisibleAct_, SLOT(trigger()));
1193 this->addAction(feedsWidgetVisibleAct_);
1194
1195 showUnreadCount_ = new QAction(this);
1196 showUnreadCount_->setData(feedsView_->columnIndex("unread"));
1197 showUnreadCount_->setCheckable(true);
1198 showUndeleteCount_ = new QAction(this);
1199 showUndeleteCount_->setData(feedsView_->columnIndex("undeleteCount"));
1200 showUndeleteCount_->setCheckable(true);
1201 showLastUpdated_ = new QAction(this);
1202 showLastUpdated_->setData(feedsView_->columnIndex("updated"));
1203 showLastUpdated_->setCheckable(true);
1204
1205 openDescriptionNewsAct_ = new QAction(this);
1206 openDescriptionNewsAct_->setObjectName("openDescriptionNewsAct");
1207 connect(openDescriptionNewsAct_, SIGNAL(triggered()),
1208 this, SLOT(slotOpenNewsWebView()));
1209 this->addAction(openDescriptionNewsAct_);
1210
1211 findTextAct_ = new QAction(this);
1212 findTextAct_->setObjectName("findTextAct");
1213 connect(findTextAct_, SIGNAL(triggered()),
1214 this, SLOT(findText()));
1215 this->addAction(findTextAct_);
1216
1217 placeToTrayAct_ = new QAction(this);
1218 placeToTrayAct_->setObjectName("placeToTrayAct");
1219 connect(placeToTrayAct_, SIGNAL(triggered()), this, SLOT(slotPlaceToTray()));
1220 this->addAction(placeToTrayAct_);
1221
1222 findFeedAct_ = new QAction(this);
1223 findFeedAct_->setObjectName("findFeedAct");
1224 findFeedAct_->setCheckable(true);
1225 findFeedAct_->setChecked(false);
1226 findFeedAct_->setIcon(QIcon(":/images/images/findFeed.png"));
1227 this->addAction(findFeedAct_);
1228 connect(findFeedAct_, SIGNAL(triggered(bool)),
1229 this, SLOT(findFeedVisible(bool)));
1230
1231 fullScreenAct_ = new QAction(this);
1232 fullScreenAct_->setObjectName("fullScreenAct");
1233 fullScreenAct_->setIcon(QIcon(":/images/images/fullScreen.png"));
1234 this->addAction(fullScreenAct_);
1235 connect(fullScreenAct_, SIGNAL(triggered()),
1236 this, SLOT(setFullScreen()));
1237
1238 stayOnTopAct_ = new QAction(this);
1239 stayOnTopAct_->setObjectName("stayOnTopAct");
1240 stayOnTopAct_->setCheckable(true);
1241 this->addAction(stayOnTopAct_);
1242 connect(stayOnTopAct_, SIGNAL(triggered()),
1243 this, SLOT(setStayOnTop()));
1244
1245 newsLabelGroup_ = new QActionGroup(this);
1246 newsLabelGroup_->setExclusive(false);
1247 QSqlQuery q;
1248 q.exec("SELECT id, name, image FROM labels ORDER BY num");
1249 while (q.next()) {
1250 int idLabel = q.value(0).toInt();
1251 QString nameLabel = q.value(1).toString();
1252 QByteArray byteArray = q.value(2).toByteArray();
1253 QPixmap imageLabel;
1254 if (!byteArray.isNull())
1255 imageLabel.loadFromData(byteArray);
1256 QAction *action = new QAction(QIcon(imageLabel), nameLabel, this);
1257 action->setObjectName(QString("labelAction_%1").arg(idLabel));
1258 action->setCheckable(true);
1259 action->setData(idLabel);
1260 newsLabelGroup_->addAction(action);
1261 }
1262 this->addActions(newsLabelGroup_->actions());
1263
1264 newsLabelAction_ = new QAction(this);
1265 newsLabelAction_->setObjectName("newsLabelAction");
1266 this->addAction(newsLabelAction_);
1267 if (newsLabelGroup_->actions().count()) {
1268 newsLabelAction_->setIcon(newsLabelGroup_->actions().at(0)->icon());
1269 newsLabelAction_->setToolTip(newsLabelGroup_->actions().at(0)->text());
1270 newsLabelAction_->setData(newsLabelGroup_->actions().at(0)->data());
1271 }
1272 connect(newsLabelAction_, SIGNAL(triggered()),
1273 this, SLOT(setDefaultLabelNews()));
1274 connect(newsLabelGroup_, SIGNAL(triggered(QAction*)),
1275 this, SLOT(setLabelNews(QAction*)));
1276
1277 showLabelsMenuAct_ = new QAction(this);
1278 showLabelsMenuAct_->setObjectName("showLabelsMenuAct");
1279 this->addAction(showLabelsMenuAct_);
1280 connect(showLabelsMenuAct_, SIGNAL(triggered()),
1281 this, SLOT(slotShowLabelsMenu()));
1282
1283 closeTabAct_ = new QAction(this);
1284 closeTabAct_->setObjectName("closeTabAct");
1285 this->addAction(closeTabAct_);
1286
1287 closeOtherTabsAct_ = new QAction(this);
1288 closeOtherTabsAct_->setObjectName("closeOtherTabsAct");
1289 this->addAction(closeOtherTabsAct_);
1290
1291 closeAllTabsAct_ = new QAction(this);
1292 closeAllTabsAct_->setObjectName("closeAllTabsAct");
1293 this->addAction(closeAllTabsAct_);
1294
1295 nextTabAct_ = new QAction(this);
1296 nextTabAct_->setObjectName("nextTabAct");
1297 this->addAction(nextTabAct_);
1298
1299 prevTabAct_ = new QAction(this);
1300 prevTabAct_->setObjectName("prevTabAct");
1301 this->addAction(prevTabAct_);
1302
1303 reduceNewsListAct_ = new QAction(this);
1304 reduceNewsListAct_->setObjectName("reduceNewsListAct");
1305 this->addAction(reduceNewsListAct_);
1306 connect(reduceNewsListAct_, SIGNAL(triggered()),
1307 this, SLOT(reduceNewsList()));
1308 increaseNewsListAct_ = new QAction(this);
1309 increaseNewsListAct_->setObjectName("increaseNewsListAct");
1310 this->addAction(increaseNewsListAct_);
1311 connect(increaseNewsListAct_, SIGNAL(triggered()),
1312 this, SLOT(increaseNewsList()));
1313
1314 nextUnreadNewsAct_ = new QAction(this);
1315 nextUnreadNewsAct_->setObjectName("nextUnreadNewsAct");
1316 nextUnreadNewsAct_->setIcon(QIcon(":/images/moveDown"));
1317 this->addAction(nextUnreadNewsAct_);
1318 connect(nextUnreadNewsAct_, SIGNAL(triggered()), this, SLOT(nextUnreadNews()));
1319 prevUnreadNewsAct_ = new QAction(this);
1320 prevUnreadNewsAct_->setObjectName("prevUnreadNewsAct");
1321 prevUnreadNewsAct_->setIcon(QIcon(":/images/moveUp"));
1322 this->addAction(prevUnreadNewsAct_);
1323 connect(prevUnreadNewsAct_, SIGNAL(triggered()), this, SLOT(prevUnreadNews()));
1324
1325 openHomeFeedAct_ = new QAction(this);
1326 openHomeFeedAct_->setObjectName("openHomeFeedsAct");
1327 openHomeFeedAct_->setIcon(QIcon(":/images/homePage"));
1328 this->addAction(openHomeFeedAct_);
1329 connect(openHomeFeedAct_, SIGNAL(triggered()), this, SLOT(slotOpenHomeFeed()));
1330
1331 copyLinkAct_ = new QAction(this);
1332 copyLinkAct_->setObjectName("copyLinkAct");
1333 copyLinkAct_->setIcon(QIcon(":/images/copy"));
1334 this->addAction(copyLinkAct_);
1335 connect(copyLinkAct_, SIGNAL(triggered()), this, SLOT(slotCopyLinkNews()));
1336
1337 pageUpWebViewAct_ = new QAction(this);
1338 pageUpWebViewAct_->setObjectName("pageUpWebViewAct");
1339 this->addAction(pageUpWebViewAct_);
1340 connect(pageUpWebViewAct_, SIGNAL(triggered()),
1341 this, SLOT(slotPageUpWebView()));
1342 pageDownWebViewAct_ = new QAction(this);
1343 pageDownWebViewAct_->setObjectName("pageDownWebViewAct");
1344 this->addAction(pageDownWebViewAct_);
1345 connect(pageDownWebViewAct_, SIGNAL(triggered()),
1346 this, SLOT(slotPageDownWebView()));
1347
1348 nextFolderAct_ = new QAction(this);
1349 nextFolderAct_->setObjectName("nextFolderAct");
1350 this->addAction(nextFolderAct_);
1351 connect(nextFolderAct_, SIGNAL(triggered()), this, SLOT(slotNextFolder()));
1352 prevFolderAct_ = new QAction(this);
1353 prevFolderAct_->setObjectName("prevFolderAct");
1354 this->addAction(prevFolderAct_);
1355 connect(prevFolderAct_, SIGNAL(triggered()), this, SLOT(slotPrevFolder()));
1356 expandFolderAct_ = new QAction(this);
1357 expandFolderAct_->setObjectName("expandFolderAct");
1358 this->addAction(expandFolderAct_);
1359 connect(expandFolderAct_, SIGNAL(triggered()), this, SLOT(slotExpandFolder()));
1360
1361 settingPageLabelsAct_ = new QAction(this);
1362 settingPageLabelsAct_->setObjectName("settingPageLabelsAct");
1363 this->addAction(settingPageLabelsAct_);
1364 connect(settingPageLabelsAct_, SIGNAL(triggered()), this, SLOT(showSettingPageLabels()));
1365
1366 backWebPageAct_ = new QAction(this);
1367 backWebPageAct_->setObjectName("backWebPageAct");
1368 forwardWebPageAct_ = new QAction(this);
1369 forwardWebPageAct_->setObjectName("forwardWebPageAct");
1370 reloadWebPageAct_ = new QAction(this);
1371 reloadWebPageAct_->setObjectName("reloadWebPageAct");
1372
1373 shareGroup_ = new QActionGroup(this);
1374 shareGroup_->setExclusive(false);
1375
1376 emailShareAct_ = new QAction(this);
1377 emailShareAct_->setObjectName("emailShareAct");
1378 emailShareAct_->setText("Email");
1379 emailShareAct_->setIcon(QIcon(":/images/images/email.png"));
1380 shareGroup_->addAction(emailShareAct_);
1381
1382 evernoteShareAct_ = new QAction(this);
1383 evernoteShareAct_->setObjectName("evernoteShareAct");
1384 evernoteShareAct_->setText("Evernote");
1385 evernoteShareAct_->setIcon(QIcon(":/share/images/share/evernote.png"));
1386 shareGroup_->addAction(evernoteShareAct_);
1387
1388 facebookShareAct_ = new QAction(this);
1389 facebookShareAct_->setObjectName("facebookShareAct");
1390 facebookShareAct_->setText("Facebook");
1391 facebookShareAct_->setIcon(QIcon(":/share/images/share/facebook.png"));
1392 shareGroup_->addAction(facebookShareAct_);
1393
1394 livejournalShareAct_ = new QAction(this);
1395 livejournalShareAct_->setObjectName("livejournalShareAct");
1396 livejournalShareAct_->setText("LiveJournal");
1397 livejournalShareAct_->setIcon(QIcon(":/share/images/share/livejournal.png"));
1398 shareGroup_->addAction(livejournalShareAct_);
1399
1400 pocketShareAct_ = new QAction(this);
1401 pocketShareAct_->setObjectName("pocketShareAct");
1402 pocketShareAct_->setText("Pocket");
1403 pocketShareAct_->setIcon(QIcon(":/share/images/share/pocket.png"));
1404 shareGroup_->addAction(pocketShareAct_);
1405
1406 twitterShareAct_ = new QAction(this);
1407 twitterShareAct_->setObjectName("twitterShareAct");
1408 twitterShareAct_->setText("Twitter");
1409 twitterShareAct_->setIcon(QIcon(":/share/images/share/twitter.png"));
1410 shareGroup_->addAction(twitterShareAct_);
1411
1412 vkShareAct_ = new QAction(this);
1413 vkShareAct_->setObjectName("vkShareAct");
1414 vkShareAct_->setText("VK");
1415 vkShareAct_->setIcon(QIcon(":/share/images/share/vk.png"));
1416 shareGroup_->addAction(vkShareAct_);
1417
1418 linkedinShareAct_ = new QAction(this);
1419 linkedinShareAct_->setObjectName("linkedinShareAct");
1420 linkedinShareAct_->setText("LinkedIn");
1421 linkedinShareAct_->setIcon(QIcon(":/share/images/share/linkedin.png"));
1422 shareGroup_->addAction(linkedinShareAct_);
1423
1424 bloggerShareAct_ = new QAction(this);
1425 bloggerShareAct_->setObjectName("bloggerShareAct");
1426 bloggerShareAct_->setText("Blogger");
1427 bloggerShareAct_->setIcon(QIcon(":/share/images/share/blogger.png"));
1428 shareGroup_->addAction(bloggerShareAct_);
1429
1430 printfriendlyShareAct_ = new QAction(this);
1431 printfriendlyShareAct_->setObjectName("printfriendlyShareAct");
1432 printfriendlyShareAct_->setText("PrintFriendly");
1433 printfriendlyShareAct_->setIcon(QIcon(":/share/images/share/printfriendly.png"));
1434 shareGroup_->addAction(printfriendlyShareAct_);
1435
1436 instapaperShareAct_ = new QAction(this);
1437 instapaperShareAct_->setObjectName("instapaperShareAct");
1438 instapaperShareAct_->setText("Instapaper");
1439 instapaperShareAct_->setIcon(QIcon(":/share/images/share/instapaper.png"));
1440 shareGroup_->addAction(instapaperShareAct_);
1441
1442 redditShareAct_ = new QAction(this);
1443 redditShareAct_->setObjectName("redditShareAct");
1444 redditShareAct_->setText("Reddit");
1445 redditShareAct_->setIcon(QIcon(":/share/images/share/reddit.ico"));
1446 shareGroup_->addAction(redditShareAct_);
1447
1448 hackerNewsShareAct_ = new QAction(this);
1449 hackerNewsShareAct_->setObjectName("hackerNewsShareAct");
1450 hackerNewsShareAct_->setText("HackerNews");
1451 hackerNewsShareAct_->setIcon(QIcon(":/share/images/share/hackernews.png"));
1452 shareGroup_->addAction(hackerNewsShareAct_);
1453
1454 telegramShareAct_ = new QAction(this);
1455 telegramShareAct_->setObjectName("telegramShareAct");
1456 telegramShareAct_->setText("Telegram");
1457 telegramShareAct_->setIcon(QIcon(":/share/images/share/telegram.png"));
1458 shareGroup_->addAction(telegramShareAct_);
1459
1460 viberShareAct_ = new QAction(this);
1461 viberShareAct_->setObjectName("viberShareAct");
1462 viberShareAct_->setText("Vider");
1463 viberShareAct_->setIcon(QIcon(":/share/images/share/viber.png"));
1464 shareGroup_->addAction(viberShareAct_);
1465
1466 this->addActions(shareGroup_->actions());
1467 connect(shareGroup_, SIGNAL(triggered(QAction*)),
1468 this, SLOT(slotShareNews(QAction*)));
1469
1470
1471 connect(markNewsRead_, SIGNAL(triggered()),
1472 this, SLOT(markNewsRead()));
1473 connect(markAllNewsRead_, SIGNAL(triggered()),
1474 this, SLOT(markAllNewsRead()));
1475 connect(markStarAct_, SIGNAL(triggered()),
1476 this, SLOT(markNewsStar()));
1477 connect(deleteNewsAct_, SIGNAL(triggered()),
1478 this, SLOT(deleteNews()));
1479 connect(deleteAllNewsAct_, SIGNAL(triggered()),
1480 this, SLOT(deleteAllNewsList()));
1481 connect(restoreNewsAct_, SIGNAL(triggered()),
1482 this, SLOT(restoreNews()));
1483
1484 connect(newsKeyUpAct_, SIGNAL(triggered()),
1485 this, SLOT(slotNewsUpPressed()));
1486 connect(newsKeyDownAct_, SIGNAL(triggered()),
1487 this, SLOT(slotNewsDownPressed()));
1488 connect(newsKeyPageUpAct_, SIGNAL(triggered()),
1489 this, SLOT(slotNewsPageUpPressed()));
1490 connect(newsKeyPageDownAct_, SIGNAL(triggered()),
1491 this, SLOT(slotNewsPageDownPressed()));
1492
1493 connect(openInBrowserAct_, SIGNAL(triggered()),
1494 this, SLOT(openInBrowserNews()));
1495 connect(openInExternalBrowserAct_, SIGNAL(triggered()),
1496 this, SLOT(openInExternalBrowserNews()));
1497 connect(openNewsNewTabAct_, SIGNAL(triggered()),
1498 this, SLOT(slotOpenNewsNewTab()));
1499 connect(openNewsBackgroundTabAct_, SIGNAL(triggered()),
1500 this, SLOT(slotOpenNewsBackgroundTab()));
1501 }
1502 // ---------------------------------------------------------------------------
createShortcut()1503 void MainWindow::createShortcut()
1504 {
1505 addFeedAct_->setShortcut(QKeySequence(QKeySequence::New));
1506 listActions_.append(addFeedAct_);
1507 addFolderAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_N));
1508 listActions_.append(addFolderAct_);
1509 listActions_.append(deleteFeedAct_);
1510 listActions_.append(createBackupAct_);
1511 exitAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); // standart on other OS
1512 listActions_.append(exitAct_);
1513 updateFeedAct_->setShortcut(QKeySequence(Qt::Key_F5));
1514 listActions_.append(updateFeedAct_);
1515 updateAllFeedsAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F5));
1516 listActions_.append(updateAllFeedsAct_);
1517 listActions_.append(stopUpdateAct_);
1518 listActions_.append(openHomeFeedAct_);
1519 listActions_.append(showDownloadManagerAct_);
1520 listActions_.append(showCleanUpWizardAct_);
1521 listActions_.append(setNewsFiltersAct_);
1522 listActions_.append(setFilterNewsAct_);
1523 optionsAct_->setShortcut(QKeySequence(Qt::Key_F8));
1524 listActions_.append(optionsAct_);
1525 deleteNewsAct_->setShortcut(QKeySequence(Qt::Key_Delete));
1526 listActions_.append(deleteNewsAct_);
1527 deleteAllNewsAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Delete));
1528 listActions_.append(deleteAllNewsAct_);
1529 feedProperties_->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_E));
1530 listActions_.append(feedProperties_);
1531 feedKeyUpAct_->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_Up));
1532 listActions_.append(feedKeyUpAct_);
1533 feedKeyDownAct_->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_Down));
1534 listActions_.append(feedKeyDownAct_);
1535 newsKeyUpAct_->setShortcut(QKeySequence(Qt::Key_Left));
1536 listActions_.append(newsKeyUpAct_);
1537 newsKeyDownAct_->setShortcut(QKeySequence(Qt::Key_Right));
1538 listActions_.append(newsKeyDownAct_);
1539 listActions_.append(newsKeyPageUpAct_);
1540 listActions_.append(newsKeyPageDownAct_);
1541
1542 listActions_.append(nextUnreadNewsAct_);
1543 listActions_.append(prevUnreadNewsAct_);
1544
1545 listActions_.append(nextFolderAct_);
1546 listActions_.append(prevFolderAct_);
1547
1548 listActions_.append(importFeedsAct_);
1549 listActions_.append(exportFeedsAct_);
1550 listActions_.append(createBackupAct_);
1551 listActions_.append(autoLoadImagesToggle_);
1552 listActions_.append(markAllFeedsRead_);
1553 listActions_.append(markFeedRead_);
1554 listActions_.append(markNewsRead_);
1555 listActions_.append(markAllNewsRead_);
1556 listActions_.append(markStarAct_);
1557 listActions_.append(collapseAllFoldersAct_);
1558 listActions_.append(expandAllFoldersAct_);
1559 listActions_.append(expandFolderAct_);
1560
1561 listActions_.append(openDescriptionNewsAct_);
1562 openDescriptionNewsAct_->setShortcut(QKeySequence(Qt::Key_Return));
1563 listActions_.append(openInBrowserAct_);
1564 openInBrowserAct_->setShortcut(QKeySequence(Qt::Key_Space));
1565 listActions_.append(openInExternalBrowserAct_);
1566 openInExternalBrowserAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));
1567 openNewsNewTabAct_->setShortcut(QKeySequence(Qt::Key_T));
1568 listActions_.append(openNewsNewTabAct_);
1569 openNewsBackgroundTabAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T));
1570 listActions_.append(openNewsBackgroundTabAct_);
1571
1572 switchFocusAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Tab));
1573 listActions_.append(switchFocusAct_);
1574 switchFocusPrevAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Tab));
1575 listActions_.append(switchFocusPrevAct_);
1576
1577 feedsWidgetVisibleAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
1578 listActions_.append(feedsWidgetVisibleAct_);
1579
1580 listActions_.append(placeToTrayAct_);
1581
1582 zoomInAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Plus));
1583 listActions_.append(zoomInAct_);
1584 zoomOutAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Minus));
1585 listActions_.append(zoomOutAct_);
1586 zoomTo100Act_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_0));
1587 listActions_.append(zoomTo100Act_);
1588
1589 printAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_P));
1590 listActions_.append(printAct_);
1591 printPreviewAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_P));
1592 listActions_.append(printPreviewAct_);
1593
1594 savePageAsAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
1595 listActions_.append(savePageAsAct_);
1596 listActions_.append(savePageAsDescriptAct_);
1597
1598 fullScreenAct_->setShortcut(QKeySequence(Qt::Key_F11));
1599 listActions_.append(fullScreenAct_);
1600
1601 stayOnTopAct_->setShortcut(QKeySequence(Qt::Key_F10));
1602 listActions_.append(stayOnTopAct_);
1603
1604 listActions_.append(layoutToggle_);
1605
1606 closeTabAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_W));
1607 listActions_.append(closeTabAct_);
1608 listActions_.append(closeOtherTabsAct_);
1609 listActions_.append(closeAllTabsAct_);
1610 listActions_.append(nextTabAct_);
1611 listActions_.append(prevTabAct_);
1612
1613 reduceNewsListAct_->setShortcut(QKeySequence(Qt::ALT+ Qt::Key_Up));
1614 listActions_.append(reduceNewsListAct_);
1615 increaseNewsListAct_->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Down));
1616 listActions_.append(increaseNewsListAct_);
1617
1618 restoreLastNewsAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z));
1619 listActions_.append(restoreLastNewsAct_);
1620
1621 findTextAct_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F));
1622 listActions_.append(findTextAct_);
1623
1624 listActions_.append(findFeedAct_);
1625
1626 listActions_.append(copyLinkAct_);
1627
1628 listActions_.append(backWebPageAct_);
1629 listActions_.append(forwardWebPageAct_);
1630 listActions_.append(reloadWebPageAct_);
1631 listActions_.append(pageUpWebViewAct_);
1632 listActions_.append(pageDownWebViewAct_);
1633
1634 listActions_.append(shareGroup_->actions());
1635
1636 // Actions for labels do add at the end
1637 listActions_.append(settingPageLabelsAct_);
1638 listActions_.append(showLabelsMenuAct_);
1639 listActions_.append(newsLabelGroup_->actions());
1640
1641 loadActionShortcuts();
1642 }
1643 // ---------------------------------------------------------------------------
loadActionShortcuts()1644 void MainWindow::loadActionShortcuts()
1645 {
1646 Settings settings;
1647 settings.beginGroup("/Shortcuts");
1648
1649 QListIterator<QAction *> iter(listActions_);
1650 while (iter.hasNext()) {
1651 QAction *pAction = iter.next();
1652 if (pAction->objectName().isEmpty())
1653 continue;
1654
1655 listDefaultShortcut_.append(pAction->shortcut().toString());
1656
1657 const QString& sKey = '/' + pAction->objectName();
1658 const QString& sValue = settings.value('/' + sKey, pAction->shortcut().toString()).toString();
1659 pAction->setShortcut(QKeySequence(sValue));
1660 }
1661
1662 settings.endGroup();
1663 }
1664 // ---------------------------------------------------------------------------
saveActionShortcuts()1665 void MainWindow::saveActionShortcuts()
1666 {
1667 Settings settings;
1668 settings.beginGroup("/Shortcuts/");
1669
1670 QListIterator<QAction *> iter(listActions_);
1671 while (iter.hasNext()) {
1672 QAction *pAction = iter.next();
1673 if (pAction->objectName().isEmpty())
1674 continue;
1675
1676 const QString& sKey = '/' + pAction->objectName();
1677 const QString& sValue = QString(pAction->shortcut().toString());
1678 settings.setValue(sKey, sValue);
1679 }
1680
1681 settings.endGroup();
1682 }
1683 // ---------------------------------------------------------------------------
createMenu()1684 void MainWindow::createMenu()
1685 {
1686 newMenu_ = new QMenu(this);
1687 newMenu_->addAction(addFeedAct_);
1688 newMenu_->addAction(addFolderAct_);
1689 addAct_->setMenu(newMenu_);
1690
1691 fileMenu_ = new QMenu(this);
1692 fileMenu_->addAction(addAct_);
1693 fileMenu_->addSeparator();
1694 fileMenu_->addAction(importFeedsAct_);
1695 fileMenu_->addAction(exportFeedsAct_);
1696 fileMenu_->addSeparator();
1697 fileMenu_->addAction(createBackupAct_);
1698 fileMenu_->addSeparator();
1699 #ifndef Q_OS_MAC
1700 fileMenu_->addAction(showMenuBarAct_);
1701 fileMenu_->addSeparator();
1702 #endif
1703 fileMenu_->addAction(exitAct_);
1704
1705 toolbarsMenu_ = new QMenu(this);
1706 toolbarsMenu_->addAction(mainToolbarToggle_);
1707 toolbarsMenu_->addAction(feedsToolbarToggle_);
1708 toolbarsMenu_->addAction(newsToolbarToggle_);
1709 toolbarsMenu_->addAction(browserToolbarToggle_);
1710 toolbarsMenu_->addAction(categoriesPanelToggle_);
1711 toolbarsMenu_->addAction(statusBarToggle_);
1712
1713 customizeToolbarGroup_ = new QActionGroup(this);
1714 customizeToolbarGroup_->addAction(customizeMainToolbarAct_);
1715 customizeToolbarGroup_->addAction(customizeFeedsToolbarAct_);
1716 customizeToolbarGroup_->addAction(customizeNewsToolbarAct_);
1717 customizeToolbarMenu_ = new QMenu(this);
1718 customizeToolbarMenu_->addActions(customizeToolbarGroup_->actions());
1719
1720 layoutGroup_ = new QActionGroup(this);
1721 layoutGroup_->addAction(classicLayoutAct_);
1722 layoutGroup_->addAction(newspaperLayoutAct_);
1723 layoutMenu_ = new QMenu(this);
1724 layoutMenu_->addActions(layoutGroup_->actions());
1725 layoutToggle_->setMenu(layoutMenu_);
1726
1727 styleGroup_ = new QActionGroup(this);
1728 styleGroup_->addAction(systemStyle_);
1729 styleGroup_->addAction(system2Style_);
1730 styleGroup_->addAction(darkStyle_);
1731 styleGroup_->addAction(greenStyle_);
1732 styleGroup_->addAction(orangeStyle_);
1733 styleGroup_->addAction(purpleStyle_);
1734 styleGroup_->addAction(pinkStyle_);
1735 styleGroup_->addAction(grayStyle_);
1736
1737 styleMenu_ = new QMenu(this);
1738 styleMenu_->addActions(styleGroup_->actions());
1739
1740 browserPositionGroup_ = new QActionGroup(this);
1741 browserPositionGroup_->addAction(topBrowserPositionAct_);
1742 browserPositionGroup_->addAction(bottomBrowserPositionAct_);
1743 browserPositionGroup_->addAction(rightBrowserPositionAct_);
1744 browserPositionGroup_->addAction(leftBrowserPositionAct_);
1745
1746 browserPositionMenu_ = new QMenu(this);
1747 browserPositionMenu_->addActions(browserPositionGroup_->actions());
1748
1749 viewMenu_ = new QMenu(this);
1750 viewMenu_->addMenu(toolbarsMenu_);
1751 viewMenu_->addMenu(customizeToolbarMenu_);
1752 viewMenu_->addSeparator();
1753 viewMenu_->addMenu(layoutMenu_);
1754 viewMenu_->addMenu(browserPositionMenu_);
1755 viewMenu_->addMenu(styleMenu_);
1756 viewMenu_->addSeparator();
1757 viewMenu_->addAction(stayOnTopAct_);
1758 viewMenu_->addAction(fullScreenAct_);
1759
1760 feedsFilterGroup_ = new QActionGroup(this);
1761 feedsFilterGroup_->setExclusive(true);
1762 feedsFilterGroup_->addAction(filterFeedsAll_);
1763 feedsFilterGroup_->addAction(filterFeedsNew_);
1764 feedsFilterGroup_->addAction(filterFeedsUnread_);
1765 feedsFilterGroup_->addAction(filterFeedsStarred_);
1766 feedsFilterGroup_->addAction(filterFeedsError_);
1767
1768 feedsFilterMenu_ = new QMenu(this);
1769 feedsFilterMenu_->addActions(feedsFilterGroup_->actions());
1770 feedsFilterMenu_->insertSeparator(filterFeedsNew_);
1771
1772 feedsFilter_->setMenu(feedsFilterMenu_);
1773
1774 feedsColumnsGroup_ = new QActionGroup(this);
1775 feedsColumnsGroup_->setExclusive(false);
1776 feedsColumnsGroup_->addAction(showUnreadCount_);
1777 feedsColumnsGroup_->addAction(showUndeleteCount_);
1778 feedsColumnsGroup_->addAction(showLastUpdated_);
1779
1780 feedsColumnsMenu_ = new QMenu(this);
1781 feedsColumnsMenu_->addActions(feedsColumnsGroup_->actions());
1782
1783 feedMenu_ = new QMenu(this);
1784 feedMenu_->addAction(updateFeedAct_);
1785 feedMenu_->addAction(updateAllFeedsAct_);
1786 feedMenu_->addSeparator();
1787 feedMenu_->addAction(markFeedRead_);
1788 feedMenu_->addAction(markAllFeedsRead_);
1789 feedMenu_->addSeparator();
1790 feedMenu_->addAction(feedsFilter_);
1791 feedMenu_->addMenu(feedsColumnsMenu_);
1792 feedMenu_->addAction(sortedByTitleFeedsTreeAct_);
1793 feedMenu_->addAction(indentationFeedsTreeAct_);
1794 feedMenu_->addSeparator();
1795 feedMenu_->addAction(deleteFeedAct_);
1796 feedMenu_->addSeparator();
1797 feedMenu_->addAction(feedProperties_);
1798 feedMenu_->addSeparator();
1799
1800 newsLabelMenu_ = new QMenu(this);
1801 newsLabelMenu_->addActions(newsLabelGroup_->actions());
1802 newsLabelMenuAction_ = new QAction(this);
1803 newsLabelMenuAction_->setIcon(QIcon(":/images/label_3"));
1804 newsLabelAction_->setMenu(newsLabelMenu_);
1805 newsLabelMenuAction_->setMenu(newsLabelMenu_);
1806
1807 shareMenu_ = new QMenu(this);
1808 shareMenu_->addActions(shareGroup_->actions());
1809 shareMenuAct_ = new QAction(this);
1810 shareMenuAct_->setObjectName("shareMenuAct");
1811 shareMenuAct_->setIcon(QIcon(":/images/images/share.png"));
1812 shareMenuAct_->setMenu(shareMenu_);
1813 this->addAction(shareMenuAct_);
1814
1815 newsFilterGroup_ = new QActionGroup(this);
1816 newsFilterGroup_->setExclusive(true);
1817 newsFilterGroup_->addAction(filterNewsAll_);
1818 newsFilterGroup_->addAction(filterNewsNew_);
1819 newsFilterGroup_->addAction(filterNewsUnread_);
1820 newsFilterGroup_->addAction(filterNewsStar_);
1821 newsFilterGroup_->addAction(filterNewsNotStarred_);
1822 newsFilterGroup_->addAction(filterNewsUnreadStar_);
1823 newsFilterGroup_->addAction(filterNewsLastDay_);
1824 newsFilterGroup_->addAction(filterNewsLastWeek_);
1825
1826 newsFilterMenu_ = new QMenu(this);
1827 newsFilterMenu_->addActions(newsFilterGroup_->actions());
1828 newsFilterMenu_->insertSeparator(filterNewsNew_);
1829 newsFilterMenu_->insertSeparator(filterNewsLastDay_);
1830
1831 newsFilter_->setMenu(newsFilterMenu_);
1832
1833 newsSortByMenu_ = new QMenu(this);
1834 newsSortByMenu_->addSeparator();
1835 newsSortByMenu_->addActions(newsSortOrderGroup_->actions());
1836
1837 newsMenu_ = new QMenu(this);
1838 newsMenu_->addAction(markNewsRead_);
1839 newsMenu_->addAction(markAllNewsRead_);
1840 newsMenu_->addSeparator();
1841 newsMenu_->addAction(markStarAct_);
1842 newsMenu_->addAction(newsLabelMenuAction_);
1843 newsMenu_->addAction(shareMenuAct_);
1844 newsMenu_->addSeparator();
1845 newsMenu_->addAction(newsFilter_);
1846 newsMenu_->addMenu(newsSortByMenu_);
1847 newsMenu_->addSeparator();
1848 newsMenu_->addAction(deleteNewsAct_);
1849 newsMenu_->addAction(deleteAllNewsAct_);
1850
1851 browserZoomGroup_ = new QActionGroup(this);
1852 browserZoomGroup_->addAction(zoomInAct_);
1853 browserZoomGroup_->addAction(zoomOutAct_);
1854 browserZoomGroup_->addAction(zoomTo100Act_);
1855
1856 browserZoomMenu_ = new QMenu(this);
1857 browserZoomMenu_->setIcon(QIcon(":/images/zoom"));
1858 browserZoomMenu_->addActions(browserZoomGroup_->actions());
1859 browserZoomMenu_->insertSeparator(zoomTo100Act_);
1860
1861 browserMenu_ = new QMenu(this);
1862 browserMenu_->addAction(autoLoadImagesToggle_);
1863 browserMenu_->addMenu(browserZoomMenu_);
1864 browserMenu_->addSeparator();
1865 browserMenu_->addAction(printAct_);
1866 browserMenu_->addAction(printPreviewAct_);
1867 browserMenu_->addSeparator();
1868 browserMenu_->addAction(savePageAsAct_);
1869 browserMenu_->addSeparator();
1870 browserMenu_->addAction(tr("&AdBlock"), AdBlockManager::instance(), SLOT(showDialog()));
1871
1872 toolsMenu_ = new QMenu(this);
1873 toolsMenu_->addAction(showDownloadManagerAct_);
1874 toolsMenu_->addSeparator();
1875 toolsMenu_->addAction(showCleanUpWizardAct_);
1876 toolsMenu_->addAction(setNewsFiltersAct_);
1877 toolsMenu_->addSeparator();
1878 toolsMenu_->addAction(optionsAct_);
1879
1880 helpMenu_ = new QMenu(this);
1881 helpMenu_->addAction(updateAppAct_);
1882 helpMenu_->addSeparator();
1883 helpMenu_->addAction(reportProblemAct_);
1884 helpMenu_->addAction(aboutAct_);
1885
1886 #ifndef Q_OS_MAC
1887 mainMenu_ = new QMenu(this);
1888 mainMenu_->addAction(addAct_);
1889 mainMenu_->addSeparator();
1890 mainMenu_->addAction(importFeedsAct_);
1891 mainMenu_->addAction(exportFeedsAct_);
1892 mainMenu_->addSeparator();
1893 mainMenu_->addAction(createBackupAct_);
1894 mainMenu_->addSeparator();
1895 mainMenu_->addMenu(viewMenu_);
1896 mainMenu_->addMenu(feedMenu_);
1897 mainMenu_->addMenu(newsMenu_);
1898 mainMenu_->addMenu(browserMenu_);
1899 mainMenu_->addSeparator();
1900 mainMenu_->addMenu(toolsMenu_);
1901 mainMenu_->addSeparator();
1902 mainMenu_->addMenu(helpMenu_);
1903 mainMenu_->addSeparator();
1904 mainMenu_->addAction(showMenuBarAct_);
1905 mainMenu_->addSeparator();
1906 mainMenu_->addAction(exitAct_);
1907 #endif
1908
1909 menuBar()->addMenu(fileMenu_);
1910 menuBar()->addMenu(viewMenu_);
1911 menuBar()->addMenu(feedMenu_);
1912 menuBar()->addMenu(newsMenu_);
1913 menuBar()->addMenu(browserMenu_);
1914 menuBar()->addMenu(toolsMenu_);
1915 menuBar()->addMenu(helpMenu_);
1916
1917 connect(customizeToolbarGroup_, SIGNAL(triggered(QAction*)),
1918 this, SLOT(showCustomizeToolbarDlg(QAction*)));
1919 connect(styleGroup_, SIGNAL(triggered(QAction*)),
1920 this, SLOT(setStyleApp(QAction*)));
1921 connect(browserPositionGroup_, SIGNAL(triggered(QAction*)),
1922 this, SLOT(setBrowserPosition(QAction*)));
1923 connect(feedsFilterGroup_, SIGNAL(triggered(QAction*)),
1924 this, SLOT(setFeedsFilter()));
1925 connect(feedsFilter_, SIGNAL(triggered()), this, SLOT(slotFeedsFilter()));
1926 connect(feedsColumnsGroup_, SIGNAL(triggered(QAction*)),
1927 this, SLOT(feedsColumnVisible(QAction*)));
1928 connect(feedMenu_, SIGNAL(aboutToShow()), this, SLOT(slotFeedMenuShow()));
1929 connect(newsLabelMenu_, SIGNAL(aboutToShow()), this, SLOT(getLabelNews()));
1930 connect(shareMenuAct_, SIGNAL(triggered()), this, SLOT(showMenuShareNews()));
1931 connect(newsFilterGroup_, SIGNAL(triggered(QAction*)),
1932 this, SLOT(setNewsFilter(QAction*)));
1933 connect(newsFilter_, SIGNAL(triggered()), this, SLOT(slotNewsFilter()));
1934 connect(newsSortByMenu_, SIGNAL(aboutToShow()),
1935 this, SLOT(showNewsSortByMenu()));
1936 connect(newsMenu_, SIGNAL(aboutToShow()), this, SLOT(showNewsMenu()));
1937 connect(browserZoomGroup_, SIGNAL(triggered(QAction*)),
1938 this, SLOT(browserZoom(QAction*)));
1939 }
1940 // ---------------------------------------------------------------------------
createToolBar()1941 void MainWindow::createToolBar()
1942 {
1943 mainToolbar_ = new QToolBar(this);
1944 mainToolbar_->setObjectName("ToolBar_General");
1945 mainToolbar_->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
1946 mainToolbar_->setContextMenuPolicy(Qt::CustomContextMenu);
1947 addToolBar(mainToolbar_);
1948
1949 connect(mainToolbarToggle_, SIGNAL(toggled(bool)),
1950 mainToolbar_, SLOT(setVisible(bool)));
1951 connect(mainToolbar_, SIGNAL(customContextMenuRequested(QPoint)),
1952 this, SLOT(showContextMenuToolBar(const QPoint &)));
1953
1954 connect(toolBarLockAct_, SIGNAL(toggled(bool)), this, SLOT(lockMainToolbar(bool)));
1955 connect(toolBarHideAct_, SIGNAL(triggered()), this, SLOT(hideMainToolbar()));
1956 }
1957
1958 /** @brief Load settings from ini-file
1959 *---------------------------------------------------------------------------*/
loadSettings()1960 void MainWindow::loadSettings()
1961 {
1962 Settings settings;
1963 settings.beginGroup("Settings");
1964
1965 showSplashScreen_ = settings.value("showSplashScreen", true).toBool();
1966 reopenFeedStartup_ = settings.value("reopenFeedStartup", true).toBool();
1967 openNewTabNextToActive_ = settings.value("openNewTabNextToActive", false).toBool();
1968
1969 showTrayIcon_ = settings.value("showTrayIcon", true).toBool();
1970 #ifndef Q_OS_MAC
1971 startingTray_ = settings.value("startingTray", false).toBool();
1972 minimizingTray_ = settings.value("minimizingTray", true).toBool();
1973 closingTray_ = settings.value("closingTray", false).toBool();
1974 #else
1975 startingTray_ = false;
1976 minimizingTray_ = false;
1977 closingTray_ = false;
1978 #endif
1979 singleClickTray_ = settings.value("singleClickTray", false).toBool();
1980 clearStatusNew_ = settings.value("clearStatusNew", true).toBool();
1981 emptyWorking_ = settings.value("emptyWorking", true).toBool();
1982
1983 QString fontFamily = settings.value("feedsFontFamily", qApp->font().family()).toString();
1984 int fontSize = settings.value("feedsFontSize", qApp->font().pointSize()).toInt();
1985 feedsView_->setFont(QFont(fontFamily, fontSize));
1986 feedsModel_->font_ = feedsView_->font();
1987
1988 newsListFontFamily_ = settings.value("newsFontFamily", qApp->font().family()).toString();
1989 newsListFontSize_ = settings.value("newsFontSize", qApp->font().pointSize()).toInt();
1990 newsTitleFontFamily_ = settings.value("newsTitleFontFamily", qApp->font().family()).toString();
1991 newsTitleFontSize_ = settings.value("newsTitleFontSize", qApp->font().pointSize()+2).toInt();
1992 newsTextFontFamily_ = settings.value("newsTextFontFamily", qApp->font().family()).toString();
1993 newsTextFontSize_ = settings.value("newsTextFontSize", qApp->font().pointSize()+2).toInt();
1994 notificationFontFamily_ = settings.value("notificationFontFamily", qApp->font().family()).toString();
1995 notificationFontSize_ = settings.value("notificationFontSize", qApp->font().pointSize()).toInt();
1996
1997 QString browserStandardFont = settings.value(
1998 "browserStandardFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::StandardFont)).toString();
1999 QString browserFixedFont = settings.value(
2000 "browserFixedFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::FixedFont)).toString();
2001 QString browserSerifFont = settings.value(
2002 "browserSerifFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::SerifFont)).toString();
2003 QString browserSansSerifFont = settings.value(
2004 "browserSansSerifFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::SansSerifFont)).toString();
2005 QString browserCursiveFont = settings.value(
2006 "browserCursiveFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::CursiveFont)).toString();
2007 QString browserFantasyFont = settings.value(
2008 "browserFantasyFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::FantasyFont)).toString();
2009 int browserDefaultFontSize = settings.value(
2010 "browserDefaultFontSize", QWebSettings::globalSettings()->fontSize(QWebSettings::DefaultFontSize)).toInt();
2011 int browserFixedFontSize = settings.value(
2012 "browserFixedFontSize", QWebSettings::globalSettings()->fontSize(QWebSettings::DefaultFixedFontSize)).toInt();
2013 int browserMinFontSize = settings.value(
2014 "browserMinFontSize", QWebSettings::globalSettings()->fontSize(QWebSettings::MinimumFontSize)).toInt();
2015 int browserMinLogFontSize = settings.value(
2016 "browserMinLogFontSize", QWebSettings::globalSettings()->fontSize(QWebSettings::MinimumLogicalFontSize)).toInt();
2017
2018 QWebSettings::globalSettings()->setFontFamily(
2019 QWebSettings::StandardFont, browserStandardFont);
2020 QWebSettings::globalSettings()->setFontFamily(
2021 QWebSettings::FixedFont, browserFixedFont);
2022 QWebSettings::globalSettings()->setFontFamily(
2023 QWebSettings::SerifFont, browserSerifFont);
2024 QWebSettings::globalSettings()->setFontFamily(
2025 QWebSettings::SansSerifFont, browserSansSerifFont);
2026 QWebSettings::globalSettings()->setFontFamily(
2027 QWebSettings::CursiveFont, browserCursiveFont);
2028 QWebSettings::globalSettings()->setFontFamily(
2029 QWebSettings::FantasyFont, browserFantasyFont);
2030 QWebSettings::globalSettings()->setFontSize(
2031 QWebSettings::DefaultFontSize, browserDefaultFontSize);
2032 QWebSettings::globalSettings()->setFontSize(
2033 QWebSettings::DefaultFixedFontSize, browserFixedFontSize);
2034 QWebSettings::globalSettings()->setFontSize(
2035 QWebSettings::MinimumFontSize, browserMinFontSize);
2036 QWebSettings::globalSettings()->setFontSize(
2037 QWebSettings::MinimumLogicalFontSize, browserMinLogFontSize);
2038
2039 updateFeedsEnable_ = settings.value("autoUpdatefeeds", false).toBool();
2040 updateFeedsInterval_ = settings.value("autoUpdatefeedsTime", 10).toInt();
2041 updateFeedsIntervalType_ = settings.value("autoUpdatefeedsInterval", 0).toInt();
2042
2043 openingFeedAction_ = settings.value("openingFeedAction", 0).toInt();
2044 openNewsWebViewOn_ = settings.value("openNewsWebViewOn", true).toBool();
2045
2046 markNewsReadOn_ = settings.value("markNewsReadOn", true).toBool();
2047 markCurNewsRead_ = settings.value("markCurNewsRead", true).toBool();
2048 markNewsReadTime_ = settings.value("markNewsReadTime", 0).toInt();
2049 markPrevNewsRead_= settings.value("markPrevNewsRead", false).toBool();
2050 markReadSwitchingFeed_ = settings.value("markReadSwitchingFeed", false).toBool();
2051 markReadClosingTab_ = settings.value("markReadClosingTab", false).toBool();
2052 markReadMinimize_ = settings.value("markReadMinimize", false).toBool();
2053
2054 showDescriptionNews_ = settings.value("showDescriptionNews", true).toBool();
2055
2056 formatDate_ = settings.value("formatData", "dd.MM.yy").toString();
2057 formatTime_ = settings.value("formatTime", "hh:mm").toString();
2058 feedsModel_->formatDate_ = formatDate_;
2059 feedsModel_->formatTime_ = formatTime_;
2060
2061 alternatingRowColorsNews_ = settings.value("alternatingColorsNews", false).toBool();
2062 changeBehaviorActionNUN_ = settings.value("changeBehaviorActionNUN", false).toBool();
2063 simplifiedDateTime_ = settings.value("simplifiedDateTime", true).toBool();
2064 notDeleteStarred_ = settings.value("notDeleteStarred", false).toBool();
2065 notDeleteLabeled_ = settings.value("notDeleteLabeled", false).toBool();
2066 markIdenticalNewsRead_ = settings.value("markIdenticalNewsRead", true).toBool();
2067 avoidOldNews_ = settings.value("avoidOldNews", false).toBool();
2068 avoidedOldNewsDate_ = settings.value("avoidedOldNewsDate").toDate();
2069
2070 mainNewsFilter_ = settings.value("mainNewsFilter", "filterNewsAll_").toString();
2071
2072 cleanupOnShutdown_ = settings.value("cleanupOnShutdown", true).toBool();
2073 maxDayCleanUp_ = settings.value("maxDayClearUp", 30).toInt();
2074 maxNewsCleanUp_ = settings.value("maxNewsClearUp", 200).toInt();
2075 dayCleanUpOn_ = settings.value("dayClearUpOn", true).toBool();
2076 newsCleanUpOn_ = settings.value("newsClearUpOn", true).toBool();
2077 readCleanUp_ = settings.value("readClearUp", false).toBool();
2078 neverUnreadCleanUp_ = settings.value("neverUnreadClearUp", true).toBool();
2079 neverStarCleanUp_ = settings.value("neverStarClearUp", true).toBool();
2080 neverLabelCleanUp_ = settings.value("neverLabelClearUp", true).toBool();
2081 cleanUpDeleted_ = settings.value("cleanUpDeleted", false).toBool();
2082 optimizeDB_ = settings.value("optimizeDB", false).toBool();
2083
2084 externalBrowserOn_ = settings.value("externalBrowserOn", 0).toInt();
2085 externalBrowser_ = settings.value("externalBrowser", "").toString();
2086 javaScriptEnable_ = settings.value("javaScriptEnable", true).toBool();
2087 pluginsEnable_ = settings.value("pluginsEnable", true).toBool();
2088 maxPagesInCache_ = settings.value("maxPagesInCache", 3).toInt();
2089 downloadLocation_ = settings.value("downloadLocation", "").toString();
2090 askDownloadLocation_ = settings.value("askDownloadLocation", true).toBool();
2091 defaultZoomPages_ = settings.value("defaultZoomPages", 100).toInt();
2092 autoLoadImages_ = settings.value("autoLoadImages", true).toBool();
2093
2094 QWebSettings::globalSettings()->setAttribute(
2095 QWebSettings::JavascriptEnabled, javaScriptEnable_);
2096 QWebSettings::globalSettings()->setAttribute(
2097 QWebSettings::PluginsEnabled, pluginsEnable_);
2098 QWebSettings::globalSettings()->setMaximumPagesInCache(maxPagesInCache_);
2099 #if QT_VERSION >= 0x050e00
2100 QWebSettings::globalSettings()->setAttribute(
2101 QWebSettings::ErrorPageEnabled, false);
2102 #endif
2103 QWebSettings::globalSettings()->setOfflineStorageDefaultQuota(0);
2104 QWebSettings::globalSettings()->setOfflineStoragePath(mainApp->dataDir());
2105
2106 soundNewNews_ = settings.value("soundNewNews", true).toBool();
2107 soundNotifyPath_ = settings.value("soundNotifyPath", mainApp->soundNotifyDefaultFile()).toString();
2108 showNotifyOn_ = settings.value("showNotifyOn", true).toBool();
2109 screenNotify_ = settings.value("screenNotify", 0).toInt();
2110 positionNotify_ = settings.value("positionNotify", 3).toInt();
2111 transparencyNotify_ = settings.value("transparencyNotify", 60).toInt();
2112 countShowNewsNotify_ = settings.value("countShowNewsNotify", 10).toInt();
2113 widthTitleNewsNotify_ = settings.value("widthTitleNewsNotify", 300).toInt();
2114 timeShowNewsNotify_ = settings.value("timeShowNewsNotify", 10).toInt();
2115 fullscreenModeNotify_ = settings.value("fullscreenModeNotify", true).toBool();
2116 showNotifyInactiveApp_ = settings.value("showNotifyInactiveApp", true).toBool();
2117 onlySelectedFeeds_ = settings.value("onlySelectedFeeds", false).toBool();
2118 showTitlesFeedsNotify_ = settings.value("showTitlesFeedsNotify", true).toBool();
2119 showIconFeedNotify_ = settings.value("showIconFeedNotify", false).toBool();
2120 showButtonMarkAllNotify_ = settings.value("showButtonMarkAllNotify", true).toBool();
2121 showButtonMarkReadNotify_ = settings.value("showButtonMarkReadNotify", true).toBool();
2122 showButtonExBrowserNotify_ = settings.value("showButtonExBrowserNotify", true).toBool();
2123 showButtonDeleteNotify_ = settings.value("showButtonDeleteNotify", true).toBool();
2124 closeNotify_ = settings.value("closeNotify", true).toBool();
2125
2126 toolBarLockAct_->setChecked(settings.value("mainToolbarLock", true).toBool());
2127 lockMainToolbar(toolBarLockAct_->isChecked());
2128
2129 mainToolbarToggle_->setChecked(settings.value("mainToolbarShow2", false).toBool());
2130 feedsToolbarToggle_->setChecked(settings.value("feedsToolbarShow2", true).toBool());
2131 newsToolbarToggle_->setChecked(settings.value("newsToolbarShow", true).toBool());
2132 browserToolbarToggle_->setChecked(settings.value("browserToolbarShow", true).toBool());
2133 categoriesPanelToggle_->setChecked(settings.value("categoriesPanelShow", true).toBool());
2134 categoriesWidget_->setVisible(categoriesPanelToggle_->isChecked());
2135 statusBarToggle_->setChecked(settings.value("statusBarShow", true).toBool());
2136
2137 QString str = settings.value("mainToolBar",
2138 "newAct,Separator,updateFeedAct,updateAllFeedsAct,"
2139 "Separator,markFeedRead,Separator,autoLoadImagesToggle").toString();
2140
2141 foreach (QString actionStr, str.split(",", QString::SkipEmptyParts)) {
2142 if (actionStr == "Separator") {
2143 mainToolbar_->addSeparator();
2144 } else {
2145 QListIterator<QAction *> iter(actions());
2146 while (iter.hasNext()) {
2147 QAction *pAction = iter.next();
2148 if (!pAction->icon().isNull()) {
2149 if (pAction->objectName() == actionStr) {
2150 mainToolbar_->addAction(pAction);
2151 break;
2152 }
2153 }
2154 }
2155 }
2156 }
2157
2158 str = settings.value("feedsToolBar2",
2159 "newAct,Separator,updateAllFeedsAct,markFeedRead,"
2160 "Separator,feedsFilter,findFeedAct").toString();
2161
2162 foreach (QString actionStr, str.split(",", QString::SkipEmptyParts)) {
2163 if (actionStr == "Separator") {
2164 feedsToolBar_->addSeparator();
2165 } else {
2166 QListIterator<QAction *> iter(actions());
2167 while (iter.hasNext()) {
2168 QAction *pAction = iter.next();
2169 if (!pAction->icon().isNull()) {
2170 if (pAction->objectName() == actionStr) {
2171 feedsToolBar_->addAction(pAction);
2172 break;
2173 }
2174 }
2175 }
2176 }
2177 }
2178
2179 setToolBarStyle(settings.value("toolBarStyle", "toolBarStyleTuI_").toString());
2180 QString iconStr = settings.value("toolBarIconSize", "toolBarIconNormal_").toString();
2181 setToolBarIconSize(mainToolbar_, iconStr);
2182 iconStr = settings.value("feedsToolBarIconSize", "toolBarIconSmall_").toString();
2183 setToolBarIconSize(feedsToolBar_, iconStr);
2184
2185 str = settings.value("styleApplication", "defaultStyle_").toString();
2186 QList<QAction*> listActions = styleGroup_->actions();
2187 foreach(QAction *action, listActions) {
2188 if (action->objectName() == str) {
2189 action->setChecked(true);
2190 break;
2191 }
2192 }
2193
2194 showUnreadCount_->setChecked(settings.value("showUnreadCount", true).toBool());
2195 showUndeleteCount_->setChecked(settings.value("showUndeleteCount", false).toBool());
2196 showLastUpdated_->setChecked(settings.value("showLastUpdated", false).toBool());
2197 feedsColumnVisible(showUnreadCount_);
2198 feedsColumnVisible(showUndeleteCount_);
2199 feedsColumnVisible(showLastUpdated_);
2200
2201 indentationFeedsTreeAct_->setChecked(settings.value("indentationFeedsTree", true).toBool());
2202 slotIndentationFeedsTree();
2203
2204 newsLayout_ = settings.value("newsLayout", 0).toInt();
2205 switch (newsLayout_) {
2206 case 1:
2207 newspaperLayoutAct_->setChecked(true);
2208 layoutToggle_->setIcon(QIcon(":/images/layout_newspaper"));
2209 break;
2210 default:
2211 classicLayoutAct_->setChecked(true);
2212 layoutToggle_->setIcon(QIcon(":/images/layout_classic"));
2213 }
2214 connect(layoutGroup_, SIGNAL(triggered(QAction*)),
2215 this, SLOT(setNewsLayout(QAction*)));
2216
2217 browserPosition_ = settings.value("browserPosition", BOTTOM_POSITION).toInt();
2218 switch (browserPosition_) {
2219 case TOP_POSITION: topBrowserPositionAct_->setChecked(true); break;
2220 case RIGHT_POSITION: rightBrowserPositionAct_->setChecked(true); break;
2221 case LEFT_POSITION: leftBrowserPositionAct_->setChecked(true); break;
2222 default: bottomBrowserPositionAct_->setChecked(true);
2223 }
2224
2225 openLinkInBackground_ = settings.value("openLinkInBackground", true).toBool();
2226 openLinkInBackgroundEmbedded_ = settings.value("openLinkInBackgroundEmbedded", true).toBool();
2227 openingLinkTimeout_ = settings.value("openingLinkTimeout", 1000).toInt();
2228
2229 stayOnTopAct_->setChecked(settings.value("stayOnTop", false).toBool());
2230 if (stayOnTopAct_->isChecked())
2231 setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
2232 else
2233 setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
2234
2235 hideFeedsOpenTab_ = settings.value("hideFeedsOpenTab", false).toBool();
2236 showToggleFeedsTree_ = settings.value("showToggleFeedsTree", true).toBool();
2237 pushButtonNull_->setVisible(showToggleFeedsTree_);
2238
2239 defaultIconFeeds_ = settings.value("defaultIconFeeds", false).toBool();
2240 feedsModel_->defaultIconFeeds_ = defaultIconFeeds_;
2241 feedsView_->autocollapseFolder_ =
2242 settings.value("autocollapseFolder", false).toBool();
2243
2244 #ifndef Q_OS_MAC
2245 showMenuBarAct_->setChecked(settings.value("showMenuBar", false).toBool());
2246 #else
2247 showMenuBarAct_->setChecked(true);
2248 #endif
2249
2250 settings.endGroup();
2251
2252 settings.beginGroup("Color");
2253 QString windowTextColor = qApp->palette().brush(QPalette::WindowText).color().name();
2254 QString linkTextColor = qApp->palette().brush(QPalette::Link).color().name();
2255 feedsModel_->textColor_ = settings.value("feedsListTextColor", windowTextColor).toString();
2256 feedsModel_->backgroundColor_ = settings.value("feedsListBackgroundColor", "").toString();
2257 feedsView_->setStyleSheet(QString("#feedsView_ {background: %1;}").arg(feedsModel_->backgroundColor_));
2258 newsListTextColor_ = settings.value("newsListTextColor", windowTextColor).toString();
2259 newsListBackgroundColor_ = settings.value("newsListBackgroundColor", "").toString();
2260 newNewsTextColor_ = settings.value("newNewsTextColor", windowTextColor).toString();
2261 unreadNewsTextColor_ = settings.value("unreadNewsTextColor", windowTextColor).toString();
2262 focusedNewsTextColor_ = settings.value("focusedNewsTextColor", windowTextColor).toString();
2263 focusedNewsBGColor_ = settings.value("focusedNewsBGColor", "").toString();
2264 linkColor_ = settings.value("linkColor", "#0066CC").toString();
2265 titleColor_ = settings.value("titleColor", "#0066CC").toString();
2266 dateColor_ = settings.value("dateColor", "#666666").toString();
2267 authorColor_ = settings.value("authorColor", "#666666").toString();
2268 newsTextColor_ = settings.value("newsTextColor", "#000000").toString();
2269 newsTitleBackgroundColor_ = settings.value("newsTitleBackgroundColor", "#FFFFFF").toString();
2270 newsBackgroundColor_ = settings.value("newsBackgroundColor", "#FFFFFF").toString();
2271 feedsModel_->feedWithNewNewsColor_ = settings.value("feedWithNewNewsColor", linkTextColor).toString();
2272 feedsModel_->countNewsUnreadColor_ = settings.value("countNewsUnreadColor", linkTextColor).toString();
2273 feedsModel_->focusedFeedTextColor_ = settings.value("focusedFeedTextColor", windowTextColor).toString();
2274 feedsModel_->focusedFeedBGColor_ = settings.value("focusedFeedBGColor", "").toString();
2275 feedsModel_->feedDisabledUpdateColor_ = settings.value("feedDisabledUpdateColor", "#999999").toString();
2276 alternatingRowColors_ = settings.value("alternatingRowColors", qApp->palette().color(QPalette::AlternateBase).name()).toString();
2277 notifierTextColor_ = settings.value("notifierTextColor", windowTextColor).toString();
2278 notifierBackgroundColor_ = settings.value("notifierBackgroundColor", "#FFFFFF").toString();
2279 settings.endGroup();
2280
2281 resize(800, 600);
2282 restoreGeometry(settings.value("GeometryState").toByteArray());
2283 restoreState(settings.value("ToolBarsState").toByteArray());
2284
2285 if (!mainToolbarToggle_->isChecked())
2286 mainToolbar_->hide();
2287 if (!feedsToolbarToggle_->isChecked())
2288 feedsPanel_->hide();
2289 if (!statusBarToggle_->isChecked())
2290 statusBar()->hide();
2291
2292 mainSplitter_->restoreState(settings.value("MainSplitterState").toByteArray());
2293 feedsWidgetVisibleAct_->setChecked(settings.value("FeedsWidgetVisible", true).toBool());
2294 slotVisibledFeedsWidget();
2295
2296 feedsWidgetSplitterState_ = settings.value("FeedsWidgetSplitterState").toByteArray();
2297 bool showCategories = settings.value("NewsCategoriesTreeVisible", true).toBool();
2298 categoriesTree_->setVisible(showCategories);
2299 if (showCategories) {
2300 showCategoriesButton_->setIcon(QIcon(":/images/images/panel_hide.png"));
2301 showCategoriesButton_->setToolTip(tr("Hide Categories"));
2302 feedsSplitter_->restoreState(feedsWidgetSplitterState_);
2303 } else {
2304 showCategoriesButton_->setIcon(QIcon(":/images/images/panel_show.png"));
2305 showCategoriesButton_->setToolTip(tr("Show Categories"));
2306 QList <int> sizes;
2307 sizes << QApplication::desktop()->height() << 20;
2308 feedsSplitter_->setSizes(sizes);
2309 }
2310 bool expandCategories = settings.value("categoriesTreeExpanded", true).toBool();
2311 if (expandCategories)
2312 categoriesTree_->expandAll();
2313
2314 showMenuBar();
2315
2316 adblockIcon_->setEnabled(settings.value("AdBlock/enabled", true).toBool());
2317 }
2318
2319 /** @brief Save settings in ini-file
2320 *---------------------------------------------------------------------------*/
saveSettings()2321 void MainWindow::saveSettings()
2322 {
2323 Settings settings;
2324 settings.beginGroup("Settings");
2325
2326 settings.setValue("showSplashScreen", showSplashScreen_);
2327 settings.setValue("reopenFeedStartup", reopenFeedStartup_);
2328 settings.setValue("openNewTabNextToActive", openNewTabNextToActive_);
2329
2330 settings.setValue("createLastFeed", mainApp->isSaveDataLastFeed());
2331
2332 settings.setValue("showTrayIcon", showTrayIcon_);
2333 settings.setValue("startingTray", startingTray_);
2334 settings.setValue("minimizingTray", minimizingTray_);
2335 settings.setValue("closingTray", closingTray_);
2336 settings.setValue("behaviorIconTray", behaviorIconTray_);
2337 settings.setValue("singleClickTray", singleClickTray_);
2338 settings.setValue("clearStatusNew", clearStatusNew_);
2339 settings.setValue("emptyWorking", emptyWorking_);
2340
2341 settings.setValue("langFileName", mainApp->language());
2342
2343 QString fontFamily = feedsView_->font().family();
2344 settings.setValue("feedsFontFamily", fontFamily);
2345 int fontSize = feedsView_->font().pointSize();
2346 settings.setValue("feedsFontSize", fontSize);
2347
2348 settings.setValue("newsFontFamily", newsListFontFamily_);
2349 settings.setValue("newsFontSize", newsListFontSize_);
2350 settings.setValue("newsTitleFontFamily", newsTitleFontFamily_);
2351 settings.setValue("newsTitleFontSize", newsTitleFontSize_);
2352 settings.setValue("newsTextFontFamily", newsTextFontFamily_);
2353 settings.setValue("newsTextFontSize", newsTextFontSize_);
2354 settings.setValue("notificationFontFamily", notificationFontFamily_);
2355 settings.setValue("notificationFontSize", notificationFontSize_);
2356
2357 settings.setValue("autoUpdatefeeds", updateFeedsEnable_);
2358 settings.setValue("autoUpdatefeedsTime", updateFeedsInterval_);
2359 settings.setValue("autoUpdatefeedsInterval", updateFeedsIntervalType_);
2360
2361 settings.setValue("openingFeedAction", openingFeedAction_);
2362 settings.setValue("openNewsWebViewOn", openNewsWebViewOn_);
2363
2364 settings.setValue("markNewsReadOn", markNewsReadOn_);
2365 settings.setValue("markCurNewsRead", markCurNewsRead_);
2366 settings.setValue("markNewsReadTime", markNewsReadTime_);
2367 settings.setValue("markPrevNewsRead", markPrevNewsRead_);
2368 settings.setValue("markReadSwitchingFeed", markReadSwitchingFeed_);
2369 settings.setValue("markReadClosingTab", markReadClosingTab_);
2370 settings.setValue("markReadMinimize", markReadMinimize_);
2371
2372 settings.setValue("showDescriptionNews", showDescriptionNews_);
2373
2374 settings.setValue("formatData", formatDate_);
2375 settings.setValue("formatTime", formatTime_);
2376
2377 settings.setValue("alternatingColorsNews", alternatingRowColorsNews_);
2378 settings.setValue("changeBehaviorActionNUN", changeBehaviorActionNUN_);
2379 settings.setValue("simplifiedDateTime", simplifiedDateTime_);
2380 settings.setValue("notDeleteStarred", notDeleteStarred_);
2381 settings.setValue("notDeleteLabeled", notDeleteLabeled_);
2382 settings.setValue("markIdenticalNewsRead", markIdenticalNewsRead_);
2383 settings.setValue("avoidOldNews", avoidOldNews_);
2384 settings.setValue("avoidedOldNewsDate", avoidedOldNewsDate_);
2385
2386 settings.setValue("mainNewsFilter", mainNewsFilter_);
2387
2388 settings.setValue("cleanupOnShutdown", cleanupOnShutdown_);
2389 settings.setValue("maxDayClearUp", maxDayCleanUp_);
2390 settings.setValue("maxNewsClearUp", maxNewsCleanUp_);
2391 settings.setValue("dayClearUpOn", dayCleanUpOn_);
2392 settings.setValue("newsClearUpOn", newsCleanUpOn_);
2393 settings.setValue("readClearUp", readCleanUp_);
2394 settings.setValue("neverUnreadClearUp", neverUnreadCleanUp_);
2395 settings.setValue("neverStarClearUp", neverStarCleanUp_);
2396 settings.setValue("neverLabelClearUp", neverLabelCleanUp_);
2397 settings.setValue("cleanUpDeleted", cleanUpDeleted_);
2398 settings.setValue("optimizeDB", optimizeDB_);
2399
2400 settings.setValue("externalBrowserOn", externalBrowserOn_);
2401 settings.setValue("externalBrowser", externalBrowser_);
2402 settings.setValue("javaScriptEnable", javaScriptEnable_);
2403 settings.setValue("pluginsEnable", pluginsEnable_);
2404 settings.setValue("maxPagesInCache", maxPagesInCache_);
2405 settings.setValue("downloadLocation", downloadLocation_);
2406 settings.setValue("askDownloadLocation", askDownloadLocation_);
2407 settings.setValue("defaultZoomPages", defaultZoomPages_);
2408 settings.setValue("autoLoadImages", autoLoadImages_);
2409
2410 settings.setValue("soundNewNews", soundNewNews_);
2411 settings.setValue("soundNotifyPath", soundNotifyPath_);
2412 settings.setValue("showNotifyOn", showNotifyOn_);
2413 settings.setValue("screenNotify", screenNotify_);
2414 settings.setValue("positionNotify", positionNotify_);
2415 settings.setValue("transparencyNotify", transparencyNotify_);
2416 settings.setValue("countShowNewsNotify", countShowNewsNotify_);
2417 settings.setValue("widthTitleNewsNotify", widthTitleNewsNotify_);
2418 settings.setValue("timeShowNewsNotify", timeShowNewsNotify_);
2419 settings.setValue("fullscreenModeNotify", fullscreenModeNotify_);
2420 settings.setValue("showNotifyInactiveApp", showNotifyInactiveApp_);
2421 settings.setValue("onlySelectedFeeds", onlySelectedFeeds_);
2422 settings.setValue("showTitlesFeedsNotify", showTitlesFeedsNotify_);
2423 settings.setValue("showIconFeedNotify", showIconFeedNotify_);
2424 settings.setValue("showButtonMarkAllNotify", showButtonMarkAllNotify_);
2425 settings.setValue("showButtonMarkReadNotify", showButtonMarkReadNotify_);
2426 settings.setValue("showButtonExBrowserNotify", showButtonExBrowserNotify_);
2427 settings.setValue("showButtonDeleteNotify", showButtonDeleteNotify_);
2428 settings.setValue("closeNotify", closeNotify_);
2429
2430 settings.setValue("mainToolbarLock", toolBarLockAct_->isChecked());
2431
2432 settings.setValue("mainToolbarShow2", mainToolbarToggle_->isChecked());
2433 settings.setValue("feedsToolbarShow2", feedsToolbarToggle_->isChecked());
2434 settings.setValue("newsToolbarShow", newsToolbarToggle_->isChecked());
2435 settings.setValue("browserToolbarShow", browserToolbarToggle_->isChecked());
2436 settings.setValue("categoriesPanelShow", categoriesPanelToggle_->isChecked());
2437 settings.setValue("statusBarShow", statusBarToggle_->isChecked());
2438
2439 settings.setValue("styleApplication",
2440 styleGroup_->checkedAction()->objectName());
2441
2442 settings.setValue("showUnreadCount", showUnreadCount_->isChecked());
2443 settings.setValue("showUndeleteCount", showUndeleteCount_->isChecked());
2444 settings.setValue("showLastUpdated", showLastUpdated_->isChecked());
2445
2446 settings.setValue("indentationFeedsTree", indentationFeedsTreeAct_->isChecked());
2447
2448 settings.setValue("newsLayout", newsLayout_);
2449 settings.setValue("browserPosition", browserPosition_);
2450
2451 settings.setValue("openLinkInBackground", openLinkInBackground_);
2452 settings.setValue("openLinkInBackgroundEmbedded", openLinkInBackgroundEmbedded_);
2453 settings.setValue("openingLinkTimeout", openingLinkTimeout_);
2454
2455 settings.setValue("stayOnTop", stayOnTopAct_->isChecked());
2456
2457 settings.setValue("hideFeedsOpenTab", hideFeedsOpenTab_);
2458 settings.setValue("showToggleFeedsTree", showToggleFeedsTree_);
2459
2460 settings.setValue("defaultIconFeeds", defaultIconFeeds_);
2461 settings.setValue("autocollapseFolder", feedsView_->autocollapseFolder_);
2462
2463 settings.setValue("showMenuBar", showMenuBarAct_->isChecked());
2464
2465 settings.endGroup();
2466
2467 settings.beginGroup("Color");
2468 settings.setValue("feedsListTextColor", feedsModel_->textColor_);
2469 settings.setValue("feedsListBackgroundColor", feedsModel_->backgroundColor_);
2470 settings.setValue("newsListTextColor", newsListTextColor_);
2471 settings.setValue("newsListBackgroundColor", newsListBackgroundColor_);
2472 settings.setValue("newNewsTextColor", newNewsTextColor_);
2473 settings.setValue("unreadNewsTextColor", unreadNewsTextColor_);
2474 settings.setValue("focusedNewsTextColor", focusedNewsTextColor_);
2475 settings.setValue("focusedNewsBGColor", focusedNewsBGColor_);
2476 settings.setValue("linkColor", linkColor_);
2477 settings.setValue("titleColor", titleColor_);
2478 settings.setValue("dateColor", dateColor_);
2479 settings.setValue("authorColor", authorColor_);
2480 settings.setValue("newsTextColor", newsTextColor_);
2481 settings.setValue("newsTitleBackgroundColor", newsTitleBackgroundColor_);
2482 settings.setValue("newsBackgroundColor", newsBackgroundColor_);
2483 settings.setValue("feedWithNewNewsColor", feedsModel_->feedWithNewNewsColor_);
2484 settings.setValue("countNewsUnreadColor", feedsModel_->countNewsUnreadColor_);
2485 settings.setValue("focusedFeedTextColor", feedsModel_->focusedFeedTextColor_);
2486 settings.setValue("focusedFeedBGColor", feedsModel_->focusedFeedBGColor_);
2487 settings.setValue("feedDisabledUpdateColor", feedsModel_->feedDisabledUpdateColor_);
2488 settings.setValue("alternatingRowColors", alternatingRowColors_);
2489 settings.setValue("notifierTextColor", notifierTextColor_);
2490 settings.setValue("notifierBackgroundColor", notifierBackgroundColor_);
2491 settings.endGroup();
2492
2493 settings.setValue("GeometryState", saveGeometry());
2494 settings.setValue("ToolBarsState", saveState());
2495
2496 settings.setValue("MainSplitterState", mainSplitter_->saveState());
2497 settings.setValue("FeedsWidgetVisible", showFeedsTabPermanent_);
2498
2499 bool newsCategoriesTreeVisible = true;
2500 if (categoriesWidget_->height() <= (categoriesPanel_->height()+2)) {
2501 newsCategoriesTreeVisible = false;
2502 settings.setValue("FeedsWidgetSplitterState", feedsWidgetSplitterState_);
2503 } else {
2504 settings.setValue("FeedsWidgetSplitterState", feedsSplitter_->saveState());
2505 }
2506 settings.setValue("NewsCategoriesTreeVisible", newsCategoriesTreeVisible);
2507 settings.setValue("categoriesTreeExpanded", categoriesTree_->topLevelItem(CategoriesTreeWidget::LabelsItem)->isExpanded());
2508
2509 if (stackedWidget_->count()) {
2510 NewsTabWidget *widget;
2511 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb)
2512 widget = currentNewsTab;
2513 else
2514 widget = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
2515
2516 widget->newsHeader_->saveStateColumns(widget);
2517 settings.setValue("NewsTabSplitterState",
2518 widget->newsTabWidgetSplitter_->saveState());
2519 }
2520
2521 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
2522 settings.setValue("feedSettings/currentId", widget->feedId_);
2523 settings.setValue("feedSettings/filterName",
2524 feedsFilterGroup_->checkedAction()->objectName());
2525 settings.setValue("newsSettings/filterName",
2526 newsFilterGroup_->checkedAction()->objectName());
2527
2528 mainApp->cookieJar()->saveCookies();
2529 mainApp->c2fSaveSettings();
2530 AdBlockManager::instance()->save();
2531 }
2532
showMainMenu()2533 void MainWindow::showMainMenu()
2534 {
2535 #ifndef Q_OS_MAC
2536 mainMenu_->popup(mainMenuButton_->mapToGlobal(QPoint(0, mainMenuButton_->height())));
2537 #endif
2538 }
2539
2540 /** @brief Add feed to feed list
2541 *---------------------------------------------------------------------------*/
addFeed()2542 void MainWindow::addFeed()
2543 {
2544 int curFolderId = 0;
2545 QPersistentModelIndex curIndex = feedsView_->selectIndex();
2546 if (feedsModel_->isFolder(curIndex)) {
2547 curFolderId = feedsModel_->idByIndex(curIndex);
2548 } else {
2549 curFolderId = feedsModel_->paridByIndex(curIndex);
2550 }
2551
2552 AddFeedWizard *addFeedWizard = new AddFeedWizard(this, curFolderId);
2553 addFeedWizard->show();
2554
2555 int result = addFeedWizard->exec();
2556 if (result == QDialog::Rejected) {
2557 delete addFeedWizard;
2558 return;
2559 }
2560
2561 emit faviconRequestUrl(addFeedWizard->htmlUrlString_, addFeedWizard->feedUrlString_);
2562
2563 QList<int> categoriesList;
2564 categoriesList << addFeedWizard->feedParentId_;
2565 recountFeedCategories(categoriesList);
2566
2567 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2568 feedsView_->setCurrentIndex(QModelIndex());
2569 feedsModelReload();
2570 QModelIndex index = feedsProxyModel_->mapFromSource(addFeedWizard->feedId_);
2571 feedsView_->selectIdEn_ = true;
2572 feedsView_->setCurrentIndex(index);
2573 slotFeedClicked(index);
2574 QApplication::restoreOverrideCursor();
2575 slotUpdateFeed(addFeedWizard->feedId_, true, addFeedWizard->newCount_, false);
2576
2577 delete addFeedWizard;
2578 }
2579
2580 /** @brief Add folder to feed list
2581 *---------------------------------------------------------------------------*/
addFolder()2582 void MainWindow::addFolder()
2583 {
2584 int curFolderId = 0;
2585 QPersistentModelIndex curIndex = feedsView_->selectIndex();
2586 if (feedsModel_->isFolder(curIndex)) {
2587 curFolderId = feedsModel_->idByIndex(curIndex);
2588 } else {
2589 curFolderId = feedsModel_->paridByIndex(curIndex);
2590 }
2591
2592 AddFolderDialog *addFolderDialog = new AddFolderDialog(this, curFolderId);
2593
2594 if (addFolderDialog->exec() == QDialog::Rejected) {
2595 delete addFolderDialog;
2596 return;
2597 }
2598
2599 QString folderText = addFolderDialog->nameFeedEdit_->text();
2600 int parentId = addFolderDialog->foldersTree_->currentItem()->text(1).toInt();
2601
2602 QSqlQuery q;
2603
2604 // Determine row number for folder
2605 int rowToParent = 0;
2606 q.exec(QString("SELECT count(id) FROM feeds WHERE parentId='%1'").
2607 arg(parentId));
2608 if (q.next()) rowToParent = q.value(0).toInt();
2609
2610 // Add feed to DB
2611 q.prepare("INSERT INTO feeds(text, created, parentId, rowToParent) "
2612 "VALUES (:text, :feedCreateTime, :parentId, :rowToParent)");
2613 q.bindValue(":text", folderText);
2614 q.bindValue(":feedCreateTime",
2615 QLocale::c().toString(QDateTime::currentDateTimeUtc(), "yyyy-MM-ddTHH:mm:ss"));
2616 q.bindValue(":parentId", parentId);
2617 q.bindValue(":rowToParent", rowToParent);
2618 q.exec();
2619
2620 delete addFolderDialog;
2621
2622 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2623 feedsModelReload();
2624 QApplication::restoreOverrideCursor();
2625 }
2626
2627 /** @brief Delete feed list item with confirmation
2628 *---------------------------------------------------------------------------*/
deleteItemFeedsTree()2629 void MainWindow::deleteItemFeedsTree()
2630 {
2631 if (!feedsView_->selectIndex().isValid()) return;
2632
2633 QMessageBox msgBox(this);
2634 msgBox.setIcon(QMessageBox::Question);
2635 msgBox.setWindowTitle(tr("Confirm Delete"));
2636 msgBox.setText(tr("Are you sure to delete selected elements?"));
2637 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
2638 msgBox.setDefaultButton(QMessageBox::No);
2639
2640 if (msgBox.exec() == QMessageBox::No) return;
2641
2642 QModelIndex currentIndex = feedsProxyModel_->mapToSource(feedsView_->currentIndex());
2643 int feedIdCur = feedsModel_->idByIndex(currentIndex);
2644
2645 QModelIndexList indexList = feedsView_->selectionModel()->selectedRows(0);
2646 if (indexList.count() <= 1) {
2647 indexList.clear();
2648 indexList.append(feedsProxyModel_->mapFromSource(feedsView_->selectIndex()));
2649 }
2650
2651 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
2652
2653 QList<int> idList;
2654 QList<int> parentIdList;
2655 for (int i = indexList.count()-1; i >= 0; --i) {
2656 QModelIndex index = feedsProxyModel_->mapToSource(indexList[i]);
2657 if (feedsModel_->isFolder(index)) {
2658 idList.append(feedsModel_->dataField(index, "id").toInt());
2659 int parentId = feedsModel_->dataField(index, "parentId").toInt();
2660 if (!parentIdList.contains(parentId)) {
2661 parentIdList.append(parentId);
2662 }
2663 indexList.removeAt(i);
2664 }
2665 }
2666 for (int i = indexList.count()-1; i >= 0; --i) {
2667 QModelIndex index = feedsProxyModel_->mapToSource(indexList[i]);
2668 int parentId = feedsModel_->dataField(index, "parentId").toInt();
2669 if (!idList.contains(parentId)) {
2670 idList.append(feedsModel_->dataField(index, "id").toInt());
2671 int parentId = feedsModel_->dataField(index, "parentId").toInt();
2672 if (!parentIdList.contains(parentId)) {
2673 parentIdList.append(parentId);
2674 }
2675 }
2676 indexList.removeAt(i);
2677 }
2678
2679 db_.transaction();
2680 QSqlQuery q;
2681 QString idStr;
2682 QString feedIdStr;
2683 foreach (int feedId, idList) {
2684 if (idStr.isEmpty()) {
2685 idStr.append(QString("id='%1'").arg(feedId));
2686 feedIdStr.append(QString("feedId='%1'").arg(feedId));
2687 } else {
2688 idStr.append(QString(" OR id='%1'").arg(feedId));
2689 feedIdStr.append(QString(" OR feedId='%1'").arg(feedId));
2690 }
2691 QQueue<int> parentIds;
2692 parentIds.enqueue(feedId);
2693 while (!parentIds.empty()) {
2694 int parentId = parentIds.dequeue();
2695 q.exec(QString("SELECT id FROM feeds WHERE parentId='%1'").arg(parentId));
2696 while (q.next()) {
2697 int feedId = q.value(0).toInt();
2698
2699 idStr.append(QString(" OR id='%1'").arg(feedId));
2700 feedIdStr.append(QString(" OR feedId='%1'").arg(feedId));
2701
2702 parentIds.enqueue(feedId);
2703 }
2704 }
2705 }
2706 q.exec(QString("DELETE FROM feeds WHERE %1").arg(idStr));
2707 q.exec(QString("DELETE FROM news WHERE %1").arg(feedIdStr));
2708 db_.commit();
2709
2710 // Correction row
2711 foreach (int parentId, parentIdList) {
2712 QList<int> idCorrectList;
2713 q.exec(QString("SELECT id FROM feeds WHERE parentId='%1' ORDER BY rowToParent").
2714 arg(parentId));
2715 while (q.next()) {
2716 idCorrectList << q.value(0).toInt();
2717 }
2718 for (int i = 0; i < idCorrectList.count(); i++) {
2719 q.exec(QString("UPDATE feeds SET rowToParent='%1' WHERE id=='%2'").
2720 arg(i).arg(idCorrectList.at(i)));
2721 }
2722 }
2723
2724 recountFeedCategories(parentIdList);
2725 feedsModelReload();
2726 currentIndex = feedsProxyModel_->mapFromSource(feedIdCur);
2727 feedsView_->setCurrentIndex(currentIndex);
2728 slotFeedClicked(currentIndex);
2729
2730 QApplication::restoreOverrideCursor();
2731 }
2732
2733 /** @brief Import feeds from OPML-file
2734 *
2735 * Calls open file system dialog with filter *.opml.
2736 * Adds all feeds to DB include hierarchy, ignore duplicate feeds
2737 *---------------------------------------------------------------------------*/
slotImportFeeds()2738 void MainWindow::slotImportFeeds()
2739 {
2740 QString fileName = QFileDialog::getOpenFileName(this, tr("Select OPML-File"),
2741 QDir::homePath(),
2742 QString(tr("OPML-Files (*.%1 *.%2)"))
2743 .arg("opml").arg("xml"));
2744
2745 if (fileName.isNull()) {
2746 statusBar()->showMessage(tr("Import canceled"), 3000);
2747 return;
2748 }
2749
2750 qDebug() << "import file:" << fileName;
2751
2752 QFile file(fileName);
2753 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
2754 statusBar()->showMessage(tr("Import: can't open a file"), 3000);
2755 return;
2756 }
2757
2758 QByteArray xmlData = file.readAll();
2759 file.close();
2760
2761 isStartImportFeed_ = true;
2762 emit signalImportFeeds(xmlData);
2763 }
2764
2765 /** @brief Export feeds to OPML-file
2766 *---------------------------------------------------------------------------*/
slotExportFeeds()2767 void MainWindow::slotExportFeeds()
2768 {
2769 QString fileName = QFileDialog::getSaveFileName(this, tr("Select OPML-File"),
2770 QDir::homePath(),
2771 QString(tr("OPML-Files (*.%1)"))
2772 .arg("opml"));
2773
2774 if (fileName.isNull()) {
2775 statusBar()->showMessage(tr("Export canceled"), 3000);
2776 return;
2777 }
2778
2779 QFile file(fileName);
2780 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
2781 statusBar()->showMessage(tr("Export: can't open a file"), 3000);
2782 return;
2783 }
2784
2785 QXmlStreamWriter xml(&file);
2786 xml.setAutoFormatting(true);
2787 xml.writeStartDocument();
2788 xml.writeStartElement("opml");
2789 xml.writeAttribute("version", "2.0");
2790 xml.writeStartElement("head");
2791 xml.writeTextElement("title", "QuiteRSS");
2792 xml.writeTextElement("dateModified", QDateTime::currentDateTime().toString());
2793 xml.writeEndElement(); // </head>
2794
2795 xml.writeStartElement("body");
2796
2797 // Create model and view for export
2798 // Expand the view to step on every item
2799 FeedsModel exportTreeModel(this);
2800 QTreeView exportTreeView;
2801 exportTreeView.setModel(&exportTreeModel);
2802 exportTreeModel.setView(feedsView_);
2803 exportTreeView.expandAll();
2804
2805 QModelIndex index = exportTreeModel.index(0, 0);
2806 QStack<int> parentIdsStack;
2807 parentIdsStack.push(0);
2808 while (index.isValid()) {
2809 int feedId = exportTreeModel.idByIndex(index);
2810 int feedParId = exportTreeModel.paridByIndex(index);
2811
2812 // Parent differs from previouse one - close folder
2813 while (feedParId != parentIdsStack.top()) {
2814 xml.writeEndElement(); // "outline" - folder finishes
2815 parentIdsStack.pop();
2816 }
2817
2818 // Folder has found. Open it
2819 if (exportTreeModel.isFolder(index)) {
2820 parentIdsStack.push(feedId);
2821 xml.writeStartElement("outline"); // Folder starts
2822 xml.writeAttribute("text", exportTreeModel.dataField(index, "text").toString());
2823 }
2824 // Feed has found. Save it
2825 else {
2826 xml.writeEmptyElement("outline");
2827 xml.writeAttribute("text", exportTreeModel.dataField(index, "text").toString());
2828 xml.writeAttribute("type", "rss");
2829 xml.writeAttribute("htmlUrl", exportTreeModel.dataField(index, "htmlUrl").toString());
2830 xml.writeAttribute("xmlUrl", exportTreeModel.dataField(index, "xmlUrl").toString());
2831 }
2832
2833 index = exportTreeView.indexBelow(index);
2834 }
2835
2836 xml.writeEndElement(); // </body>
2837
2838 xml.writeEndElement(); // </opml>
2839 xml.writeEndDocument();
2840
2841 file.close();
2842 }
2843 // ----------------------------------------------------------------------------
slotFeedsViewportUpdate()2844 void MainWindow::slotFeedsViewportUpdate()
2845 {
2846 feedsView_->viewport()->update();
2847 #ifdef HAVE_QT5
2848 feedsView_->header()->setSectionResizeMode(feedsView_->columnIndex("unread"), QHeaderView::ResizeToContents);
2849 feedsView_->header()->setSectionResizeMode(feedsView_->columnIndex("undeleteCount"), QHeaderView::ResizeToContents);
2850 feedsView_->header()->setSectionResizeMode(feedsView_->columnIndex("updated"), QHeaderView::ResizeToContents);
2851 #else
2852 feedsView_->header()->setResizeMode(feedsView_->columnIndex("unread"), QHeaderView::ResizeToContents);
2853 feedsView_->header()->setResizeMode(feedsView_->columnIndex("undeleteCount"), QHeaderView::ResizeToContents);
2854 feedsView_->header()->setResizeMode(feedsView_->columnIndex("updated"), QHeaderView::ResizeToContents);
2855 #endif
2856 }
2857 // ----------------------------------------------------------------------------
slotFeedCountsUpdate(FeedCountStruct counts)2858 void MainWindow::slotFeedCountsUpdate(FeedCountStruct counts)
2859 {
2860 QModelIndex index = feedsModel_->indexById(counts.feedId);
2861 if (index.isValid()) {
2862 QModelIndex indexUnread = feedsModel_->indexSibling(index, "unread");
2863 QModelIndex indexNew = feedsModel_->indexSibling(index, "newCount");
2864 QModelIndex indexUndelete = feedsModel_->indexSibling(index, "undeleteCount");
2865 feedsModel_->setData(indexUnread, counts.unreadCount);
2866 feedsModel_->setData(indexNew, counts.newCount);
2867 feedsModel_->setData(indexUndelete, counts.undeleteCount);
2868
2869 if (!counts.updated.isEmpty()) {
2870 QModelIndex indexUpdated = feedsModel_->indexSibling(index, "updated");
2871 feedsModel_->setData(indexUpdated, counts.updated);
2872 }
2873
2874 if (!counts.lastBuildDate.isEmpty()) {
2875 QModelIndex indexLastBuildDate = feedsModel_->indexSibling(index, "lastBuildDate");
2876 feedsModel_->setData(indexLastBuildDate, counts.lastBuildDate);
2877 }
2878
2879 if (!counts.htmlUrl.isEmpty()) {
2880 QModelIndex indexHtmlUrl = feedsModel_->indexSibling(index, "htmlUrl");
2881 feedsModel_->setData(indexHtmlUrl, counts.htmlUrl);
2882 }
2883
2884 if (!counts.title.isEmpty()) {
2885 QModelIndex indexTitle = feedsModel_->indexSibling(index, "title");
2886 feedsModel_->setData(indexTitle, counts.title);
2887 }
2888 }
2889
2890 if (isStartImportFeed_ && !counts.xmlUrl.isEmpty()) {
2891 emit faviconRequestUrl(counts.htmlUrl, counts.xmlUrl);
2892 }
2893 }
2894
2895 /** @brief Recalculate counters for specified categories
2896 * @details Processing DB data. Model "reselect()" needed.
2897 * @param categoriesList - categories identifiers list for processing
2898 *---------------------------------------------------------------------------*/
recountFeedCategories(const QList<int> & categoriesList)2899 void MainWindow::recountFeedCategories(const QList<int> &categoriesList)
2900 {
2901 QSqlQuery q;
2902 QString qStr;
2903
2904 foreach (int categoryIdStart, categoriesList) {
2905 if (categoryIdStart < 1) continue;
2906
2907 int categoryId = categoryIdStart;
2908 // Process all parents
2909 while (0 < categoryId) {
2910 int unreadCount = -1;
2911 int undeleteCount = -1;
2912 int newCount = -1;
2913
2914 // Calculate sum of all feeds with same parent
2915 qStr = QString("SELECT sum(unread), sum(undeleteCount), sum(newCount) "
2916 "FROM feeds WHERE parentId=='%1'").arg(categoryId);
2917 q.exec(qStr);
2918 if (q.next()) {
2919 unreadCount = q.value(0).toInt();
2920 undeleteCount = q.value(1).toInt();
2921 newCount = q.value(2).toInt();
2922 }
2923
2924 if (unreadCount != -1) {
2925 qStr = QString("UPDATE feeds SET unread='%1', undeleteCount='%2', newCount='%3' WHERE id=='%4'").
2926 arg(unreadCount).arg(undeleteCount).arg(newCount).arg(categoryId);
2927 q.exec(qStr);
2928 }
2929
2930 // go to next parent's parent
2931 qStr = QString("SELECT parentId FROM feeds WHERE id=='%1'").
2932 arg(categoryId);
2933 categoryId = 0;
2934 q.exec(qStr);
2935 if (q.next()) categoryId = q.value(0).toInt();
2936 }
2937 }
2938 }
2939 // ----------------------------------------------------------------------------
recountCategoryCounts()2940 void MainWindow::recountCategoryCounts()
2941 {
2942 if (recountCategoryCountsOn_) return;
2943
2944 if (!categoriesTree_->isVisible() || !stackedWidget_->count()) return;
2945
2946 recountCategoryCountsOn_ = true;
2947 emit signalRecountCategoryCounts();
2948 }
2949
2950 /** @brief Process recalculating categories counters
2951 *----------------------------------------------------------------------------*/
slotRecountCategoryCounts(QList<int> deletedList,QList<int> starredList,QList<int> readList,QStringList labelList)2952 void MainWindow::slotRecountCategoryCounts(QList<int> deletedList, QList<int> starredList,
2953 QList<int> readList, QStringList labelList)
2954 {
2955 int allStarredCount = 0;
2956 int unreadStarredCount = 0;
2957 int deletedCount = 0;
2958 QMap<int,int> allCountList;
2959 QMap<int,int> unreadCountList;
2960 int allLabelCount = 0;
2961 int unreadLabelCount = 0;
2962 QFont font;
2963
2964 QTreeWidgetItem *labelTreeItem = categoriesTree_->topLevelItem(CategoriesTreeWidget::LabelsItem);
2965 for (int i = 0; i < labelTreeItem->childCount(); i++) {
2966 int id = labelTreeItem->child(i)->text(2).toInt();
2967 allCountList.insert(id, 0);
2968 unreadCountList.insert(id, 0);
2969 }
2970
2971 for (int i = 0; i < deletedList.count(); ++i) {
2972 if (deletedList.at(i) == 0) {
2973 if (starredList.at(i) == 1) {
2974 allStarredCount++;
2975 if (readList.at(i) == 0)
2976 unreadStarredCount++;
2977 }
2978 QString idString = labelList.at(i);
2979 if (!idString.isEmpty() && idString != ",") {
2980 QStringList idList = idString.split(",", QString::SkipEmptyParts);
2981 foreach (QString idStr, idList) {
2982 int id = idStr.toInt();
2983 if (allCountList.contains(id)) {
2984 allCountList[id]++;
2985 if (readList.at(i) == 0)
2986 unreadCountList[id]++;
2987 }
2988 }
2989 }
2990 } else if (deletedList.at(i) == 1) {
2991 deletedCount++;
2992 }
2993 }
2994
2995 for (int i = 0; i < labelTreeItem->childCount(); i++) {
2996 int id = labelTreeItem->child(i)->text(2).toInt();
2997 QString countStr;
2998 if (!unreadCountList[id] && !allCountList[id])
2999 countStr = "";
3000 else
3001 countStr = QString("(%1/%2)").arg(unreadCountList[id]).arg(allCountList[id]);
3002 labelTreeItem->child(i)->setText(4, countStr);
3003 font = labelTreeItem->child(i)->font(0);
3004 if (unreadCountList[id])
3005 font.setBold(true);
3006 else
3007 font.setBold(false);
3008 labelTreeItem->child(i)->setFont(0, font);
3009
3010 unreadLabelCount = unreadLabelCount + unreadCountList[id];
3011 allLabelCount = allLabelCount + allCountList[id];
3012 }
3013
3014 QString countStr;
3015 if (!unreadStarredCount && !allStarredCount)
3016 countStr = "";
3017 else
3018 countStr = QString("(%1/%2)").arg(unreadStarredCount).arg(allStarredCount);
3019 categoriesTree_->topLevelItem(CategoriesTreeWidget::StarredItem)->setText(4, countStr);
3020 font = categoriesTree_->topLevelItem(CategoriesTreeWidget::StarredItem)->font(0);
3021 if (unreadStarredCount)
3022 font.setBold(true);
3023 else
3024 font.setBold(false);
3025 categoriesTree_->topLevelItem(CategoriesTreeWidget::StarredItem)->setFont(0, font);
3026
3027 if (!deletedCount)
3028 countStr = "";
3029 else
3030 countStr = QString("(%1)").arg(deletedCount);
3031 categoriesTree_->topLevelItem(CategoriesTreeWidget::DeletedItem)->setText(4, countStr);
3032
3033 if (!unreadLabelCount && !allLabelCount)
3034 countStr = "";
3035 else
3036 countStr = QString("(%1/%2)").arg(unreadLabelCount).arg(allLabelCount);
3037 categoriesTree_->topLevelItem(CategoriesTreeWidget::LabelsItem)->setText(4, countStr);
3038 font = categoriesTree_->topLevelItem(CategoriesTreeWidget::LabelsItem)->font(0);
3039 if (unreadLabelCount)
3040 font.setBold(true);
3041 else
3042 font.setBold(false);
3043 categoriesTree_->topLevelItem(CategoriesTreeWidget::LabelsItem)->setFont(0, font);
3044
3045 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(stackedWidget_->currentIndex());
3046 if ((widget->type_ > NewsTabWidget::TabTypeFeed) && (widget->type_ < NewsTabWidget::TabTypeWeb)
3047 && categoriesTree_->currentIndex().isValid()) {
3048 int unreadCount = widget->getUnreadCount(categoriesTree_->currentItem()->text(4));
3049 int allCount = widget->newsModel_->rowCount();
3050 statusUnread_->setText(QString(" " + tr("Unread: %1") + " ").arg(unreadCount));
3051 statusAll_->setText(QString(" " + tr("All: %1") + " ").arg(allCount));
3052 }
3053
3054 recountCategoryCountsOn_ = false;
3055 }
3056
3057 /** @brief Update feed view
3058 *
3059 * Slot is called by UpdateDelayer after some delay
3060 * @param feedId Feed identifier to update
3061 * @param changed Flag indicating that feed is updated indeed
3062 *---------------------------------------------------------------------------*/
slotUpdateFeed(int feedId,bool changed,int newCount,bool finish)3063 void MainWindow::slotUpdateFeed(int feedId, bool changed, int newCount, bool finish)
3064 {
3065 if (finish) {
3066 emit signalShowNotification();
3067 progressBar_->hide();
3068 progressBar_->setMaximum(0);
3069 progressBar_->setValue(0);
3070 isStartImportFeed_ = false;
3071 }
3072
3073 if (!changed) {
3074 emit signalNextUpdate(finish);
3075 return;
3076 }
3077
3078 // Action after new news has arrived: tray, sound
3079 if (!isActiveWindow() && (newCount > 0) &&
3080 (behaviorIconTray_ == CHANGE_ICON_TRAY)) {
3081 traySystem->setIcon(QIcon(":/images/quiterss128_NewNews"));
3082 }
3083 emit signalRefreshInfoTray();
3084 if (newCount > 0)
3085 emit signalPlaySoundNewNews();
3086
3087 // Manage notifications
3088 bool showNotify = true;
3089
3090 if (showNotifyInactiveApp_)
3091 {
3092 showNotify = !isActiveWindow();
3093 }
3094
3095 if (!showNotify)
3096 {
3097 clearNotification();
3098 }
3099
3100 if (newCount > 0)
3101 {
3102 bool bAddRecentNews = !onlySelectedFeeds_ || idFeedsNotifyList_.contains(feedId);
3103 bool bAddNewNews = bAddRecentNews && showNotify;
3104
3105 if (bAddNewNews)
3106 {
3107 int newFeedIdIndex = newNews.idFeedList_.indexOf(feedId);
3108
3109 if (-1 < newFeedIdIndex)
3110 {
3111 newNews.cntNewsList_[newFeedIdIndex] = newCount;
3112 }
3113 else
3114 {
3115 newNews.idFeedList_.append(feedId);
3116 newNews.cntNewsList_.append(newCount);
3117 }
3118 }
3119
3120 if (bAddRecentNews)
3121 {
3122 int recentFeedIdIndex = recentNews.idFeedList_.indexOf(feedId);
3123
3124 if (-1 < recentFeedIdIndex)
3125 {
3126 recentNews.cntNewsList_[recentFeedIdIndex] += newCount;
3127 }
3128 else
3129 {
3130 recentNews.idFeedList_.append(feedId);
3131 recentNews.cntNewsList_.append(newCount);
3132 }
3133 }
3134 }
3135
3136 recountCategoryCounts();
3137
3138 emit signalNextUpdate(finish);
3139 }
3140
3141 /** @brief Process updating news list
3142 *---------------------------------------------------------------------------*/
slotUpdateNews(int refresh)3143 void MainWindow::slotUpdateNews(int refresh)
3144 {
3145 int newsId = newsModel_->index(
3146 newsView_->currentIndex().row(), newsModel_->fieldIndex("id")).data(Qt::EditRole).toInt();
3147
3148 newsModel_->select();
3149
3150 if (newsModel_->rowCount() != 0) {
3151 while (newsModel_->canFetchMore())
3152 newsModel_->fetchMore();
3153 }
3154
3155 currentNewsTab->loadNewspaper(refresh);
3156
3157 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("id"));
3158 QModelIndexList indexList = newsModel_->match(index, Qt::EditRole, newsId);
3159 if (indexList.count()) {
3160 int newsRow = indexList.first().row();
3161 newsView_->setCurrentIndex(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
3162 } else {
3163 currentNewsTab->currentNewsIdOld = newsId;
3164 currentNewsTab->hideWebContent();
3165 }
3166 }
3167
3168 /** @brief Process click in feed tree
3169 *---------------------------------------------------------------------------*/
slotFeedClicked(QModelIndex index)3170 void MainWindow::slotFeedClicked(QModelIndex index)
3171 {
3172 if (feedsView_->selectionModel()->selectedRows(0).count() > 1) return;
3173
3174 int feedIdCur = feedsModel_->idByIndex(feedsProxyModel_->mapToSource(index));
3175
3176 if (stackedWidget_->count() && currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
3177 currentNewsTab->newsHeader_->saveStateColumns(currentNewsTab);
3178 }
3179
3180 // Search open tab containing this feed
3181 int indexTab = -1;
3182 for (int i = 0; i < stackedWidget_->count(); i++) {
3183 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
3184 if (widget->feedId_ == feedIdCur) {
3185 indexTab = i;
3186 break;
3187 }
3188 }
3189
3190 if (indexTab == -1) {
3191 if (tabBar_->currentIndex() != TAB_WIDGET_PERMANENT) {
3192 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_, FeedReadSwitchingTab, currentNewsTab);
3193
3194 updateCurrentTab_ = false;
3195 tabBar_->setCurrentIndex(TAB_WIDGET_PERMANENT);
3196 updateCurrentTab_ = true;
3197 QModelIndex currentIndex = feedsProxyModel_->mapFromSource(feedIdCur);
3198 feedsView_->setCurrentIndex(currentIndex);
3199
3200 currentNewsTab = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
3201 newsModel_ = currentNewsTab->newsModel_;
3202 newsView_ = currentNewsTab->newsView_;
3203 } else {
3204 if (stackedWidget_->count() && currentNewsTab->type_ != NewsTabWidget::TabTypeFeed) {
3205 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_, FeedReadSwitchingFeed, currentNewsTab);
3206 } else {
3207 // Mark previous feed Read while switching to another feed
3208 setFeedRead(NewsTabWidget::TabTypeFeed, feedIdOld_, FeedReadSwitchingFeed, 0, feedIdCur);
3209 }
3210
3211 categoriesTree_->setCurrentIndex(QModelIndex());
3212 }
3213
3214 slotFeedSelected(feedsModel_->indexById(feedIdCur));
3215 feedsView_->repaint();
3216 } else if (indexTab != -1) {
3217 tabBar_->setCurrentIndex(indexTab);
3218 }
3219 feedIdOld_ = feedIdCur;
3220 }
3221
3222 /** @brief Process feed choosing
3223 *---------------------------------------------------------------------------*/
slotFeedSelected(QModelIndex index,bool createTab)3224 void MainWindow::slotFeedSelected(QModelIndex index, bool createTab)
3225 {
3226 int feedId = feedsModel_->idByIndex(index);
3227 int feedParId = feedsModel_->paridByIndex(index);
3228
3229 // Open or create feed tab
3230 if (!stackedWidget_->count() || createTab) {
3231 NewsTabWidget *widget = new NewsTabWidget(this, NewsTabWidget::TabTypeFeed, feedId, feedParId);
3232 int indexTab = addTab(widget);
3233
3234 createNewsTab(indexTab);
3235
3236 if (indexTab == 0)
3237 currentNewsTab->closeButton_->setVisible(false);
3238 if (!index.isValid())
3239 currentNewsTab->setVisible(false);
3240
3241 emit signalSetCurrentTab(indexTab);
3242 } else {
3243 currentNewsTab->type_ = NewsTabWidget::TabTypeFeed;
3244 currentNewsTab->feedId_ = feedId;
3245 currentNewsTab->feedParId_ = feedParId;
3246 currentNewsTab->setSettings(true, false);
3247 currentNewsTab->setVisible(index.isValid());
3248 }
3249 statusUnread_->setVisible(index.isValid());
3250 statusAll_->setVisible(index.isValid());
3251
3252 // Set icon for tab has opened
3253 bool isFeed = (index.isValid() && feedsModel_->isFolder(index)) ? false : true;
3254
3255 QPixmap iconTab;
3256 QByteArray byteArray = feedsModel_->dataField(index, "image").toByteArray();
3257 if (!isFeed) {
3258 iconTab.load(":/images/folder");
3259 } else {
3260 if (byteArray.isNull() || defaultIconFeeds_) {
3261 iconTab.load(":/images/feed");
3262 } else if (isFeed) {
3263 iconTab.loadFromData(QByteArray::fromBase64(byteArray));
3264 }
3265 }
3266 currentNewsTab->newsIconTitle_->setPixmap(iconTab);
3267
3268 // Set title for tab has opened
3269 currentNewsTab->setTextTab(feedsModel_->dataField(index, "text").toString());
3270
3271 feedProperties_->setEnabled(index.isValid());
3272
3273 setNewsFilter(newsFilterGroup_->checkedAction(), false);
3274
3275 // Search feed news that displayed before
3276 int newsRow = -1;
3277 if (openingFeedAction_ == 0) {
3278 QModelIndex feedIndex = feedsModel_->indexById(feedId);
3279 int newsIdCur = feedsModel_->dataField(feedIndex, "currentNews").toInt();
3280 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("id"));
3281 QModelIndexList indexList = newsModel_->match(index, Qt::EditRole, newsIdCur);
3282
3283 if (!indexList.isEmpty()) newsRow = indexList.first().row();
3284 } else if (openingFeedAction_ == 1) {
3285 newsRow = 0;
3286 } else if ((openingFeedAction_ == 3) || (openingFeedAction_ == 4)) {
3287 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("read"));
3288 QModelIndexList indexList;
3289 if ((newsView_->header()->sortIndicatorOrder() == Qt::DescendingOrder) &&
3290 (openingFeedAction_ != 4))
3291 indexList = newsModel_->match(index, Qt::EditRole, 0, -1);
3292 else
3293 indexList = newsModel_->match(index, Qt::EditRole, 0);
3294
3295 if (!indexList.isEmpty()) newsRow = indexList.last().row();
3296 }
3297
3298 // Focus feed news that displayed before
3299 newsView_->setCurrentIndex(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
3300 if (newsRow == -1) newsView_->verticalScrollBar()->setValue(newsRow);
3301
3302 if ((openingFeedAction_ != 2) && openNewsWebViewOn_) {
3303 currentNewsTab->slotNewsViewSelected(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
3304 } else {
3305 currentNewsTab->slotNewsViewSelected(newsModel_->index(-1, newsModel_->fieldIndex("title")));
3306 int newsId = newsModel_->index(newsRow, newsModel_->fieldIndex("id")).data(Qt::EditRole).toInt();
3307 QString qStr = QString("UPDATE feeds SET currentNews='%1' WHERE id=='%2'").arg(newsId).arg(feedId);
3308 mainApp->sqlQueryExec(qStr);
3309 QModelIndex feedIndex = feedsModel_->indexById(feedId);
3310 feedsModel_->setData(feedsModel_->indexSibling(feedIndex, "currentNews"), newsId);
3311 }
3312 }
3313
3314 // ----------------------------------------------------------------------------
showOptionDlg(int index)3315 void MainWindow::showOptionDlg(int index)
3316 {
3317 static int pageIndex = 0;
3318 Settings settings;
3319
3320 if (index != -1) pageIndex = index;
3321
3322 if (optionsDialog_) {
3323 optionsDialog_->activateWindow();
3324 return;
3325 }
3326
3327 optionsDialog_ = new OptionsDialog(this);
3328
3329 settings.beginGroup("Settings");
3330 bool updateFeedsStartUp = settings.value("autoUpdatefeedsStartUp", false).toBool();
3331 settings.endGroup();
3332
3333 optionsDialog_->showSplashScreen_->setChecked(showSplashScreen_);
3334 optionsDialog_->reopenFeedStartup_->setChecked(reopenFeedStartup_);
3335 optionsDialog_->openNewTabNextToActive_->setChecked(openNewTabNextToActive_);
3336 optionsDialog_->hideFeedsOpenTab_->setChecked(hideFeedsOpenTab_);
3337 optionsDialog_->showToggleFeedsTree_->setChecked(showToggleFeedsTree_);
3338 optionsDialog_->defaultIconFeeds_->setChecked(defaultIconFeeds_);
3339 optionsDialog_->autocollapseFolder_->setChecked(feedsView_->autocollapseFolder_);
3340 bool showCloseButtonTab = settings.value("Settings/showCloseButtonTab", true).toBool();
3341 optionsDialog_->showCloseButtonTab_->setChecked(showCloseButtonTab);
3342
3343 bool updateCheckEnabled = settings.value("Settings/updateCheckEnabled", true).toBool();
3344 optionsDialog_->updateCheckEnabled_->setChecked(updateCheckEnabled);
3345 bool statisticsEnabled = settings.value("Settings/statisticsEnabled2", true).toBool();
3346 optionsDialog_->statisticsEnabled_->setChecked(statisticsEnabled);
3347
3348 bool storeDBMemory_ = settings.value("Settings/storeDBMemory", true).toBool();
3349 optionsDialog_->storeDBMemory_->setChecked(storeDBMemory_);
3350 int saveDBMemFileInterval = settings.value("Settings/saveDBMemFileInterval", 30).toInt();
3351 optionsDialog_->saveDBMemFileInterval_->setValue(saveDBMemFileInterval);
3352
3353 optionsDialog_->showTrayIconBox_->setChecked(showTrayIcon_);
3354 optionsDialog_->startingTray_->setChecked(startingTray_);
3355 optionsDialog_->minimizingTray_->setChecked(minimizingTray_);
3356 optionsDialog_->closingTray_->setChecked(closingTray_);
3357 optionsDialog_->setBehaviorIconTray(behaviorIconTray_);
3358 optionsDialog_->singleClickTray_->setChecked(singleClickTray_);
3359 optionsDialog_->clearStatusNew_->setChecked(clearStatusNew_);
3360 optionsDialog_->emptyWorking_->setChecked(emptyWorking_);
3361
3362 optionsDialog_->setProxy(mainApp->networkProxy());
3363
3364 int timeoutRequest = settings.value("Settings/timeoutRequest", 15).toInt();
3365 int numberRequests = settings.value("Settings/numberRequest", 10).toInt();
3366 int numberRepeats = settings.value("Settings/numberRepeats", 2).toInt();
3367 optionsDialog_->timeoutRequest_->setValue(timeoutRequest);
3368 optionsDialog_->numberRequests_->setValue(numberRequests);
3369 optionsDialog_->numberRepeats_->setValue(numberRepeats);
3370
3371 optionsDialog_->embeddedBrowserOn_->setChecked(externalBrowserOn_ <= 0);
3372 optionsDialog_->externalBrowserOn_->setChecked(externalBrowserOn_ >= 1);
3373 optionsDialog_->defaultExternalBrowserOn_->setChecked((externalBrowserOn_ == 0) ||
3374 (externalBrowserOn_ == 1));
3375 optionsDialog_->otherExternalBrowserOn_->setChecked((externalBrowserOn_ == -1) ||
3376 (externalBrowserOn_ == 2));
3377 optionsDialog_->otherExternalBrowserEdit_->setText(externalBrowser_);
3378 optionsDialog_->autoLoadImages_->setChecked(autoLoadImages_);
3379 optionsDialog_->javaScriptEnable_->setChecked(javaScriptEnable_);
3380 optionsDialog_->pluginsEnable_->setChecked(pluginsEnable_);
3381 optionsDialog_->defaultZoomPages_->setValue(defaultZoomPages_);
3382 optionsDialog_->openLinkInBackground_->setChecked(openLinkInBackground_);
3383 optionsDialog_->openLinkInBackgroundEmbedded_->setChecked(openLinkInBackgroundEmbedded_);
3384 optionsDialog_->maxPagesInCache_->setValue(maxPagesInCache_);
3385
3386 settings.beginGroup("Settings");
3387
3388 QString userStyleBrowser = settings.value("userStyleBrowser", QString()).toString();
3389 optionsDialog_->userStyleBrowserEdit_->setText(userStyleBrowser);
3390
3391 bool useDiskCache = settings.value("useDiskCache", true).toBool();
3392 optionsDialog_->diskCacheOn_->setChecked(useDiskCache);
3393 QString diskCacheDir = settings.value("dirDiskCache", mainApp->cacheDefaultDir()).toString();
3394 if (diskCacheDir.isEmpty()) diskCacheDir = mainApp->cacheDefaultDir();
3395 optionsDialog_->dirDiskCacheEdit_->setText(diskCacheDir);
3396 int maxDiskCache = settings.value("maxDiskCache", 50).toInt();
3397 optionsDialog_->maxDiskCache_->setValue(maxDiskCache);
3398
3399 settings.endGroup();
3400
3401 UseCookies useCookies = mainApp->cookieJar()->useCookies();
3402 optionsDialog_->saveCookies_->setChecked(useCookies == SaveCookies);
3403 optionsDialog_->deleteCookiesOnClose_->setChecked(useCookies == DeleteCookiesOnClose);
3404 optionsDialog_->blockCookies_->setChecked(useCookies == BlockCookies);
3405
3406 optionsDialog_->downloadLocationEdit_->setText(downloadLocation_);
3407 optionsDialog_->askDownloadLocation_->setChecked(askDownloadLocation_);
3408
3409 optionsDialog_->updateFeedsStartUp_->setChecked(updateFeedsStartUp);
3410 optionsDialog_->updateFeedsEnable_->setChecked(updateFeedsEnable_);
3411 optionsDialog_->updateIntervalType_->setCurrentIndex(updateFeedsIntervalType_+1);
3412 optionsDialog_->updateFeedsInterval_->setValue(updateFeedsInterval_);
3413
3414 optionsDialog_->setOpeningFeed(openingFeedAction_);
3415 optionsDialog_->openNewsWebViewOn_->setChecked(openNewsWebViewOn_);
3416
3417 optionsDialog_->markNewsReadOn_->setChecked(markNewsReadOn_);
3418 optionsDialog_->markCurNewsRead_->setChecked(markCurNewsRead_);
3419 optionsDialog_->markNewsReadTime_->setValue(markNewsReadTime_);
3420 optionsDialog_->markPrevNewsRead_->setChecked(markPrevNewsRead_);
3421 optionsDialog_->markReadSwitchingFeed_->setChecked(markReadSwitchingFeed_);
3422 optionsDialog_->markReadClosingTab_->setChecked(markReadClosingTab_);
3423 optionsDialog_->markReadMinimize_->setChecked(markReadMinimize_);
3424
3425 optionsDialog_->showDescriptionNews_->setChecked(showDescriptionNews_);
3426
3427 for (int i = 0; i < optionsDialog_->formatDate_->count(); i++) {
3428 if (optionsDialog_->formatDate_->itemData(i).toString() == formatDate_) {
3429 optionsDialog_->formatDate_->setCurrentIndex(i);
3430 break;
3431 }
3432 }
3433 for (int i = 0; i < optionsDialog_->formatTime_->count(); i++) {
3434 if (optionsDialog_->formatTime_->itemData(i).toString() == formatTime_) {
3435 optionsDialog_->formatTime_->setCurrentIndex(i);
3436 break;
3437 }
3438 }
3439
3440 optionsDialog_->alternatingRowColorsNews_->setChecked(alternatingRowColorsNews_);
3441 optionsDialog_->changeBehaviorActionNUN_->setChecked(changeBehaviorActionNUN_);
3442 optionsDialog_->simplifiedDateTime_->setChecked(simplifiedDateTime_);
3443 optionsDialog_->notDeleteStarred_->setChecked(notDeleteStarred_);
3444 optionsDialog_->notDeleteLabeled_->setChecked(notDeleteLabeled_);
3445 optionsDialog_->markIdenticalNewsRead_->setChecked(markIdenticalNewsRead_);
3446 optionsDialog_->avoidedOldNewsDateOn_->setChecked(avoidOldNews_);
3447
3448 if (!avoidedOldNewsDate_.isNull() && avoidedOldNewsDate_.isValid()) {
3449 optionsDialog_->avoidedOldNewsDate_->setSelectedDate(avoidedOldNewsDate_);
3450 } else {
3451 optionsDialog_->avoidedOldNewsDate_->setSelectedDate(QDate::currentDate());
3452 }
3453
3454 for (int i = 0; i < optionsDialog_->mainNewsFilter_->count(); i++) {
3455 if (optionsDialog_->mainNewsFilter_->itemData(i).toString() == mainNewsFilter_) {
3456 optionsDialog_->mainNewsFilter_->setCurrentIndex(i);
3457 break;
3458 }
3459 }
3460
3461 QString styleSheetNews = settings.value("Settings/styleSheetNews",
3462 mainApp->styleSheetNewsDefaultFile()).toString();
3463 optionsDialog_->styleSheetNewsEdit_->setText(styleSheetNews);
3464
3465 optionsDialog_->cleanupOnShutdownBox_->setChecked(cleanupOnShutdown_);
3466 optionsDialog_->dayCleanUpOn_->setChecked(dayCleanUpOn_);
3467 optionsDialog_->maxDayCleanUp_->setValue(maxDayCleanUp_);
3468 optionsDialog_->newsCleanUpOn_->setChecked(newsCleanUpOn_);
3469 optionsDialog_->maxNewsCleanUp_->setValue(maxNewsCleanUp_);
3470 optionsDialog_->readCleanUp_->setChecked(readCleanUp_);
3471 optionsDialog_->neverUnreadCleanUp_->setChecked(neverUnreadCleanUp_);
3472 optionsDialog_->neverStarCleanUp_->setChecked(neverStarCleanUp_);
3473 optionsDialog_->neverLabelCleanUp_->setChecked(neverLabelCleanUp_);
3474 optionsDialog_->cleanUpDeleted_->setChecked(cleanUpDeleted_);
3475 optionsDialog_->optimizeDB_->setChecked(optimizeDB_);
3476
3477 optionsDialog_->soundNotifyBox_->setChecked(soundNewNews_);
3478 optionsDialog_->editSoundNotifer_->setText(soundNotifyPath_);
3479 optionsDialog_->showNotifyOn_->setChecked(showNotifyOn_);
3480 optionsDialog_->screenNotify_->setCurrentIndex(screenNotify_+1);
3481 optionsDialog_->positionNotify_->setCurrentIndex(positionNotify_);
3482 optionsDialog_->transparencyNotify_->setValue(transparencyNotify_);
3483 optionsDialog_->countShowNewsNotify_->setValue(countShowNewsNotify_);
3484 optionsDialog_->widthTitleNewsNotify_->setValue(widthTitleNewsNotify_);
3485 optionsDialog_->timeShowNewsNotify_->setValue(timeShowNewsNotify_);
3486 optionsDialog_->fullscreenModeNotify_->setChecked(fullscreenModeNotify_);
3487 optionsDialog_->showNotifyInactiveApp_->setChecked(showNotifyInactiveApp_);
3488 optionsDialog_->onlySelectedFeeds_->setChecked(onlySelectedFeeds_);
3489 optionsDialog_->showTitlesFeedsNotify_->setChecked(showTitlesFeedsNotify_);
3490 optionsDialog_->showIconFeedNotify_->setChecked(showIconFeedNotify_);
3491 optionsDialog_->showButtonMarkAllNotify_->setChecked(showButtonMarkAllNotify_);
3492 optionsDialog_->showButtonMarkReadNotify_->setChecked(showButtonMarkReadNotify_);
3493 optionsDialog_->showButtonExBrowserNotify_->setChecked(showButtonExBrowserNotify_);
3494 optionsDialog_->showButtonDeleteNotify_->setChecked(showButtonDeleteNotify_);
3495 optionsDialog_->closeNotify_->setChecked(closeNotify_);
3496
3497 optionsDialog_->setLanguage(mainApp->language());
3498
3499 QString strFont = QString("%1, %2").
3500 arg(feedsView_->font().family()).
3501 arg(feedsView_->font().pointSize());
3502 optionsDialog_->fontsTree_->topLevelItem(0)->setText(2, strFont);
3503 strFont = QString("%1, %2").arg(newsListFontFamily_).arg(newsListFontSize_);
3504 optionsDialog_->fontsTree_->topLevelItem(1)->setText(2, strFont);
3505 strFont = QString("%1, %2").arg(newsTitleFontFamily_).arg(newsTitleFontSize_);
3506 optionsDialog_->fontsTree_->topLevelItem(2)->setText(2, strFont);
3507 strFont = QString("%1, %2").arg(newsTextFontFamily_).arg(newsTextFontSize_);
3508 optionsDialog_->fontsTree_->topLevelItem(3)->setText(2, strFont);
3509 strFont = QString("%1, %2").arg(notificationFontFamily_).arg(notificationFontSize_);
3510 optionsDialog_->fontsTree_->topLevelItem(4)->setText(2, strFont);
3511
3512 settings.beginGroup("Settings");
3513 QString browserStandardFont = settings.value(
3514 "browserStandardFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::StandardFont)).toString();
3515 QString browserFixedFont = settings.value(
3516 "browserFixedFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::FixedFont)).toString();
3517 QString browserSerifFont = settings.value(
3518 "browserSerifFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::SerifFont)).toString();
3519 QString browserSansSerifFont = settings.value(
3520 "browserSansSerifFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::SansSerifFont)).toString();
3521 QString browserCursiveFont = settings.value(
3522 "browserCursiveFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::CursiveFont)).toString();
3523 QString browserFantasyFont = settings.value(
3524 "browserFantasyFont", QWebSettings::globalSettings()->fontFamily(QWebSettings::FantasyFont)).toString();
3525 int browserDefaultFontSize = settings.value(
3526 "browserDefaultFontSize", QWebSettings::globalSettings()->fontSize(QWebSettings::DefaultFontSize)).toInt();
3527 int browserFixedFontSize = settings.value(
3528 "browserFixedFontSize", QWebSettings::globalSettings()->fontSize(QWebSettings::DefaultFixedFontSize)).toInt();
3529 int browserMinFontSize = settings.value(
3530 "browserMinFontSize", QWebSettings::globalSettings()->fontSize(QWebSettings::MinimumFontSize)).toInt();
3531 int browserMinLogFontSize = settings.value(
3532 "browserMinLogFontSize", QWebSettings::globalSettings()->fontSize(QWebSettings::MinimumLogicalFontSize)).toInt();
3533 settings.endGroup();
3534
3535 optionsDialog_->browserStandardFont_->setCurrentFont(QFont(browserStandardFont));
3536 optionsDialog_->browserFixedFont_->setCurrentFont(QFont(browserFixedFont));
3537 optionsDialog_->browserSerifFont_->setCurrentFont(QFont(browserSerifFont));
3538 optionsDialog_->browserSansSerifFont_->setCurrentFont(QFont(browserSansSerifFont));
3539 optionsDialog_->browserCursiveFont_->setCurrentFont(QFont(browserCursiveFont));
3540 optionsDialog_->browserFantasyFont_->setCurrentFont(QFont(browserFantasyFont));
3541 optionsDialog_->browserDefaultFontSize_->setValue(browserDefaultFontSize);
3542 optionsDialog_->browserFixedFontSize_->setValue(browserFixedFontSize);
3543 optionsDialog_->browserMinFontSize_->setValue(browserMinFontSize);
3544 optionsDialog_->browserMinLogFontSize_->setValue(browserMinLogFontSize);
3545
3546 QPixmap pixmapColor(14, 14);
3547 pixmapColor.fill(feedsModel_->textColor_);
3548 optionsDialog_->colorsTree_->topLevelItem(0)->setIcon(0, pixmapColor);
3549 optionsDialog_->colorsTree_->topLevelItem(0)->setText(1, feedsModel_->textColor_);
3550 if (feedsModel_->backgroundColor_.isEmpty())
3551 pixmapColor.fill(QColor(0, 0, 0, 0));
3552 else
3553 pixmapColor.fill(feedsModel_->backgroundColor_);
3554 optionsDialog_->colorsTree_->topLevelItem(1)->setIcon(0, pixmapColor);
3555 optionsDialog_->colorsTree_->topLevelItem(1)->setText(1, feedsModel_->backgroundColor_);
3556 pixmapColor.fill(newsListTextColor_);
3557 optionsDialog_->colorsTree_->topLevelItem(2)->setIcon(0, pixmapColor);
3558 optionsDialog_->colorsTree_->topLevelItem(2)->setText(1, newsListTextColor_);
3559
3560 if (newsListBackgroundColor_.isEmpty())
3561 pixmapColor.fill(QColor(0, 0, 0, 0));
3562 else
3563 pixmapColor.fill(newsListBackgroundColor_);
3564 optionsDialog_->colorsTree_->topLevelItem(3)->setIcon(0, pixmapColor);
3565 optionsDialog_->colorsTree_->topLevelItem(3)->setText(1, newsListBackgroundColor_);
3566 pixmapColor.fill(focusedNewsTextColor_);
3567 optionsDialog_->colorsTree_->topLevelItem(4)->setIcon(0, pixmapColor);
3568 optionsDialog_->colorsTree_->topLevelItem(4)->setText(1, focusedNewsTextColor_);
3569 if (focusedNewsBGColor_.isEmpty())
3570 pixmapColor.fill(QColor(0, 0, 0, 0));
3571 else
3572 pixmapColor.fill(focusedNewsBGColor_);
3573 optionsDialog_->colorsTree_->topLevelItem(5)->setIcon(0, pixmapColor);
3574 optionsDialog_->colorsTree_->topLevelItem(5)->setText(1, focusedNewsBGColor_);
3575 pixmapColor.fill(linkColor_);
3576 optionsDialog_->colorsTree_->topLevelItem(6)->setIcon(0, pixmapColor);
3577 optionsDialog_->colorsTree_->topLevelItem(6)->setText(1, linkColor_);
3578 pixmapColor.fill(titleColor_);
3579 optionsDialog_->colorsTree_->topLevelItem(7)->setIcon(0, pixmapColor);
3580 optionsDialog_->colorsTree_->topLevelItem(7)->setText(1, titleColor_);
3581 pixmapColor.fill(dateColor_);
3582 optionsDialog_->colorsTree_->topLevelItem(8)->setIcon(0, pixmapColor);
3583 optionsDialog_->colorsTree_->topLevelItem(8)->setText(1, dateColor_);
3584 pixmapColor.fill(authorColor_);
3585 optionsDialog_->colorsTree_->topLevelItem(9)->setIcon(0, pixmapColor);
3586 optionsDialog_->colorsTree_->topLevelItem(9)->setText(1, authorColor_);
3587 pixmapColor.fill(newsTextColor_);
3588 optionsDialog_->colorsTree_->topLevelItem(10)->setIcon(0, pixmapColor);
3589 optionsDialog_->colorsTree_->topLevelItem(10)->setText(1, newsTextColor_);
3590 pixmapColor.fill(newsTitleBackgroundColor_);
3591 optionsDialog_->colorsTree_->topLevelItem(11)->setIcon(0, pixmapColor);
3592 optionsDialog_->colorsTree_->topLevelItem(11)->setText(1, newsTitleBackgroundColor_);
3593 pixmapColor.fill(newsBackgroundColor_);
3594 optionsDialog_->colorsTree_->topLevelItem(12)->setIcon(0, pixmapColor);
3595 optionsDialog_->colorsTree_->topLevelItem(12)->setText(1, newsBackgroundColor_);
3596 pixmapColor.fill(feedsModel_->feedWithNewNewsColor_);
3597 optionsDialog_->colorsTree_->topLevelItem(13)->setIcon(0, pixmapColor);
3598 optionsDialog_->colorsTree_->topLevelItem(13)->setText(1, feedsModel_->feedWithNewNewsColor_);
3599 pixmapColor.fill(feedsModel_->countNewsUnreadColor_);
3600 optionsDialog_->colorsTree_->topLevelItem(14)->setIcon(0, pixmapColor);
3601 optionsDialog_->colorsTree_->topLevelItem(14)->setText(1, feedsModel_->countNewsUnreadColor_);
3602
3603 pixmapColor.fill(newNewsTextColor_);
3604 optionsDialog_->colorsTree_->topLevelItem(15)->setIcon(0, pixmapColor);
3605 optionsDialog_->colorsTree_->topLevelItem(15)->setText(1, newNewsTextColor_);
3606 pixmapColor.fill(unreadNewsTextColor_);
3607 optionsDialog_->colorsTree_->topLevelItem(16)->setIcon(0, pixmapColor);
3608 optionsDialog_->colorsTree_->topLevelItem(16)->setText(1, unreadNewsTextColor_);
3609
3610 pixmapColor.fill(feedsModel_->focusedFeedTextColor_);
3611 optionsDialog_->colorsTree_->topLevelItem(17)->setIcon(0, pixmapColor);
3612 optionsDialog_->colorsTree_->topLevelItem(17)->setText(1, feedsModel_->focusedFeedTextColor_);
3613 if (feedsModel_->focusedFeedBGColor_.isEmpty())
3614 pixmapColor.fill(QColor(0, 0, 0, 0));
3615 else
3616 pixmapColor.fill(feedsModel_->focusedFeedBGColor_);
3617 optionsDialog_->colorsTree_->topLevelItem(18)->setIcon(0, pixmapColor);
3618 optionsDialog_->colorsTree_->topLevelItem(18)->setText(1, feedsModel_->focusedFeedBGColor_);
3619 pixmapColor.fill(feedsModel_->feedDisabledUpdateColor_);
3620 optionsDialog_->colorsTree_->topLevelItem(19)->setIcon(0, pixmapColor);
3621 optionsDialog_->colorsTree_->topLevelItem(19)->setText(1, feedsModel_->feedDisabledUpdateColor_);
3622
3623 pixmapColor.fill(alternatingRowColors_);
3624 optionsDialog_->colorsTree_->topLevelItem(20)->setIcon(0, pixmapColor);
3625 optionsDialog_->colorsTree_->topLevelItem(20)->setText(1, alternatingRowColors_);
3626
3627 pixmapColor.fill(notifierTextColor_);
3628 optionsDialog_->colorsTree_->topLevelItem(21)->setIcon(0, pixmapColor);
3629 optionsDialog_->colorsTree_->topLevelItem(21)->setText(1, notifierTextColor_);
3630 pixmapColor.fill(notifierBackgroundColor_);
3631 optionsDialog_->colorsTree_->topLevelItem(22)->setIcon(0, pixmapColor);
3632 optionsDialog_->colorsTree_->topLevelItem(22)->setText(1, notifierBackgroundColor_);
3633
3634 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
3635 backWebPageAct_->setText(widget->webView_->page()->action(QWebPage::Back)->text());
3636 backWebPageAct_->setToolTip(widget->webView_->page()->action(QWebPage::Back)->toolTip() + " " + tr("(Browser)"));
3637 backWebPageAct_->setIcon(widget->webView_->page()->action(QWebPage::Back)->icon());
3638 backWebPageAct_->setShortcut(widget->webView_->page()->action(QWebPage::Back)->shortcut());
3639
3640 forwardWebPageAct_->setText(widget->webView_->page()->action(QWebPage::Forward)->text());
3641 forwardWebPageAct_->setToolTip(widget->webView_->page()->action(QWebPage::Forward)->toolTip() + " " + tr("(Browser)"));
3642 forwardWebPageAct_->setIcon(widget->webView_->page()->action(QWebPage::Forward)->icon());
3643 forwardWebPageAct_->setShortcut(widget->webView_->page()->action(QWebPage::Forward)->shortcut());
3644
3645 reloadWebPageAct_->setText(widget->webView_->page()->action(QWebPage::Reload)->text());
3646 reloadWebPageAct_->setToolTip(widget->webView_->page()->action(QWebPage::Reload)->toolTip() + " " + tr("(Browser)"));
3647 reloadWebPageAct_->setIcon(widget->webView_->page()->action(QWebPage::Reload)->icon());
3648 reloadWebPageAct_->setShortcut(widget->webView_->page()->action(QWebPage::Reload)->shortcut());
3649
3650 optionsDialog_->loadActionShortcut(listActions_, &listDefaultShortcut_);
3651
3652 // Display setting dialog
3653
3654 optionsDialog_->setCurrentItem(pageIndex);
3655 int result = optionsDialog_->exec();
3656 pageIndex = optionsDialog_->currentIndex();
3657
3658 if (result == QDialog::Rejected) {
3659 delete optionsDialog_;
3660 optionsDialog_ = NULL;
3661 return;
3662 }
3663
3664 // Apply accepted settings
3665
3666 foreach (QAction *action, listActions_) {
3667 QString objectName = action->objectName();
3668 if (objectName.contains("labelAction_")) {
3669 listActions_.removeOne(action);
3670 delete action;
3671 }
3672 }
3673 optionsDialog_->saveActionShortcut(listActions_, newsLabelGroup_);
3674 listActions_.append(newsLabelGroup_->actions());
3675 newsLabelMenu_->addActions(newsLabelGroup_->actions());
3676 this->addActions(newsLabelGroup_->actions());
3677 if (newsLabelGroup_->actions().count()) {
3678 newsLabelAction_->setIcon(newsLabelGroup_->actions().at(0)->icon());
3679 newsLabelAction_->setToolTip(newsLabelGroup_->actions().at(0)->text());
3680 newsLabelAction_->setData(newsLabelGroup_->actions().at(0)->data());
3681 }
3682
3683 if (optionsDialog_->idLabels_.count()) {
3684 QTreeWidgetItem *labelTreeItem = categoriesTree_->topLevelItem(CategoriesTreeWidget::LabelsItem);
3685 while (labelTreeItem->childCount()) {
3686 labelTreeItem->removeChild(labelTreeItem->child(0));
3687 }
3688
3689 bool closeTab = true;
3690 int indexTab = -1;
3691 int tabLabelId = -1;
3692 for (int i = 0; i < stackedWidget_->count(); i++) {
3693 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
3694 if (widget->type_ == NewsTabWidget::TabTypeLabel) {
3695 indexTab = i;
3696 tabLabelId = widget->labelId_;
3697 break;
3698 }
3699 }
3700
3701 QSqlQuery q;
3702 q.exec("SELECT id, name, image, currentNews, num, color_bg, color_text FROM labels ORDER BY num");
3703 while (q.next()) {
3704 int idLabel = q.value(0).toInt();
3705 QString nameLabel = q.value(1).toString();
3706 QByteArray byteArray = q.value(2).toByteArray();
3707 QString currentNews = q.value(3).toString();
3708 QPixmap imageLabel;
3709 if (!byteArray.isNull())
3710 imageLabel.loadFromData(byteArray);
3711 QStringList dataItem;
3712 dataItem << nameLabel << QString::number(NewsTabWidget::TabTypeLabel)
3713 << QString::number(idLabel) << currentNews;
3714 QTreeWidgetItem *childItem = new QTreeWidgetItem(dataItem);
3715 childItem->setIcon(0, QIcon(imageLabel));
3716 childItem->setData(0, CategoriesTreeWidget::ImageRole, q.value(2));
3717 childItem->setData(0, CategoriesTreeWidget::NumRole, q.value(4));
3718 childItem->setData(0, CategoriesTreeWidget::colorBgRole, q.value(5));
3719 childItem->setData(0, CategoriesTreeWidget::colorTextRole, q.value(6));
3720 labelTreeItem->addChild(childItem);
3721
3722 if (idLabel == tabLabelId) {
3723 closeTab = false;
3724 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(indexTab);
3725 // Set icon and title for tab has opened
3726 widget->newsIconTitle_->setPixmap(imageLabel);
3727 widget->setTextTab(nameLabel);
3728 }
3729 }
3730
3731 if (closeTab && (indexTab > 0) && (tabLabelId > 0)) {
3732 slotCloseTab(indexTab);
3733 }
3734 if ((tabBar_->currentIndex() == indexTab) && (indexTab > 0) && (tabLabelId == 0)) {
3735 slotUpdateNews(NewsTabWidget::RefreshWithPos);
3736 }
3737 }
3738
3739 showSplashScreen_ = optionsDialog_->showSplashScreen_->isChecked();
3740 reopenFeedStartup_ = optionsDialog_->reopenFeedStartup_->isChecked();
3741 openNewTabNextToActive_ = optionsDialog_->openNewTabNextToActive_->isChecked();
3742 hideFeedsOpenTab_ = optionsDialog_->hideFeedsOpenTab_->isChecked();
3743 showToggleFeedsTree_ = optionsDialog_->showToggleFeedsTree_->isChecked();
3744 defaultIconFeeds_ = optionsDialog_->defaultIconFeeds_->isChecked();
3745 feedsModel_->defaultIconFeeds_ = defaultIconFeeds_;
3746 feedsView_->autocollapseFolder_ = optionsDialog_->autocollapseFolder_->isChecked();
3747
3748 showCloseButtonTab = optionsDialog_->showCloseButtonTab_->isChecked();
3749 settings.setValue("Settings/showCloseButtonTab", showCloseButtonTab);
3750
3751 pushButtonNull_->setVisible(showToggleFeedsTree_);
3752
3753 updateCheckEnabled = optionsDialog_->updateCheckEnabled_->isChecked();
3754 settings.setValue("Settings/updateCheckEnabled", updateCheckEnabled);
3755 statisticsEnabled = optionsDialog_->statisticsEnabled_->isChecked();
3756 settings.setValue("Settings/statisticsEnabled2", statisticsEnabled);
3757
3758 storeDBMemory_ = optionsDialog_->storeDBMemory_->isChecked();
3759 settings.setValue("Settings/storeDBMemory", storeDBMemory_);
3760 if (saveDBMemFileInterval != optionsDialog_->saveDBMemFileInterval_->value()) {
3761 saveDBMemFileInterval = optionsDialog_->saveDBMemFileInterval_->value();
3762 settings.setValue("Settings/saveDBMemFileInterval", saveDBMemFileInterval);
3763 mainApp->updateFeeds()->startSaveTimer();
3764 }
3765
3766 showTrayIcon_ = optionsDialog_->showTrayIconBox_->isChecked();
3767 startingTray_ = optionsDialog_->startingTray_->isChecked();
3768 minimizingTray_ = optionsDialog_->minimizingTray_->isChecked();
3769 closingTray_ = optionsDialog_->closingTray_->isChecked();
3770 behaviorIconTray_ = optionsDialog_->behaviorIconTray();
3771 if (behaviorIconTray_ > CHANGE_ICON_TRAY) {
3772 emit signalRefreshInfoTray();
3773 } else {
3774 traySystem->setIcon(QIcon(":/images/quiterss128"));
3775 }
3776 singleClickTray_ = optionsDialog_->singleClickTray_->isChecked();
3777 clearStatusNew_ = optionsDialog_->clearStatusNew_->isChecked();
3778 emptyWorking_ = optionsDialog_->emptyWorking_->isChecked();
3779 if (showTrayIcon_) traySystem->show();
3780 else traySystem->hide();
3781
3782 mainApp->proxySaveSettings(optionsDialog_->proxy());
3783
3784 timeoutRequest = optionsDialog_->timeoutRequest_->value();
3785 numberRequests = optionsDialog_->numberRequests_->value();
3786 numberRepeats = optionsDialog_->numberRepeats_->value();
3787 settings.setValue("Settings/timeoutRequest", timeoutRequest);
3788 settings.setValue("Settings/numberRequest", numberRequests);
3789 settings.setValue("Settings/numberRepeats", numberRepeats);
3790
3791 if (optionsDialog_->embeddedBrowserOn_->isChecked()) {
3792 if (optionsDialog_->defaultExternalBrowserOn_->isChecked())
3793 externalBrowserOn_ = 0;
3794 else
3795 externalBrowserOn_ = -1;
3796 } else {
3797 if (optionsDialog_->defaultExternalBrowserOn_->isChecked())
3798 externalBrowserOn_ = 1;
3799 else
3800 externalBrowserOn_ = 2;
3801 }
3802
3803 externalBrowser_ = optionsDialog_->otherExternalBrowserEdit_->text();
3804 autoLoadImages_ = optionsDialog_->autoLoadImages_->isChecked();
3805 javaScriptEnable_ = optionsDialog_->javaScriptEnable_->isChecked();
3806 pluginsEnable_ = optionsDialog_->pluginsEnable_->isChecked();
3807 openLinkInBackground_ = optionsDialog_->openLinkInBackground_->isChecked();
3808 openLinkInBackgroundEmbedded_ = optionsDialog_->openLinkInBackgroundEmbedded_->isChecked();
3809 maxPagesInCache_ = optionsDialog_->maxPagesInCache_->value();
3810 defaultZoomPages_ = optionsDialog_->defaultZoomPages_->value();
3811
3812 QWebSettings::globalSettings()->setAttribute(
3813 QWebSettings::JavascriptEnabled, javaScriptEnable_);
3814 QWebSettings::globalSettings()->setAttribute(
3815 QWebSettings::PluginsEnabled, pluginsEnable_);
3816 QWebSettings::globalSettings()->setMaximumPagesInCache(maxPagesInCache_);
3817
3818 settings.beginGroup("Settings");
3819
3820 userStyleBrowser = optionsDialog_->userStyleBrowserEdit_->text();
3821 settings.setValue("userStyleBrowser", userStyleBrowser);
3822
3823 useDiskCache = optionsDialog_->diskCacheOn_->isChecked();
3824 settings.setValue("useDiskCache", useDiskCache);
3825 maxDiskCache = optionsDialog_->maxDiskCache_->value();
3826 settings.setValue("maxDiskCache", maxDiskCache);
3827
3828 if (diskCacheDir != optionsDialog_->dirDiskCacheEdit_->text()) {
3829 Common::removePath(diskCacheDir);
3830 }
3831 diskCacheDir = optionsDialog_->dirDiskCacheEdit_->text();
3832 if (diskCacheDir.isEmpty()) diskCacheDir = mainApp->cacheDefaultDir();
3833 settings.setValue("dirDiskCache", diskCacheDir);
3834
3835 settings.endGroup();
3836
3837 mainApp->setDiskCache();
3838
3839 useCookies = SaveCookies;
3840 if (optionsDialog_->deleteCookiesOnClose_->isChecked())
3841 useCookies = DeleteCookiesOnClose;
3842 else if (optionsDialog_->blockCookies_->isChecked())
3843 useCookies = BlockCookies;
3844 mainApp->cookieJar()->setUseCookies(useCookies);
3845
3846 downloadLocation_ = optionsDialog_->downloadLocationEdit_->text();
3847 askDownloadLocation_ = optionsDialog_->askDownloadLocation_->isChecked();
3848
3849 updateFeedsStartUp = optionsDialog_->updateFeedsStartUp_->isChecked();
3850 updateFeedsEnable_ = optionsDialog_->updateFeedsEnable_->isChecked();
3851 updateFeedsInterval_ = optionsDialog_->updateFeedsInterval_->value();
3852 updateFeedsIntervalType_ = optionsDialog_->updateIntervalType_->currentIndex()-1;
3853
3854 int updateInterval = updateFeedsInterval_;
3855 if (updateFeedsIntervalType_ == 0)
3856 updateInterval = updateInterval*60;
3857 else if (updateFeedsIntervalType_ == 1)
3858 updateInterval = updateInterval*60*60;
3859 updateIntervalSec_ = updateInterval;
3860
3861 openingFeedAction_ = optionsDialog_->getOpeningFeed();
3862 openNewsWebViewOn_ = optionsDialog_->openNewsWebViewOn_->isChecked();
3863
3864 markNewsReadOn_ = optionsDialog_->markNewsReadOn_->isChecked();
3865 markCurNewsRead_ = optionsDialog_->markCurNewsRead_->isChecked();
3866 markNewsReadTime_ = optionsDialog_->markNewsReadTime_->value();
3867 markPrevNewsRead_ = optionsDialog_->markPrevNewsRead_->isChecked();
3868 markReadSwitchingFeed_ = optionsDialog_->markReadSwitchingFeed_->isChecked();
3869 markReadClosingTab_ = optionsDialog_->markReadClosingTab_->isChecked();
3870 markReadMinimize_ = optionsDialog_->markReadMinimize_->isChecked();
3871
3872 showDescriptionNews_ = optionsDialog_->showDescriptionNews_->isChecked();
3873
3874 formatDate_ = optionsDialog_->formatDate_->itemData(
3875 optionsDialog_->formatDate_->currentIndex()).toString();
3876 feedsModel_->formatDate_ = formatDate_;
3877 formatTime_ = optionsDialog_->formatTime_->itemData(
3878 optionsDialog_->formatTime_->currentIndex()).toString();
3879 feedsModel_->formatTime_ = formatTime_;
3880
3881 alternatingRowColorsNews_ = optionsDialog_->alternatingRowColorsNews_->isChecked();
3882 changeBehaviorActionNUN_ = optionsDialog_->changeBehaviorActionNUN_->isChecked();
3883 simplifiedDateTime_ = optionsDialog_->simplifiedDateTime_->isChecked();
3884 notDeleteStarred_ = optionsDialog_->notDeleteStarred_->isChecked();
3885 notDeleteLabeled_ = optionsDialog_->notDeleteLabeled_->isChecked();
3886 markIdenticalNewsRead_ = optionsDialog_->markIdenticalNewsRead_->isChecked();
3887 avoidOldNews_ = optionsDialog_->avoidedOldNewsDateOn_->isChecked();
3888
3889 if (!optionsDialog_->avoidedOldNewsDate_->selectedDate().isNull() && optionsDialog_->avoidedOldNewsDate_->selectedDate().isValid()) {
3890 avoidedOldNewsDate_ = optionsDialog_->avoidedOldNewsDate_->selectedDate();
3891 } else {
3892 avoidedOldNewsDate_ = QDate::currentDate();
3893 }
3894
3895 mainNewsFilter_ = optionsDialog_->mainNewsFilter_->itemData(
3896 optionsDialog_->mainNewsFilter_->currentIndex()).toString();
3897
3898 styleSheetNews = optionsDialog_->styleSheetNewsEdit_->text();
3899 if (styleSheetNews.isEmpty()) styleSheetNews = mainApp->styleSheetNewsDefaultFile();
3900 settings.setValue("Settings/styleSheetNews", styleSheetNews);
3901
3902 cleanupOnShutdown_ = optionsDialog_->cleanupOnShutdownBox_->isChecked();
3903 dayCleanUpOn_ = optionsDialog_->dayCleanUpOn_->isChecked();
3904 maxDayCleanUp_ = optionsDialog_->maxDayCleanUp_->value();
3905 newsCleanUpOn_ = optionsDialog_->newsCleanUpOn_->isChecked();
3906 maxNewsCleanUp_ = optionsDialog_->maxNewsCleanUp_->value();
3907 readCleanUp_ = optionsDialog_->readCleanUp_->isChecked();
3908 neverUnreadCleanUp_ = optionsDialog_->neverUnreadCleanUp_->isChecked();
3909 neverStarCleanUp_ = optionsDialog_->neverStarCleanUp_->isChecked();
3910 neverLabelCleanUp_ = optionsDialog_->neverLabelCleanUp_->isChecked();
3911 cleanUpDeleted_ = optionsDialog_->cleanUpDeleted_->isChecked();
3912 optimizeDB_ = optionsDialog_->optimizeDB_->isChecked();
3913
3914 soundNewNews_ = optionsDialog_->soundNotifyBox_->isChecked();
3915 soundNotifyPath_ = optionsDialog_->editSoundNotifer_->text();
3916 showNotifyOn_ = optionsDialog_->showNotifyOn_->isChecked();
3917 screenNotify_ = optionsDialog_->screenNotify_->currentIndex()-1;
3918 positionNotify_ = optionsDialog_->positionNotify_->currentIndex();
3919 transparencyNotify_ = optionsDialog_->transparencyNotify_->value();
3920 countShowNewsNotify_ = optionsDialog_->countShowNewsNotify_->value();
3921 widthTitleNewsNotify_ = optionsDialog_->widthTitleNewsNotify_->value();
3922 timeShowNewsNotify_ = optionsDialog_->timeShowNewsNotify_->value();
3923 fullscreenModeNotify_ = optionsDialog_->fullscreenModeNotify_->isChecked();
3924 showNotifyInactiveApp_ = optionsDialog_->showNotifyInactiveApp_->isChecked();
3925 onlySelectedFeeds_ = optionsDialog_->onlySelectedFeeds_->isChecked();
3926 showTitlesFeedsNotify_ = optionsDialog_->showTitlesFeedsNotify_->isChecked();
3927 showIconFeedNotify_ = optionsDialog_->showIconFeedNotify_->isChecked();
3928 showButtonMarkAllNotify_ = optionsDialog_->showButtonMarkAllNotify_->isChecked();
3929 showButtonMarkReadNotify_ = optionsDialog_->showButtonMarkReadNotify_->isChecked();
3930 showButtonExBrowserNotify_ = optionsDialog_->showButtonExBrowserNotify_->isChecked();
3931 showButtonDeleteNotify_ = optionsDialog_->showButtonDeleteNotify_->isChecked();
3932 closeNotify_ = optionsDialog_->closeNotify_->isChecked();
3933
3934 mainApp->setLanguage(optionsDialog_->language());
3935 mainApp->setTranslateApplication();
3936
3937 QFont font = feedsView_->font();
3938 font.setFamily(
3939 optionsDialog_->fontsTree_->topLevelItem(0)->text(2).section(", ", 0, 0));
3940 font.setPointSize(
3941 optionsDialog_->fontsTree_->topLevelItem(0)->text(2).section(", ", 1).toInt());
3942 feedsView_->setFont(font);
3943 feedsModel_->font_ = font;
3944
3945 newsListFontFamily_ = optionsDialog_->fontsTree_->topLevelItem(1)->text(2).section(", ", 0, 0);
3946 newsListFontSize_ = optionsDialog_->fontsTree_->topLevelItem(1)->text(2).section(", ", 1).toInt();
3947 newsTitleFontFamily_ = optionsDialog_->fontsTree_->topLevelItem(2)->text(2).section(", ", 0, 0);
3948 newsTitleFontSize_ = optionsDialog_->fontsTree_->topLevelItem(2)->text(2).section(", ", 1).toInt();
3949 newsTextFontFamily_ = optionsDialog_->fontsTree_->topLevelItem(3)->text(2).section(", ", 0, 0);
3950 newsTextFontSize_ = optionsDialog_->fontsTree_->topLevelItem(3)->text(2).section(", ", 1).toInt();
3951 notificationFontFamily_ = optionsDialog_->fontsTree_->topLevelItem(4)->text(2).section(", ", 0, 0);
3952 notificationFontSize_ = optionsDialog_->fontsTree_->topLevelItem(4)->text(2).section(", ", 1).toInt();
3953
3954 browserStandardFont = optionsDialog_->browserStandardFont_->currentFont().family();
3955 browserFixedFont = optionsDialog_->browserFixedFont_->currentFont().family();
3956 browserSerifFont = optionsDialog_->browserSerifFont_->currentFont().family();
3957 browserSansSerifFont = optionsDialog_->browserSansSerifFont_->currentFont().family();
3958 browserCursiveFont = optionsDialog_->browserCursiveFont_->currentFont().family();
3959 browserFantasyFont = optionsDialog_->browserFantasyFont_->currentFont().family();
3960 browserDefaultFontSize = optionsDialog_->browserDefaultFontSize_->value();
3961 browserFixedFontSize = optionsDialog_->browserFixedFontSize_->value();
3962 browserMinFontSize = optionsDialog_->browserMinFontSize_->value();
3963 browserMinLogFontSize = optionsDialog_->browserMinLogFontSize_->value();
3964
3965 QWebSettings::globalSettings()->setFontFamily(
3966 QWebSettings::StandardFont, browserStandardFont);
3967 QWebSettings::globalSettings()->setFontFamily(
3968 QWebSettings::FixedFont, browserFixedFont);
3969 QWebSettings::globalSettings()->setFontFamily(
3970 QWebSettings::SerifFont, browserSerifFont);
3971 QWebSettings::globalSettings()->setFontFamily(
3972 QWebSettings::SansSerifFont, browserSansSerifFont);
3973 QWebSettings::globalSettings()->setFontFamily(
3974 QWebSettings::CursiveFont, browserCursiveFont);
3975 QWebSettings::globalSettings()->setFontFamily(
3976 QWebSettings::FantasyFont, browserFantasyFont);
3977 QWebSettings::globalSettings()->setFontSize(
3978 QWebSettings::DefaultFontSize, browserDefaultFontSize);
3979 QWebSettings::globalSettings()->setFontSize(
3980 QWebSettings::DefaultFixedFontSize, browserFixedFontSize);
3981 QWebSettings::globalSettings()->setFontSize(
3982 QWebSettings::MinimumFontSize, browserMinFontSize);
3983 QWebSettings::globalSettings()->setFontSize(
3984 QWebSettings::MinimumLogicalFontSize, browserMinLogFontSize);
3985
3986 settings.beginGroup("Settings");
3987 settings.setValue("browserStandardFont", browserStandardFont);
3988 settings.setValue("browserFixedFont", browserFixedFont);
3989 settings.setValue("browserSerifFont", browserSerifFont);
3990 settings.setValue("browserSansSerifFont", browserSansSerifFont);
3991 settings.setValue("browserCursiveFont", browserCursiveFont);
3992 settings.setValue("browserFantasyFont", browserFantasyFont);
3993 settings.setValue("browserDefaultFontSize", browserDefaultFontSize);
3994 settings.setValue("browserFixedFontSize", browserFixedFontSize);
3995 settings.setValue("browserMinFontSize", browserMinFontSize);
3996 settings.setValue("browserMinLogFontSize", browserMinLogFontSize);
3997 settings.endGroup();
3998
3999 feedsModel_->textColor_ = optionsDialog_->colorsTree_->topLevelItem(0)->text(1);
4000 feedsModel_->backgroundColor_ = optionsDialog_->colorsTree_->topLevelItem(1)->text(1);
4001 feedsView_->setStyleSheet(QString("#feedsView_ {background: %1;}").arg(feedsModel_->backgroundColor_));
4002 newsListTextColor_ = optionsDialog_->colorsTree_->topLevelItem(2)->text(1);
4003 newsListBackgroundColor_ = optionsDialog_->colorsTree_->topLevelItem(3)->text(1);
4004 focusedNewsTextColor_ = optionsDialog_->colorsTree_->topLevelItem(4)->text(1);
4005 focusedNewsBGColor_ = optionsDialog_->colorsTree_->topLevelItem(5)->text(1);
4006 linkColor_ = optionsDialog_->colorsTree_->topLevelItem(6)->text(1);
4007 titleColor_ = optionsDialog_->colorsTree_->topLevelItem(7)->text(1);
4008 dateColor_ = optionsDialog_->colorsTree_->topLevelItem(8)->text(1);
4009 authorColor_ = optionsDialog_->colorsTree_->topLevelItem(9)->text(1);
4010 newsTextColor_ = optionsDialog_->colorsTree_->topLevelItem(10)->text(1);
4011 newsTitleBackgroundColor_ = optionsDialog_->colorsTree_->topLevelItem(11)->text(1);
4012 newsBackgroundColor_ = optionsDialog_->colorsTree_->topLevelItem(12)->text(1);
4013 feedsModel_->feedWithNewNewsColor_ = optionsDialog_->colorsTree_->topLevelItem(13)->text(1);
4014 feedsModel_->countNewsUnreadColor_ = optionsDialog_->colorsTree_->topLevelItem(14)->text(1);
4015 newNewsTextColor_ = optionsDialog_->colorsTree_->topLevelItem(15)->text(1);
4016 unreadNewsTextColor_ = optionsDialog_->colorsTree_->topLevelItem(16)->text(1);
4017 feedsModel_->focusedFeedTextColor_ = optionsDialog_->colorsTree_->topLevelItem(17)->text(1);
4018 feedsModel_->focusedFeedBGColor_ = optionsDialog_->colorsTree_->topLevelItem(18)->text(1);
4019 feedsModel_->feedDisabledUpdateColor_ = optionsDialog_->colorsTree_->topLevelItem(19)->text(1);
4020 alternatingRowColors_ = optionsDialog_->colorsTree_->topLevelItem(20)->text(1);
4021 notifierTextColor_ = optionsDialog_->colorsTree_->topLevelItem(21)->text(1);
4022 notifierBackgroundColor_ = optionsDialog_->colorsTree_->topLevelItem(22)->text(1);
4023
4024 delete optionsDialog_;
4025 optionsDialog_ = NULL;
4026
4027 settings.beginGroup("Settings");
4028 settings.setValue("autoUpdatefeedsStartUp", updateFeedsStartUp);
4029 settings.endGroup();
4030
4031 saveSettings();
4032 saveActionShortcuts();
4033 mainApp->reloadUserStyleBrowser();
4034
4035 if (currentNewsTab != NULL) {
4036 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb)
4037 currentNewsTab->newsHeader_->saveStateColumns(currentNewsTab);
4038 currentNewsTab->setSettings(false);
4039 }
4040 }
4041
showSettingPageLabels()4042 void MainWindow::showSettingPageLabels()
4043 {
4044 showOptionDlg(5);
4045 }
4046
4047 // ----------------------------------------------------------------------------
createTrayMenu()4048 void MainWindow::createTrayMenu()
4049 {
4050 trayMenu_ = new QMenu(this);
4051 showWindowAct_ = new QAction(this);
4052 connect(showWindowAct_, SIGNAL(triggered()), this, SLOT(showWindows()));
4053 QFont font_ = showWindowAct_->font();
4054 font_.setBold(true);
4055 showWindowAct_->setFont(font_);
4056 trayMenu_->addAction(showWindowAct_);
4057 trayMenu_->addAction(addFeedTrayAct_);
4058 trayMenu_->addAction(updateAllFeedsAct_);
4059 trayMenu_->addAction(markAllFeedsRead_);
4060 trayMenu_->addSeparator();
4061
4062 trayMenu_->addAction(optionsAct_);
4063 trayMenu_->addSeparator();
4064
4065 trayMenu_->addAction(exitAct_);
4066 traySystem->setContextMenu(trayMenu_);
4067 }
4068
4069 /** @brief Free memory working set in Windows
4070 *---------------------------------------------------------------------------*/
myEmptyWorkingSet()4071 void MainWindow::myEmptyWorkingSet()
4072 {
4073 #if defined(Q_OS_WIN)
4074 if (isHidden())
4075 EmptyWorkingSet(GetCurrentProcess());
4076 #endif
4077 }
4078 // ----------------------------------------------------------------------------
initUpdateFeeds()4079 void MainWindow::initUpdateFeeds()
4080 {
4081 QSqlQuery q;
4082
4083 if (onlySelectedFeeds_) {
4084 q.exec("SELECT feedId FROM feeds_ex WHERE value=1 AND name='showNotification'");
4085 while (q.next()) {
4086 idFeedsNotifyList_.append(q.value(0).toInt());
4087 }
4088 }
4089
4090 q.exec("SELECT id, updateInterval, updateIntervalType FROM feeds WHERE xmlUrl != '' AND updateIntervalEnable == 1");
4091 while (q.next()) {
4092 int updateInterval = q.value(1).toInt();
4093 int updateIntervalType = q.value(2).toInt();
4094 if (updateIntervalType == 0)
4095 updateInterval = updateInterval*60;
4096 else if (updateIntervalType == 1)
4097 updateInterval = updateInterval*60*60;
4098
4099 updateFeedsIntervalSec_.insert(q.value(0).toInt(), updateInterval);
4100 updateFeedsTimeCount_.insert(q.value(0).toInt(), 0);
4101 }
4102
4103 int updateInterval = updateFeedsInterval_;
4104 if (updateFeedsIntervalType_ == 0)
4105 updateInterval = updateInterval*60;
4106 else if (updateFeedsIntervalType_ == 1)
4107 updateInterval = updateInterval*60*60;
4108 updateIntervalSec_ = updateInterval;
4109
4110 updateFeedsTimer_ = new QTimer(this);
4111 connect(updateFeedsTimer_, SIGNAL(timeout()),
4112 this, SLOT(slotGetFeedsTimer()));
4113 updateFeedsTimer_->start(1000);
4114 }
4115 // ----------------------------------------------------------------------------
slotGetFeedsTimer()4116 void MainWindow::slotGetFeedsTimer()
4117 {
4118 if (updateFeedsEnable_) {
4119 updateTimeCount_++;
4120 if (updateTimeCount_ >= updateIntervalSec_) {
4121 updateTimeCount_ = 0;
4122
4123 emit signalGetAllFeedsTimer();
4124 }
4125 } else {
4126 updateTimeCount_ = 0;
4127 }
4128
4129 QMapIterator<int, int> iterator(updateFeedsTimeCount_);
4130 while (iterator.hasNext()) {
4131 iterator.next();
4132 int feedId = iterator.key();
4133 updateFeedsTimeCount_[feedId]++;
4134 if (updateFeedsTimeCount_[feedId] >= updateFeedsIntervalSec_[feedId]) {
4135 updateFeedsTimeCount_[feedId] = 0;
4136
4137 emit signalGetFeedTimer(feedId);
4138 }
4139 }
4140 }
4141 /** @brief Process update feed action
4142 *---------------------------------------------------------------------------*/
slotGetFeed()4143 void MainWindow::slotGetFeed()
4144 {
4145 QModelIndexList indexList = feedsView_->selectionModel()->selectedRows(0);
4146 if (indexList.count() <= 1) {
4147 indexList.clear();
4148 indexList.append(feedsProxyModel_->mapFromSource(feedsView_->selectIndex()));
4149 }
4150 QList<int> idList;
4151 foreach (QModelIndex indexProxy, indexList) {
4152 QModelIndex index = feedsProxyModel_->mapToSource(indexProxy);
4153 if (feedsModel_->isFolder(index)) {
4154 QList<int> list = UpdateObject::getIdFeedsInList(db_, feedsModel_->dataField(index, "id").toInt());
4155 foreach (int idFeed, list) {
4156 if (!idList.contains(idFeed)) {
4157 idList.append(idFeed);
4158 index = feedsModel_->indexById(idFeed);
4159 if (!feedsModel_->dataField(index, "disableUpdate").toBool()) {
4160 emit signalGetFeed(feedsModel_->dataField(index, "id").toInt(),
4161 feedsModel_->dataField(index, "xmlUrl").toString(),
4162 feedsModel_->dataField(index, "lastBuildDate").toDateTime(),
4163 feedsModel_->dataField(index, "authentication").toInt());
4164 }
4165 }
4166 }
4167
4168 } else {
4169 int idFeed = feedsModel_->dataField(index, "id").toInt();
4170 if (!idList.contains(idFeed)) {
4171 idList.append(idFeed);
4172 emit signalGetFeed(feedsModel_->dataField(index, "id").toInt(),
4173 feedsModel_->dataField(index, "xmlUrl").toString(),
4174 feedsModel_->dataField(index, "lastBuildDate").toDateTime(),
4175 feedsModel_->dataField(index, "authentication").toInt());
4176 }
4177 }
4178 }
4179 }
4180
4181 /** @brief Process update all feeds action
4182 *---------------------------------------------------------------------------*/
slotGetAllFeeds()4183 void MainWindow::slotGetAllFeeds()
4184 {
4185 emit signalGetAllFeeds();
4186 }
4187
slotStopUpdate()4188 void MainWindow::slotStopUpdate()
4189 {
4190 progressBar_->hide();
4191 emit signalStopUpdate();
4192 }
4193
4194 /** @brief Show update progress bar after feed update has started
4195 *---------------------------------------------------------------------------*/
showProgressBar(int maximum)4196 void MainWindow::showProgressBar(int maximum)
4197 {
4198 if (maximum == 0) {
4199 isStartImportFeed_ = false;
4200 return;
4201 }
4202
4203 Settings settings;
4204 settings.setValue("Flags/updatingFeeds", true);
4205
4206 playSoundNewNews_ = false;
4207
4208 progressBar_->setMaximum(maximum);
4209 progressBar_->show();
4210 }
slotSetValue(int value)4211 void MainWindow::slotSetValue(int value)
4212 {
4213 if (progressBar_->isVisible())
4214 progressBar_->setValue(progressBar_->maximum() - value);
4215 }
showMessageStatusBar(QString message,int timeout)4216 void MainWindow::showMessageStatusBar(QString message, int timeout)
4217 {
4218 statusBar()->showMessage(message, timeout);
4219 }
slotCountsStatusBar(int unreadCount,int allCount)4220 void MainWindow::slotCountsStatusBar(int unreadCount, int allCount)
4221 {
4222 statusUnread_->setText(QString(" " + tr("Unread: %1") + " ").arg(unreadCount));
4223 statusAll_->setText(QString(" " + tr("All: %1") + " ").arg(allCount));
4224 }
4225 // ----------------------------------------------------------------------------
slotVisibledFeedsWidget()4226 void MainWindow::slotVisibledFeedsWidget()
4227 {
4228 if (tabBar_->currentIndex() == TAB_WIDGET_PERMANENT) {
4229 showFeedsTabPermanent_ = feedsWidgetVisibleAct_->isChecked();
4230 }
4231
4232 feedsWidget_->setVisible(feedsWidgetVisibleAct_->isChecked());
4233 updateIconToolBarNull(feedsWidgetVisibleAct_->isChecked());
4234 }
4235 // ----------------------------------------------------------------------------
updateIconToolBarNull(bool feedsWidgetVisible)4236 void MainWindow::updateIconToolBarNull(bool feedsWidgetVisible)
4237 {
4238 if (feedsWidgetVisible)
4239 pushButtonNull_->setIcon(QIcon(":/images/images/triangleR.png"));
4240 else
4241 pushButtonNull_->setIcon(QIcon(":/images/images/triangleL.png"));
4242 }
4243
4244 /** @brief Update status of current feed or feed of current tab
4245 *---------------------------------------------------------------------------*/
slotUpdateStatus(int feedId,bool changed)4246 void MainWindow::slotUpdateStatus(int feedId, bool changed)
4247 {
4248 emit signalUpdateStatus(feedId, changed);
4249 }
4250
4251 /** @brief Set filter for viewing feeds and categories
4252 * @param pAct Filter mode
4253 * @param clicked Flag to call function after user click or from programm code
4254 * true - user click
4255 * false - programm call
4256 *----------------------------------------------------------------------------*/
setFeedsFilter(bool clicked)4257 void MainWindow::setFeedsFilter(bool clicked)
4258 {
4259 QList<int> idList;
4260 static bool setFilter = false;
4261
4262 if (setFilter) return;
4263 setFilter = true;
4264
4265 QAction* filterAct = feedsFilterGroup_->checkedAction();
4266
4267 if (filterAct->objectName() == "filterFeedsNew_") {
4268 QModelIndex index = feedsProxyModel_->mapToSource(feedsView_->currentIndex());
4269 int newCount = feedsModel_->dataField(index, "newCount").toInt();
4270 if (!(clicked && !newCount)) {
4271 while (index.isValid()) {
4272 idList << feedsModel_->idByIndex(index);
4273 index = index.parent();
4274 }
4275 }
4276 } else if (filterAct->objectName() == "filterFeedsUnread_") {
4277 QModelIndex index = feedsProxyModel_->mapToSource(feedsView_->currentIndex());
4278 int unRead = feedsModel_->dataField(index, "unread").toInt();
4279 if (!(clicked && !unRead)) {
4280 while (index.isValid()) {
4281 idList << feedsModel_->idByIndex(index);
4282 index = index.parent();
4283 }
4284 }
4285 } else if (filterAct->objectName() == "filterFeedsStarred_") {
4286 QSqlQuery q;
4287 q.exec(QString("SELECT id, parentId FROM feeds WHERE label LIKE '%starred%'"));
4288 while (q.next()) {
4289 idList.append(q.value(0).toInt());
4290 int parentId = q.value(1).toInt();
4291 if (!idList.contains(parentId)) {
4292 while (parentId) {
4293 if (!idList.contains(parentId))
4294 idList.append(parentId);
4295 else break;
4296 QSqlQuery q1;
4297 q1.exec(QString("SELECT parentId FROM feeds WHERE id==%1").arg(parentId));
4298 if (q1.next()) parentId = q1.value(0).toInt();
4299 }
4300 }
4301 }
4302 } else if (filterAct->objectName() == "filterFeedsError_") {
4303 QSqlQuery q;
4304 q.exec(QString("SELECT id, parentId FROM feeds WHERE status!=0 AND status!=''"));
4305 while (q.next()) {
4306 idList.append(q.value(0).toInt());
4307 int parentId = q.value(1).toInt();
4308 if (!idList.contains(parentId)) {
4309 while (parentId) {
4310 if (!idList.contains(parentId))
4311 idList.append(parentId);
4312 else break;
4313 QSqlQuery q1;
4314 q1.exec(QString("SELECT parentId FROM feeds WHERE id==%1").arg(parentId));
4315 if (q1.next()) parentId = q1.value(0).toInt();
4316 }
4317 }
4318 }
4319 }
4320
4321 if ((filterAct->objectName() == "filterFeedsNew_") ||
4322 (filterAct->objectName() == "filterFeedsUnread_")) {
4323 for (int i = 0; i < stackedWidget_->count(); i++) {
4324 if ((i == 0) && clicked && (stackedWidget_->currentIndex() == 0)) continue;
4325 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
4326 if (!idList.contains(widget->feedId_)) {
4327 idList.append(widget->feedId_);
4328 QModelIndex index = feedsModel_->indexById(widget->feedId_).parent();
4329 while (index.isValid()) {
4330 int id = feedsModel_->idByIndex(index);
4331 if (!idList.contains(id))
4332 idList.append(id);
4333 index = index.parent();
4334 }
4335 }
4336 }
4337 }
4338
4339 // Set filter
4340 feedsProxyModel_->setFilter(filterAct->objectName(), idList,
4341 findFeeds_->findGroup_->checkedAction()->objectName(),
4342 findFeeds_->text());
4343
4344 feedsView_->restoreExpanded();
4345
4346 feedsView_->clearSelection();
4347 feedsView_->setCurrentIndex(feedsView_->currentIndex());
4348
4349 if (clicked && (tabBar_->currentIndex() == TAB_WIDGET_PERMANENT)) {
4350 slotFeedClicked(feedsView_->currentIndex());
4351 }
4352
4353 if (filterAct->objectName() == "filterFeedsAll_") feedsFilter_->setIcon(QIcon(":/images/filterOff"));
4354 else feedsFilter_->setIcon(QIcon(":/images/filterOn"));
4355
4356 // Store filter to enable it as "last used filter"
4357 if (filterAct->objectName() != "filterFeedsAll_")
4358 feedsFilterAction_ = filterAct;
4359
4360 setFilter = false;
4361 }
4362
4363 /** @brief Set filter for news list
4364 *---------------------------------------------------------------------------*/
setNewsFilter(QAction * pAct,bool clicked)4365 void MainWindow::setNewsFilter(QAction* pAct, bool clicked)
4366 {
4367 if (currentNewsTab == NULL) return;
4368 if (currentNewsTab->type_ >= NewsTabWidget::TabTypeWeb) {
4369 filterNewsAll_->setChecked(true);
4370 return;
4371 }
4372
4373 QModelIndex index = newsView_->currentIndex();
4374 int feedId = currentNewsTab->feedId_;
4375 int newsId = newsModel_->index(
4376 index.row(), newsModel_->fieldIndex("id")).data(Qt::EditRole).toInt();
4377
4378 // Hide news has marrked "Read"
4379 // read=1 - show regardless of filter
4380 // read=2 - don't display at all
4381 if (clicked) {
4382 QString qStr = QString("UPDATE news SET read=2 WHERE feedId='%1' AND read=1").
4383 arg(feedId);
4384 mainApp->sqlQueryExec(qStr);
4385 }
4386
4387 // Create filter for category or for feed
4388 if (feedsModel_->isFolder(feedsModel_->indexById(feedId))) {
4389 newsFilterStr = QString("(%1) AND ").arg(getIdFeedsString(feedId));
4390 } else {
4391 newsFilterStr = QString("feedId=%1 AND ").arg(feedId);
4392 }
4393
4394 // ... add filter from "filter"
4395 if (pAct->objectName() == "filterNewsAll_") {
4396 newsFilterStr.append("deleted = 0");
4397 } else if (pAct->objectName() == "filterNewsNew_") {
4398 newsFilterStr.append(QString("new = 1 AND deleted = 0"));
4399 } else if (pAct->objectName() == "filterNewsUnread_") {
4400 newsFilterStr.append(QString("read < 2 AND deleted = 0"));
4401 } else if (pAct->objectName() == "filterNewsStar_") {
4402 newsFilterStr.append(QString("starred = 1 AND deleted = 0"));
4403 } else if (pAct->objectName() == "filterNewsNotStarred_") {
4404 newsFilterStr.append(QString("starred = 0 AND deleted = 0"));
4405 } else if (pAct->objectName() == "filterNewsUnreadStar_") {
4406 newsFilterStr.append(QString("(read < 2 OR starred = 1) AND deleted = 0"));
4407 } else if (pAct->objectName() == "filterNewsLastDay_") {
4408 newsFilterStr.append(QString("(published >= datetime('now', '-1 day')) AND deleted = 0"));
4409 } else if (pAct->objectName() == "filterNewsLastWeek_") {
4410 newsFilterStr.append(QString("(published >= datetime('now', '-7 day')) AND deleted = 0"));
4411 }
4412
4413 // ... add filter from "search"
4414 QString filterStr = newsFilterStr;
4415 QString objectName = currentNewsTab->findText_->findGroup_->checkedAction()->objectName();
4416 if (objectName != "findInBrowserAct") {
4417 QString findText = currentNewsTab->findText_->text();
4418 if (!findText.isEmpty()) {
4419 findText = findText.replace("'", "''").toUpper();
4420 if (objectName == "findTitleAct") {
4421 filterStr.append(
4422 QString(" AND UPPER(title) LIKE '%%1%'").arg(findText));
4423 } else if (objectName == "findAuthorAct") {
4424 filterStr.append(
4425 QString(" AND UPPER(author_name) LIKE '%%1%'").arg(findText));
4426 } else if (objectName == "findCategoryAct") {
4427 filterStr.append(
4428 QString(" AND UPPER(category) LIKE '%%1%'").arg(findText));
4429 } else if (objectName == "findContentAct") {
4430 filterStr.append(
4431 QString(" AND (UPPER(content) LIKE '%%1%' OR UPPER(description) LIKE '%%1%')").
4432 arg(findText));
4433 } else if (objectName == "findLinkAct") {
4434 filterStr.append(
4435 QString(" AND link_href LIKE '%%1%'").
4436 arg(findText));
4437 } else {
4438 filterStr.append(
4439 QString(" AND (UPPER(title) LIKE '%%1%' OR UPPER(author_name) LIKE '%%1%' "
4440 "OR UPPER(category) LIKE '%%1%' OR UPPER(content) LIKE '%%1%' "
4441 "OR UPPER(description) LIKE '%%1%')").
4442 arg(findText));
4443 }
4444 }
4445 }
4446
4447 newsModel_->setFilter(filterStr);
4448 while (newsModel_->canFetchMore())
4449 newsModel_->fetchMore();
4450
4451 if ((currentNewsTab->newsHeader_->sortIndicatorSection() == newsModel_->fieldIndex("read")) ||
4452 currentNewsTab->newsHeader_->sortIndicatorSection() == newsModel_->fieldIndex("starred")) {
4453 currentNewsTab->slotSort(currentNewsTab->newsHeader_->sortIndicatorSection(),
4454 currentNewsTab->newsHeader_->sortIndicatorOrder());
4455 }
4456
4457 currentNewsTab->loadNewspaper();
4458
4459 // Set icon right before user click
4460 if (pAct->objectName() == "filterNewsAll_") newsFilter_->setIcon(QIcon(":/images/filterOff"));
4461 else newsFilter_->setIcon(QIcon(":/images/filterOn"));
4462
4463 // Set focus on previous displayed feed, if user click has been
4464 if (clicked) {
4465 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("id"));
4466 QModelIndexList indexList = newsModel_->match(index, Qt::EditRole, newsId);
4467 if (indexList.count()) {
4468 int newsRow = indexList.first().row();
4469 newsView_->setCurrentIndex(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
4470 } else {
4471 currentNewsTab->currentNewsIdOld = newsId;
4472 currentNewsTab->hideWebContent();
4473 }
4474 }
4475
4476 // Store filter to enable it as "last used filter"
4477 if (pAct->objectName() != mainNewsFilter_)
4478 newsFilterAction_ = pAct;
4479 }
4480
4481 /** @brief Mark feed Read while clicking on unfocused one
4482 *---------------------------------------------------------------------------*/
setFeedRead(int type,int feedId,FeedReedType feedReadType,NewsTabWidget * widgetTab,int idException)4483 void MainWindow::setFeedRead(int type, int feedId, FeedReedType feedReadType,
4484 NewsTabWidget *widgetTab, int idException)
4485 {
4486 if ((type >= NewsTabWidget::TabTypeWeb) || (type == NewsTabWidget::TabTypeDel))
4487 return;
4488
4489 if ((type == NewsTabWidget::TabTypeFeed) && (feedReadType != FeedReadSwitchingTab)) {
4490 if (feedId <= -1) return;
4491
4492 QList<int> idNewsList;
4493 if (((feedReadType == FeedReadSwitchingFeed) && markReadSwitchingFeed_) ||
4494 ((feedReadType == FeedReadClosingTab) && markReadClosingTab_) ||
4495 ((feedReadType == FeedReadPlaceToTray) && markReadMinimize_)) {
4496 emit signalSetFeedRead(feedReadType, feedId, idException, idNewsList);
4497 } else {
4498 emit signalSetFeedRead(feedReadType, feedId, idException, idNewsList);
4499 }
4500 } else if (widgetTab) {
4501 int cnt = widgetTab->newsModel_->rowCount();
4502 if (cnt == 0) return;
4503
4504 QList<int> idNewsList;
4505 for (int i = cnt-1; i >= 0; --i) {
4506 int newsId = widgetTab->newsModel_->index(i, widgetTab->newsModel_->fieldIndex("id")).data().toInt();
4507 idNewsList.append(newsId);
4508 }
4509 for (int i = 0; i < stackedWidget_->count(); i++) {
4510 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
4511 if ((widget->type_ < NewsTabWidget::TabTypeWeb) &&
4512 !((feedReadType == FeedReadSwitchingFeed) && (i == TAB_WIDGET_PERMANENT))) {
4513 int row = widget->newsView_->currentIndex().row();
4514 int newsId = widget->newsModel_->index(row, widget->newsModel_->fieldIndex("id")).data().toInt();
4515 idNewsList.removeOne(newsId);
4516 }
4517 }
4518 emit signalSetFeedRead(FeedReadSwitchingTab, feedId, idException, idNewsList);
4519 }
4520 }
4521
4522 /** @brief Mark feed read
4523 *---------------------------------------------------------------------------*/
markFeedRead()4524 void MainWindow::markFeedRead()
4525 {
4526 bool openFeed = false;
4527 bool isFolder = false;
4528
4529 QModelIndexList indexList = feedsView_->selectionModel()->selectedRows(0);
4530 if (indexList.count() <= 1) {
4531 indexList.clear();
4532 indexList.append(feedsProxyModel_->mapFromSource(feedsView_->selectIndex()));
4533 }
4534 QList<int> idList;
4535 for (int i = indexList.count()-1; i >= 0; --i) {
4536 QModelIndex index = feedsProxyModel_->mapToSource(indexList[i]);
4537 if (feedsModel_->isFolder(index)) {
4538 idList.append(feedsModel_->dataField(index, "id").toInt());
4539 indexList.removeAt(i);
4540 }
4541 }
4542 for (int i = indexList.count()-1; i >= 0; --i) {
4543 QModelIndex index = feedsProxyModel_->mapToSource(indexList[i]);
4544 int parentId = feedsModel_->dataField(index, "parentId").toInt();
4545 if (!idList.contains(parentId)) {
4546 idList.append(feedsModel_->dataField(index, "id").toInt());
4547 }
4548 indexList.removeAt(i);
4549 }
4550 foreach (int id, idList) {
4551 bool openFeedT = false;
4552 QModelIndex index = feedsModel_->indexById(id);
4553 int parentId = feedsModel_->dataField(index, "parentId").toInt();
4554 if (currentNewsTab->feedId_ == id) {
4555 openFeedT = true;
4556 openFeed = true;
4557 }
4558 if (currentNewsTab->feedParId_ == id) {
4559 openFeed = true;
4560 }
4561 if (currentNewsTab->feedId_ == parentId) {
4562 openFeed = true;
4563 isFolder = true;
4564 }
4565 if (feedsModel_->isFolder(index)) {
4566 if (currentNewsTab->feedId_ == id) {
4567 isFolder = true;
4568 }
4569 QList<int> list = UpdateObject::getIdFeedsInList(db_, id);
4570 foreach (int id1, list) {
4571 QModelIndex index1 = feedsModel_->indexById(id1);
4572 QModelIndex indexUnread = feedsModel_->indexSibling(index1, "unread");
4573 QModelIndex indexNew = feedsModel_->indexSibling(index1, "newCount");
4574 feedsModel_->setData(indexUnread, 0);
4575 feedsModel_->setData(indexNew, 0);
4576
4577 if (!openFeed) {
4578 int parentId1 = feedsModel_->dataField(index1, "parentId").toInt();
4579 if ((currentNewsTab->feedId_ == id1) || (currentNewsTab->feedId_ == parentId1)) {
4580 openFeed = true;
4581 }
4582 }
4583 }
4584 }
4585
4586 QModelIndex indexUnread = feedsModel_->indexSibling(index, "unread");
4587 QModelIndex indexNew = feedsModel_->indexSibling(index, "newCount");
4588 feedsModel_->setData(indexUnread, 0);
4589 feedsModel_->setData(indexNew, 0);
4590 emit signalMarkFeedRead(id, feedsModel_->isFolder(index), openFeedT);
4591 }
4592
4593 // Update feed view with focus
4594 if (openFeed) {
4595 if ((tabBar_->currentIndex() == TAB_WIDGET_PERMANENT) && !isFolder) {
4596 signalRefreshNewsView(1);
4597 } else {
4598 signalRefreshNewsView(0);
4599 recountCategoryCounts();
4600 emit signalSetFeedsFilter(true);
4601 }
4602 }
4603 // Update feeds view without focus
4604 else {
4605 recountCategoryCounts();
4606 emit signalSetFeedsFilter();
4607 }
4608 }
4609
4610 /** @brief Refresh news view (After mark all feeds or one feed read)
4611 *---------------------------------------------------------------------------*/
slotRefreshNewsView(int nextUnread)4612 void MainWindow::slotRefreshNewsView(int nextUnread)
4613 {
4614 if (nextUnread == 1) {
4615 feedsView_->clearSelection();
4616 QModelIndex indexNextUnread =
4617 feedsView_->indexNextUnread(feedsView_->currentIndex());
4618 feedsView_->setCurrentIndex(indexNextUnread);
4619 slotFeedClicked(indexNextUnread);
4620 } else if ((tabBar_->currentIndex() == TAB_WIDGET_PERMANENT) && (nextUnread == -1)) {
4621 QModelIndex index = feedsProxyModel_->index(-1, "text");
4622 feedsView_->setCurrentIndex(index);
4623 slotFeedClicked(index);
4624 } else {
4625 int currentRow = newsView_->currentIndex().row();
4626
4627 newsModel_->select();
4628
4629 while (newsModel_->canFetchMore())
4630 newsModel_->fetchMore();
4631
4632 currentNewsTab->loadNewspaper(NewsTabWidget::RefreshWithPos);
4633
4634 newsView_->setCurrentIndex(newsModel_->index(currentRow, newsModel_->fieldIndex("title")));
4635 }
4636 }
4637
4638 // ----------------------------------------------------------------------------
slotShowAboutDlg()4639 void MainWindow::slotShowAboutDlg()
4640 {
4641 AboutDialog *aboutDialog = new AboutDialog(mainApp->language(), this);
4642 aboutDialog->exec();
4643 delete aboutDialog;
4644 }
4645
4646 /** @brief Call context menu of the feeds tree
4647 *----------------------------------------------------------------------------*/
showContextMenuFeed(const QPoint & pos)4648 void MainWindow::showContextMenuFeed(const QPoint &pos)
4649 {
4650 slotFeedMenuShow();
4651
4652 QModelIndex index = feedsView_->indexAt(pos);
4653 if (index.isValid()) {
4654 QRect rectText = feedsView_->visualRect(index);
4655 if (pos.x() >= rectText.x()) {
4656 QMenu menu;
4657 menu.addAction(addAct_);
4658 menu.addSeparator();
4659 menu.addAction(openFeedNewTabAct_);
4660 menu.addSeparator();
4661 menu.addAction(updateFeedAct_);
4662 menu.addSeparator();
4663 menu.addAction(markFeedRead_);
4664 menu.addSeparator();
4665 menu.addAction(deleteFeedAct_);
4666 menu.addSeparator();
4667 menu.addAction(setFilterNewsAct_);
4668 menu.addAction(feedProperties_);
4669
4670 menu.exec(feedsView_->viewport()->mapToGlobal(pos));
4671 }
4672 } else {
4673 QMenu menu;
4674 menu.addAction(addAct_);
4675
4676 menu.exec(feedsView_->viewport()->mapToGlobal(pos));
4677 }
4678
4679 index = feedsProxyModel_->mapToSource(feedsView_->currentIndex());
4680 feedsView_->selectId_ = feedsModel_->idByIndex(index);
4681
4682 feedProperties_->setEnabled(feedsView_->selectIndex().isValid());
4683 }
4684 // ----------------------------------------------------------------------------
slotFeedMenuShow()4685 void MainWindow::slotFeedMenuShow()
4686 {
4687 feedProperties_->setEnabled(feedsView_->selectIndex().isValid());
4688 }
4689 // ----------------------------------------------------------------------------
loadSettingsFeeds()4690 void MainWindow::loadSettingsFeeds()
4691 {
4692 markCurNewsRead_ = false;
4693 Settings settings;
4694 behaviorIconTray_ = settings.value("Settings/behaviorIconTray", NEW_COUNT_ICON_TRAY).toInt();
4695
4696 QString filterName = settings.value("feedSettings/filterName", "filterFeedsAll_").toString();
4697 QList<QAction*> listActions = feedsFilterGroup_->actions();
4698 foreach(QAction *action, listActions) {
4699 if (action->objectName() == filterName) {
4700 action->setChecked(true);
4701 break;
4702 }
4703 }
4704 filterName = settings.value("newsSettings/filterName", "filterNewsAll_").toString();
4705 listActions = newsFilterGroup_->actions();
4706 foreach(QAction *action, listActions) {
4707 if (action->objectName() == filterName) {
4708 action->setChecked(true);
4709 break;
4710 }
4711 }
4712
4713 setFeedsFilter(false);
4714 }
4715
4716 /** @brief Restore feeds state on application startup
4717 *---------------------------------------------------------------------------*/
restoreFeedsOnStartUp()4718 void MainWindow::restoreFeedsOnStartUp()
4719 {
4720 qApp->processEvents();
4721
4722 //* Restore current feed
4723 QModelIndex feedIndex = QModelIndex();
4724 if (reopenFeedStartup_) {
4725 Settings settings;
4726 int feedId = settings.value("feedSettings/currentId", 0).toInt();
4727 feedIndex = feedsProxyModel_->mapFromSource(feedId);
4728 }
4729 feedsView_->setCurrentIndex(feedIndex);
4730 updateCurrentTab_ = false;
4731 slotFeedClicked(feedIndex);
4732 currentNewsTab->webView_->setFocus();
4733 updateCurrentTab_ = true;
4734
4735 slotUpdateStatus(-1, false);
4736 recountCategoryCounts();
4737
4738 // Open feeds in tabs
4739 QSqlQuery q;
4740 q.exec(QString("SELECT id, parentId FROM feeds WHERE displayOnStartup=1"));
4741 while (q.next()) {
4742 creatFeedTab(q.value(0).toInt(), q.value(1).toInt());
4743 }
4744 }
4745 // ----------------------------------------------------------------------------
slotFeedsFilter()4746 void MainWindow::slotFeedsFilter()
4747 {
4748 if (feedsFilterGroup_->checkedAction()->objectName() == "filterFeedsAll_") {
4749 if (feedsFilterAction_ != NULL) {
4750 feedsFilterAction_->setChecked(true);
4751 setFeedsFilter();
4752 } else {
4753 if (mainToolbar_->widgetForAction(feedsFilter_)) {
4754 QWidget *widget = mainToolbar_->widgetForAction(feedsFilter_);
4755 if (widget->underMouse()) {
4756 feedsFilterMenu_->popup(widget->mapToGlobal(QPoint(0, mainToolbar_->height()-1)));
4757 }
4758 }
4759 if (feedsToolBar_->widgetForAction(feedsFilter_)) {
4760 QWidget *widget = feedsToolBar_->widgetForAction(feedsFilter_);
4761 if (widget->underMouse()) {
4762 feedsFilterMenu_->popup(widget->mapToGlobal(QPoint(0, feedsToolBar_->height()-1)));
4763 }
4764 }
4765 if (currentNewsTab->newsToolBar_->widgetForAction(feedsFilter_)) {
4766 QWidget *widget = currentNewsTab->newsToolBar_->widgetForAction(feedsFilter_);
4767 if (widget->underMouse()) {
4768 feedsFilterMenu_->popup(widget->mapToGlobal(QPoint(0, currentNewsTab->newsToolBar_->height()-1)));
4769 }
4770 }
4771 }
4772 } else {
4773 filterFeedsAll_->setChecked(true);
4774 setFeedsFilter();
4775 }
4776 }
4777 // ----------------------------------------------------------------------------
slotNewsFilter()4778 void MainWindow::slotNewsFilter()
4779 {
4780 if (newsFilterGroup_->checkedAction()->objectName() == mainNewsFilter_) {
4781 if (newsFilterAction_ != NULL) {
4782 newsFilterAction_->setChecked(true);
4783 setNewsFilter(newsFilterAction_);
4784 } else {
4785 if (mainToolbar_->widgetForAction(newsFilter_)) {
4786 QWidget *widget = mainToolbar_->widgetForAction(newsFilter_);
4787 if (widget->underMouse()) {
4788 newsFilterMenu_->popup(widget->mapToGlobal(QPoint(0, mainToolbar_->height()-1)));
4789 }
4790 }
4791 if (feedsToolBar_->widgetForAction(newsFilter_)) {
4792 QWidget *widget = feedsToolBar_->widgetForAction(newsFilter_);
4793 if (widget->underMouse()) {
4794 newsFilterMenu_->popup(widget->mapToGlobal(QPoint(0, feedsToolBar_->height()-1)));
4795 }
4796 }
4797 if (currentNewsTab->newsToolBar_->widgetForAction(newsFilter_)) {
4798 QWidget *widget = currentNewsTab->newsToolBar_->widgetForAction(newsFilter_);
4799 if (widget->underMouse()) {
4800 newsFilterMenu_->popup(widget->mapToGlobal(QPoint(0, currentNewsTab->newsToolBar_->height()-1)));
4801 }
4802 }
4803 }
4804 } else {
4805 foreach(QAction *action, newsFilterGroup_->actions()) {
4806 if (action->objectName() == mainNewsFilter_) {
4807 action->setChecked(true);
4808 setNewsFilter(action);
4809 break;
4810 }
4811 }
4812 }
4813 }
4814 // ----------------------------------------------------------------------------
slotShowUpdateAppDlg()4815 void MainWindow::slotShowUpdateAppDlg()
4816 {
4817 UpdateAppDialog *updateAppDialog = new UpdateAppDialog(mainApp->language(), this);
4818 updateAppDialog->activateWindow();
4819 updateAppDialog->exec();
4820 delete updateAppDialog;
4821 }
4822 // ----------------------------------------------------------------------------
retranslateStrings()4823 void MainWindow::retranslateStrings()
4824 {
4825 QString str = statusUnread_->text();
4826 str = str.right(str.length() - str.indexOf(':') - 1).replace(" ", "");
4827 statusUnread_->setText(QString(" " + tr("Unread: %1") + " ").arg(str));
4828 str = statusAll_->text();
4829 str = str.right(str.length() - str.indexOf(':') - 1).replace(" ", "");
4830 statusAll_->setText(QString(" " + tr("All: %1") + " ").arg(str));
4831
4832 str = traySystem->toolTip();
4833 QString info =
4834 "QuiteRSS\n" +
4835 QString(tr("New News: %1")).arg(str.section(": ", 1).section("\n", 0, 0)) +
4836 QString("\n") +
4837 QString(tr("Unread News: %1")).arg(str.section(": ", 2));
4838 traySystem->setToolTip(info);
4839
4840 mainMenuButton_->setToolTip(tr("Menu"));
4841
4842 addAct_->setText(tr("&Add"));
4843 addAct_->setToolTip(tr("Add New Feed"));
4844
4845 addFeedAct_->setText(tr("&Feed..."));
4846 addFeedAct_->setToolTip(tr("Add New Feed"));
4847
4848 addFeedTrayAct_->setText(tr("Add Feed..."));
4849
4850 addFolderAct_->setText(tr("F&older..."));
4851 addFolderAct_->setToolTip(tr("Add New Folder"));
4852
4853 openFeedNewTabAct_->setText(tr("Open in New Tab"));
4854
4855 deleteFeedAct_->setText(tr("&Delete..."));
4856 deleteFeedAct_->setToolTip(tr("Delete Selected Feed"));
4857
4858 importFeedsAct_->setText(tr("&Import Feeds..."));
4859 importFeedsAct_->setToolTip(tr("Import Feeds from OPML File"));
4860
4861 exportFeedsAct_->setText(tr("&Export Feeds..."));
4862 exportFeedsAct_->setToolTip(tr("Export Feeds to OPML File"));
4863
4864 createBackupAct_->setText(tr("&Create Backup..."));
4865 showMenuBarAct_->setText(tr("S&how Menu Bar"));
4866
4867 exitAct_->setText(tr("E&xit"));
4868
4869 updateFeedAct_->setText(tr("Update Feed"));
4870 updateFeedAct_->setToolTip(tr("Update Current Feed"));
4871
4872 updateAllFeedsAct_->setText(tr("Update All"));
4873 updateAllFeedsAct_->setToolTip(tr("Update All Feeds"));
4874
4875 stopUpdateAct_->setText(tr("Stop Update Feeds"));
4876 stopUpdateAct_->setToolTip(tr("Stop Update Feeds"));
4877
4878 markAllFeedsRead_->setText(tr("Mark All Feeds Read"));
4879
4880 markNewsRead_->setText(tr("Mark Read/Unread"));
4881 markNewsRead_->setToolTip(tr("Mark Current News Read/Unread"));
4882
4883 markAllNewsRead_->setText(tr("Mark All News Read"));
4884 markAllNewsRead_->setToolTip(tr("Mark All News Read"));
4885
4886 showDownloadManagerAct_->setText(tr("Downloads"));
4887
4888 showCleanUpWizardAct_->setText(tr("Clean Up..."));
4889
4890 setNewsFiltersAct_->setText(tr("News Filters..."));
4891 setFilterNewsAct_->setText(tr("Filter News..."));
4892
4893 optionsAct_->setText(tr("Options..."));
4894 optionsAct_->setToolTip(tr("Open Options Dialog"));
4895
4896 feedsFilter_->setText(tr("Filter Feeds"));
4897 filterFeedsAll_->setText(tr("Show All"));
4898 filterFeedsNew_->setText(tr("Show New"));
4899 filterFeedsUnread_->setText(tr("Show Unread"));
4900 filterFeedsStarred_->setText(tr("Show Starred Feeds"));
4901 filterFeedsError_->setText(tr("Show Not Working Feeds"));
4902
4903 newsFilter_->setText(tr("Filter News"));
4904 filterNewsAll_->setText(tr("Show All"));
4905 filterNewsNew_->setText(tr("Show New"));
4906 filterNewsUnread_->setText(tr("Show Unread"));
4907 filterNewsStar_->setText(tr("Show Starred"));
4908 filterNewsNotStarred_->setText(tr("Show Not Starred"));
4909 filterNewsUnreadStar_->setText(tr("Show Unread or Starred"));
4910 filterNewsLastDay_->setText(tr("Show Last Day"));
4911 filterNewsLastWeek_->setText(tr("Show Last 7 Days"));
4912
4913 aboutAct_ ->setText(tr("About..."));
4914 aboutAct_->setToolTip(tr("Show 'About' Dialog"));
4915
4916 updateAppAct_->setText(tr("Check for Updates..."));
4917 reportProblemAct_->setText(tr("Report a Problem..."));
4918
4919 openDescriptionNewsAct_->setText(tr("Open News"));
4920 openDescriptionNewsAct_->setToolTip(tr("Open News Description"));
4921 openInBrowserAct_->setText(tr("Open in Browser"));
4922 openInExternalBrowserAct_->setText(tr("Open in External Browser"));
4923 openInExternalBrowserAct_->setToolTip(tr("Open News in External Browser"));
4924 openNewsNewTabAct_->setText(tr("Open in New Tab"));
4925 openNewsNewTabAct_->setToolTip(tr("Open News in New Tab"));
4926 openNewsBackgroundTabAct_->setText(tr("Open in Background Tab"));
4927 openNewsBackgroundTabAct_->setToolTip(tr("Open News in Background Tab"));
4928 markStarAct_->setText(tr("Star"));
4929 markStarAct_->setToolTip(tr("Mark News Star"));
4930 deleteNewsAct_->setText(tr("Delete"));
4931 deleteNewsAct_->setToolTip(tr("Delete Selected News"));
4932 deleteAllNewsAct_->setText(tr("Delete All News"));
4933 deleteAllNewsAct_->setToolTip(tr("Delete All News from List"));
4934 restoreNewsAct_->setText(tr("Restore"));
4935 restoreNewsAct_->setToolTip(tr("Restore News"));
4936 copyLinkAct_->setText(tr("Copy Link"));
4937 copyLinkAct_->setToolTip(tr("Copy News Link"));
4938
4939 restoreLastNewsAct_->setText(tr("Restore last deleted news"));
4940
4941 markFeedRead_->setText(tr("Mark Read"));
4942 markFeedRead_->setToolTip(tr("Mark Feed Read"));
4943 feedProperties_->setText(tr("Properties"));
4944 feedProperties_->setToolTip(tr("Properties"));
4945
4946 fileMenu_->setTitle(tr("&File"));
4947 viewMenu_->setTitle(tr("&View"));
4948 feedMenu_->setTitle(tr("Fee&ds"));
4949 newsMenu_->setTitle(tr("&News"));
4950 browserMenu_->setTitle(tr("&Browser"));
4951 toolsMenu_->setTitle(tr("&Tools"));
4952 helpMenu_->setTitle(tr("&Help"));
4953
4954 mainToolbar_->setWindowTitle(tr("Main Toolbar"));
4955 customizeToolbarMenu_->setTitle(tr("Customize Toolbar"));
4956 customizeMainToolbarAct_->setText(tr("Main Toolbar..."));
4957 customizeMainToolbarAct2_->setText(tr("Customize Toolbar..."));
4958 customizeFeedsToolbarAct_->setText(tr("Feeds Toolbar..."));
4959 customizeNewsToolbarAct_->setText(tr("News Toolbar..."));
4960
4961 toolBarLockAct_->setText(tr("Lock Toolbar"));
4962 toolBarHideAct_->setText(tr("Hide Toolbar"));
4963
4964 layoutMenu_->setTitle(tr("Layout"));
4965 classicLayoutAct_->setText(tr("Classic"));
4966 newspaperLayoutAct_->setText(tr("Newspaper"));
4967 layoutToggle_->setText(tr("Layout"));
4968
4969 styleMenu_->setTitle(tr("Application Style"));
4970 systemStyle_->setText(tr("System"));
4971 system2Style_->setText(tr("System2"));
4972 darkStyle_->setText(tr("Dark"));
4973 greenStyle_->setText(tr("Green"));
4974 orangeStyle_->setText(tr("Orange"));
4975 purpleStyle_->setText(tr("Purple"));
4976 pinkStyle_->setText(tr("Pink"));
4977 grayStyle_->setText(tr("Gray"));
4978
4979 browserPositionMenu_->setTitle(tr("Browser Position"));
4980 topBrowserPositionAct_->setText(tr("Top"));
4981 bottomBrowserPositionAct_->setText(tr("Bottom"));
4982 rightBrowserPositionAct_->setText(tr("Right"));
4983 leftBrowserPositionAct_->setText(tr("Left"));
4984
4985 showWindowAct_->setText(tr("Show Window"));
4986
4987 feedKeyUpAct_->setText(tr("Previous Feed"));
4988 feedKeyDownAct_->setText(tr("Next Feed"));
4989 newsKeyUpAct_->setText(tr("Previous News"));
4990 newsKeyDownAct_->setText(tr("Next News"));
4991 newsKeyPageUpAct_->setText(tr("News Page Up"));
4992 newsKeyPageDownAct_->setText(tr("News Page Down"));
4993
4994 nextUnreadNewsAct_->setText(tr("Next Unread News"));
4995 prevUnreadNewsAct_->setText(tr("Previous Unread News"));
4996
4997 switchFocusAct_->setText(tr("Switch Focus to Next Panel"));
4998 switchFocusAct_->setToolTip(
4999 tr("Switch Focus to Next Panel (Tree Feeds, List News, Browser)"));
5000 switchFocusPrevAct_->setText(tr("Switch Focus to Previous Panel"));
5001 switchFocusPrevAct_->setToolTip(
5002 tr("Switch Focus to Previous Panel (Tree Feeds, Browser, List News)"));
5003
5004 feedsWidgetVisibleAct_->setText(tr("Show/Hide Tree Feeds"));
5005
5006 placeToTrayAct_->setText(tr("Minimize to Tray"));
5007 placeToTrayAct_->setToolTip(tr("Minimize Application to Tray"));
5008
5009 feedsColumnsMenu_->setTitle(tr("Columns"));
5010 showUnreadCount_->setText(tr("Count Unread News"));
5011 showUndeleteCount_->setText(tr("Count All News"));
5012 showLastUpdated_->setText(tr("Last Update"));
5013
5014 indentationFeedsTreeAct_->setText(tr("Show Indentation"));
5015
5016 findFeedAct_->setText(tr("Search Feed"));
5017 findFeedAct_->setToolTip(tr("Search Feed"));
5018
5019 browserZoomMenu_->setTitle(tr("Zoom"));
5020 zoomInAct_->setText(tr("Zoom In"));
5021 zoomInAct_->setToolTip(tr("Zoom in in browser"));
5022 zoomOutAct_->setText(tr("Zoom Out"));
5023 zoomOutAct_->setToolTip(tr("Zoom out in browser"));
5024 zoomTo100Act_->setText(tr("100%"));
5025 zoomTo100Act_->setToolTip(tr("Reset browser zoom"));
5026
5027 printAct_->setText(tr("Print..."));
5028 printAct_->setToolTip(tr("Print Web Page"));
5029 printPreviewAct_->setText(tr("Print Preview..."));
5030 printPreviewAct_->setToolTip(tr("Preview Web Page"));
5031
5032 pageUpWebViewAct_->setText(tr("Page up (Browser)"));
5033 pageDownWebViewAct_->setText(tr("Page down (Browser)"));
5034
5035 savePageAsAct_->setText(tr("Save As..."));
5036 savePageAsAct_->setToolTip(tr("Save Page As..."));
5037 savePageAsDescriptAct_->setText(tr("Save page in database"));
5038 savePageAsDescriptAct_->setToolTip(tr("Save page in database instead of news description"));
5039
5040 toolbarsMenu_->setTitle(tr("Show/Hide"));
5041 mainToolbarToggle_->setText(tr("Main Toolbar"));
5042 feedsToolbarToggle_->setText(tr("Feeds Toolbar"));
5043 newsToolbarToggle_->setText(tr("News Toolbar"));
5044 browserToolbarToggle_->setText(tr("Browser Toolbar"));
5045 categoriesPanelToggle_->setText(tr("Panel Categories"));
5046 statusBarToggle_->setText(tr("Status Bar"));
5047
5048 fullScreenAct_->setText(tr("Full Screen"));
5049 fullScreenAct_->setToolTip(tr("Full Screen"));
5050
5051 stayOnTopAct_->setText(tr("Stay On Top"));
5052 stayOnTopAct_->setToolTip(tr("Stay On Top"));
5053
5054 categoriesLabel_->setText(tr("Categories"));
5055 if (categoriesTree_->isHidden())
5056 showCategoriesButton_->setToolTip(tr("Show Categories"));
5057 else
5058 showCategoriesButton_->setToolTip(tr("Hide Categories"));
5059
5060 newsLabelMenuAction_->setText(tr("Label"));
5061 newsLabelAction_->setText(tr("Label"));
5062 showLabelsMenuAct_->setText(tr("Show labels menu"));
5063
5064 closeTabAct_->setText(tr("Close Tab"));
5065 closeOtherTabsAct_->setText(tr("Close Other Tabs"));
5066 closeAllTabsAct_->setText(tr("Close All Tabs"));
5067 nextTabAct_->setText(tr("Switch to next tab"));
5068 prevTabAct_->setText(tr("Switch to previous tab"));
5069
5070 categoriesTree_->topLevelItem(CategoriesTreeWidget::UnreadItem)->setText(0, tr("Unread"));
5071 categoriesTree_->topLevelItem(CategoriesTreeWidget::StarredItem)->setText(0, tr("Starred"));
5072 categoriesTree_->topLevelItem(CategoriesTreeWidget::DeletedItem)->setText(0, tr("Deleted"));
5073 categoriesTree_->topLevelItem(CategoriesTreeWidget::LabelsItem)->setText(0, tr("Labels"));
5074
5075 reduceNewsListAct_->setText(tr("Decrease news list/increase browser"));
5076 increaseNewsListAct_->setText(tr("Increase news list/decrease browser"));
5077
5078 findTextAct_->setText(tr("Find"));
5079
5080 openHomeFeedAct_->setText(tr("Open Homepage Feed"));
5081 sortedByTitleFeedsTreeAct_->setText(tr("Sort by Name"));
5082 collapseAllFoldersAct_->setText(tr("Collapse All Folders"));
5083 expandAllFoldersAct_->setText(tr("Expand All Folders"));
5084 nextFolderAct_->setText(tr("Next Folder"));
5085 prevFolderAct_->setText(tr("Previous Folder"));
5086 expandFolderAct_->setText(tr("Expand Folder"));
5087
5088 settingPageLabelsAct_->setText(tr("Setting Page: Labels"));
5089
5090 shareMenuAct_->setText(tr("Share"));
5091
5092 newsSortByMenu_->setTitle(tr("Sort By"));
5093 newsSortOrderGroup_->actions().at(0)->setText(tr("Ascending"));
5094 newsSortOrderGroup_->actions().at(1)->setText(tr("Descending"));
5095
5096 QApplication::translate("QDialogButtonBox", "Close");
5097 QApplication::translate("QDialogButtonBox", "Cancel");
5098 QApplication::translate("QDialogButtonBox", "&Yes");
5099 QApplication::translate("QDialogButtonBox", "&No");
5100
5101 QApplication::translate("QLineEdit", "&Undo");
5102 QApplication::translate("QLineEdit", "&Redo");
5103 QApplication::translate("QLineEdit", "Cu&t");
5104 QApplication::translate("QLineEdit", "&Copy");
5105 QApplication::translate("QLineEdit", "&Paste");
5106 QApplication::translate("QLineEdit", "Delete");
5107 QApplication::translate("QLineEdit", "Select All");
5108
5109 QApplication::translate("QTextControl", "&Undo");
5110 QApplication::translate("QTextControl", "&Redo");
5111 QApplication::translate("QTextControl", "Cu&t");
5112 QApplication::translate("QTextControl", "&Copy");
5113 QApplication::translate("QTextControl", "&Paste");
5114 QApplication::translate("QTextControl", "Delete");
5115 QApplication::translate("QTextControl", "Select All");
5116 QApplication::translate("QTextControl", "Copy &Link Location");
5117
5118 QApplication::translate("QAbstractSpinBox", "&Step up");
5119 QApplication::translate("QAbstractSpinBox", "Step &down");
5120 QApplication::translate("QAbstractSpinBox", "&Select All");
5121
5122 QApplication::translate("QMultiInputContext", "Select IM");
5123
5124 QApplication::translate("QWizard", "Cancel");
5125 QApplication::translate("QWizard", "< &Back");
5126 QApplication::translate("QWizard", "&Finish");
5127 QApplication::translate("QWizard", "&Next >");
5128
5129 QSqlQuery q;
5130 q.exec("SELECT id, name FROM labels WHERE id <= 6");
5131 while (q.next()) {
5132 int idLabel = q.value(0).toInt();
5133 QString nameLabel = q.value(1).toString();
5134 QList<QTreeWidgetItem *> treeItems;
5135 treeItems = categoriesTree_->findItems(QString::number(idLabel),
5136 Qt::MatchFixedString|Qt::MatchRecursive,
5137 2);
5138 if (treeItems.count() && (nameLabels().at(idLabel-1) == nameLabel)) {
5139 treeItems.at(0)->setText(0, trNameLabels().at(idLabel-1));
5140 for (int i = 0; i < newsLabelGroup_->actions().count(); i++) {
5141 if (newsLabelGroup_->actions().at(i)->data().toInt() == idLabel) {
5142 newsLabelGroup_->actions().at(i)->setText(trNameLabels().at(idLabel-1));
5143 newsLabelGroup_->actions().at(i)->setToolTip(trNameLabels().at(idLabel-1));
5144 break;
5145 }
5146 }
5147 for (int i = 0; i < stackedWidget_->count(); i++) {
5148 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
5149 if (widget->type_ == NewsTabWidget::TabTypeLabel) {
5150 if (widget->labelId_ == idLabel) {
5151 widget->setTextTab(trNameLabels().at(idLabel-1));
5152 }
5153 }
5154 }
5155 }
5156 }
5157
5158 if (newsView_) {
5159 currentNewsTab->retranslateStrings();
5160 }
5161 findFeeds_->retranslateStrings();
5162 mainApp->downloadManager()->retranslateStrings();
5163 adblockIcon_->retranslateStrings();
5164 QApplication::translate("AdBlockCustomList", "Custom Rules");
5165
5166
5167 if ((mainApp->language() == "ar") || (mainApp->language() == "fa")) {
5168 QApplication::setLayoutDirection(Qt::RightToLeft);
5169 mainMenuButton_->setStyleSheet("#mainMenuButton { border: none; padding: 0px 5px 0px 0px; }");
5170 } else {
5171 QApplication::setLayoutDirection(Qt::LeftToRight);
5172 mainMenuButton_->setStyleSheet("#mainMenuButton { border: none; padding: 0px 0px 0px 5px; }");
5173 }
5174
5175 /** Hack ltr <-> rtl**/
5176 int indexTab = tabBar_->addTab("");
5177 tabBar_->removeTab(indexTab);
5178 }
5179 // ----------------------------------------------------------------------------
setToolBarStyle(const QString & styleStr)5180 void MainWindow::setToolBarStyle(const QString &styleStr)
5181 {
5182 if (mainToolbar_->widgetForAction(addAct_))
5183 mainToolbar_->widgetForAction(addAct_)->setMinimumWidth(10);
5184 if (styleStr == "toolBarStyleI_") {
5185 mainToolbar_->setToolButtonStyle(Qt::ToolButtonIconOnly);
5186 } else if (styleStr == "toolBarStyleT_") {
5187 mainToolbar_->setToolButtonStyle(Qt::ToolButtonTextOnly);
5188 } else if (styleStr == "toolBarStyleTbI_") {
5189 mainToolbar_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
5190 } else {
5191 mainToolbar_->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
5192 if (mainToolbar_->widgetForAction(addAct_))
5193 mainToolbar_->widgetForAction(addAct_)->setMinimumWidth(60);
5194 }
5195 }
5196 // ----------------------------------------------------------------------------
setToolBarIconSize(QToolBar * toolbar,const QString & iconSizeStr)5197 void MainWindow::setToolBarIconSize(QToolBar *toolbar, const QString &iconSizeStr)
5198 {
5199 if (iconSizeStr == "toolBarIconBig_") {
5200 toolbar->setIconSize(QSize(32, 32));
5201 } else if (iconSizeStr == "toolBarIconSmall_") {
5202 toolbar->setIconSize(QSize(18, 18));
5203 } else {
5204 toolbar->setIconSize(QSize(24, 24));
5205 }
5206 }
5207
5208 /** @brief Call toolbar context menu
5209 *----------------------------------------------------------------------------*/
showContextMenuToolBar(const QPoint & pos)5210 void MainWindow::showContextMenuToolBar(const QPoint &pos)
5211 {
5212 QMenu menu;
5213 menu.addAction(customizeMainToolbarAct2_);
5214 menu.addSeparator();
5215 menu.addAction(toolBarLockAct_);
5216 menu.addAction(toolBarHideAct_);
5217
5218 menu.exec(mainToolbar_->mapToGlobal(pos));
5219 }
5220 // ----------------------------------------------------------------------------
lockMainToolbar(bool lock)5221 void MainWindow::lockMainToolbar(bool lock)
5222 {
5223 mainToolbar_->setMovable(!lock);
5224 }
5225 // ----------------------------------------------------------------------------
hideMainToolbar()5226 void MainWindow::hideMainToolbar()
5227 {
5228 mainToolbarToggle_->setChecked(false);
5229 mainToolbar_->hide();
5230 }
5231 // ----------------------------------------------------------------------------
showFeedPropertiesDlg()5232 void MainWindow::showFeedPropertiesDlg()
5233 {
5234 if (!feedsView_->selectIndex().isValid()) {
5235 feedProperties_->setEnabled(false);
5236 return;
5237 }
5238
5239 QPersistentModelIndex index = feedsView_->selectIndex();
5240 int feedId = feedsModel_->idByIndex(index);
5241 bool isFeed = (index.isValid() && feedsModel_->isFolder(index)) ? false : true;
5242
5243 FeedPropertiesDialog *feedPropertiesDialog = new FeedPropertiesDialog(isFeed, this);
5244
5245 FEED_PROPERTIES properties;
5246 FEED_PROPERTIES properties_tmp;
5247
5248 QByteArray byteArray = feedsModel_->dataField(index, "image").toByteArray();
5249 if (!byteArray.isNull()) {
5250 QPixmap icon;
5251 icon.loadFromData(QByteArray::fromBase64(byteArray));
5252 feedPropertiesDialog->setWindowIcon(icon);
5253 } else if (isFeed) {
5254 feedPropertiesDialog->setWindowIcon(QPixmap(":/images/feed"));
5255 } else {
5256 feedPropertiesDialog->setWindowIcon(QPixmap(":/images/folder"));
5257 }
5258 properties.general.image = QByteArray::fromBase64(byteArray);
5259
5260 QString str(feedPropertiesDialog->windowTitle() +
5261 " '" +
5262 feedsModel_->dataField(index, "text").toString() +
5263 "'");
5264 feedPropertiesDialog->setWindowTitle(str);
5265
5266 properties.general.text =
5267 feedsModel_->dataField(index, "text").toString();
5268 properties.general.title =
5269 feedsModel_->dataField(index, "title").toString();
5270 properties.general.url =
5271 feedsModel_->dataField(index, "xmlUrl").toString();
5272 properties.general.homepage =
5273 feedsModel_->dataField(index, "htmlUrl").toString();
5274 properties.general.displayOnStartup =
5275 feedsModel_->dataField(index, "displayOnStartup").toInt();
5276 properties.display.displayEmbeddedImages =
5277 feedsModel_->dataField(index, "displayEmbeddedImages").toInt();
5278 properties.display.javaScriptEnable =
5279 feedsModel_->dataField(index, "javaScriptEnable").toInt();
5280 if (feedsModel_->dataField(index, "displayNews").toString().isEmpty())
5281 properties.display.displayNews = !showDescriptionNews_;
5282 else
5283 properties.display.displayNews =
5284 feedsModel_->dataField(index, "displayNews").toInt();
5285 properties.display.layoutDirection =
5286 feedsModel_->dataField(index, "layoutDirection").toInt();
5287
5288 properties.general.disableUpdate =
5289 feedsModel_->dataField(index, "disableUpdate").toBool();
5290
5291 if (feedsModel_->dataField(index, "updateIntervalEnable").isNull() ||
5292 (feedsModel_->dataField(index, "updateIntervalEnable").toInt() == -1)) {
5293 properties.general.updateEnable = updateFeedsEnable_;
5294 properties.general.updateInterval = updateFeedsInterval_;
5295 properties.general.intervalType = updateFeedsIntervalType_;
5296 } else {
5297 properties.general.updateEnable =
5298 feedsModel_->dataField(index, "updateIntervalEnable").toBool();
5299 properties.general.updateInterval =
5300 feedsModel_->dataField(index, "updateInterval").toInt();
5301 properties.general.intervalType =
5302 feedsModel_->dataField(index, "updateIntervalType").toInt();
5303 }
5304
5305 if (feedsModel_->dataField(index, "label").toString().contains("starred"))
5306 properties.general.starred = true;
5307 else
5308 properties.general.starred = false;
5309
5310 properties.general.duplicateNewsMode =
5311 feedsModel_->dataField(index, "duplicateNewsMode").toBool();
5312
5313 properties.general.addSingleNewsAnyDateOn =
5314 feedsModel_->dataField(index, "addSingleNewsAnyDateOn").toBool();
5315
5316 properties.general.avoidedOldSingleNewsDateOn =
5317 feedsModel_->dataField(index, "avoidedOldSingleNewsDateOn").toBool();
5318
5319 properties.general.avoidedOldSingleNewsDate =
5320 feedsModel_->dataField(index, "avoidedOldSingleNewsDate").toDate();
5321
5322 Settings settings;
5323 settings.beginGroup("NewsHeader");
5324 QString indexColumnsStr = settings.value("columns").toString();
5325 QStringList indexColumnsList = indexColumnsStr.split(",", QString::SkipEmptyParts);
5326 foreach (QString indexStr, indexColumnsList) {
5327 properties.columnDefault.columns.append(indexStr.toInt());
5328 }
5329 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
5330 int sortBy = settings.value("sortBy", widget->newsModel_->fieldIndex("published")).toInt();
5331 properties.columnDefault.sortBy = sortBy;
5332 int sortType = settings.value("sortOrder", Qt::DescendingOrder).toInt();
5333 properties.columnDefault.sortType = sortType;
5334 settings.endGroup();
5335
5336 if (feedsModel_->dataField(index, "columns").toString().isEmpty()) {
5337 widget = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
5338 QListIterator<QAction *> iter(widget->newsHeader_->viewMenu_->actions());
5339 while (iter.hasNext()) {
5340 QAction *nextAction = iter.next();
5341 properties.column.indexList.append(nextAction->data().toInt());
5342 properties.column.nameList.append(nextAction->text());
5343 if (nextAction->isChecked())
5344 properties.column.columns.append(nextAction->data().toInt());
5345 }
5346 int section = widget->newsHeader_->sortIndicatorSection();
5347 properties.column.sortBy = section;
5348 if (widget->newsHeader_->sortIndicatorOrder() == Qt::AscendingOrder) {
5349 properties.column.sortType = 0;
5350 } else {
5351 properties.column.sortType = 1;
5352 }
5353 } else {
5354 widget = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
5355 QListIterator<QAction *> iter(widget->newsHeader_->viewMenu_->actions());
5356 while (iter.hasNext()) {
5357 QAction *nextAction = iter.next();
5358 properties.column.indexList.append(nextAction->data().toInt());
5359 properties.column.nameList.append(nextAction->text());
5360 }
5361 indexColumnsStr = feedsModel_->dataField(index, "columns").toString();
5362 indexColumnsList = indexColumnsStr.split(",", QString::SkipEmptyParts);
5363 foreach (QString indexStr, indexColumnsList) {
5364 properties.column.columns.append(indexStr.toInt());
5365 }
5366 properties.column.sortBy = feedsModel_->dataField(index, "sort").toInt();
5367 properties.column.sortType = feedsModel_->dataField(index, "sortType").toInt();
5368 }
5369
5370 properties.authentication.on = false;
5371 if (feedsModel_->dataField(index, "authentication").toInt() == 1) {
5372 properties.authentication.on = true;
5373 }
5374 QUrl url(feedsModel_->dataField(index, "xmlUrl").toString());
5375 QSqlQuery q;
5376 q.prepare("SELECT username, password FROM passwords WHERE server=?");
5377 q.addBindValue(url.host());
5378 q.exec();
5379 if (q.next()) {
5380 properties.authentication.user = q.value(0).toString();
5381 properties.authentication.pass = QString::fromUtf8(QByteArray::fromBase64(q.value(1).toByteArray()));
5382 }
5383
5384 properties.status.feedStatus = feedsModel_->dataField(index, "status").toString();
5385
5386 QDateTime dtLocalTime = QDateTime::currentDateTime();
5387 QDateTime dtUTC = QDateTime(dtLocalTime.date(), dtLocalTime.time(), Qt::UTC);
5388 int nTimeShift = dtLocalTime.secsTo(dtUTC);
5389
5390 QDateTime dt = QDateTime::fromString(
5391 feedsModel_->dataField(index, "created").toString(),
5392 Qt::ISODate);
5393 properties.status.createdTime = dt.addSecs(nTimeShift);
5394
5395 dt = QDateTime::fromString(
5396 feedsModel_->dataField(index, "updated").toString(),
5397 Qt::ISODate);
5398 properties.status.lastUpdate = dt.addSecs(nTimeShift);
5399
5400 dt = QDateTime::fromString(
5401 feedsModel_->dataField(index, "lastBuildDate").toString(),
5402 Qt::ISODate);
5403 properties.status.lastBuildDate = dt.addSecs(nTimeShift);
5404
5405 properties.status.undeleteCount = feedsModel_->dataField(index, "undeleteCount").toInt();
5406 properties.status.newCount = feedsModel_->dataField(index, "newCount").toInt();
5407 properties.status.unreadCount = feedsModel_->dataField(index, "unread").toInt();
5408 properties.status.description = feedsModel_->dataField(index, "description").toString();
5409
5410 properties.status.feedsCount = 0;
5411 if (!isFeed) {
5412 QQueue<int> parentIds;
5413 parentIds.enqueue(feedId);
5414 while (!parentIds.empty()) {
5415 int parentId = parentIds.dequeue();
5416 q.exec(QString("SELECT id, xmlUrl FROM feeds WHERE parentId='%1'").arg(parentId));
5417 while (q.next()) {
5418 QString xmlUrl = q.value(1).toString();
5419 if (xmlUrl.isEmpty())
5420 parentIds.enqueue(q.value(0).toInt());
5421 else
5422 properties.status.feedsCount++;
5423 }
5424 }
5425 }
5426
5427 feedPropertiesDialog->setFeedProperties(properties);
5428 properties_tmp = properties;
5429
5430 int result = feedPropertiesDialog->exec();
5431 if (result == QDialog::Rejected) {
5432 delete feedPropertiesDialog;
5433 return;
5434 }
5435
5436 if (!mainApp->storeDBMemory())
5437 db_.transaction();
5438
5439 properties = feedPropertiesDialog->getFeedProperties();
5440 delete feedPropertiesDialog;
5441
5442 index = feedsModel_->indexById(feedId);
5443
5444 q.prepare("UPDATE feeds SET text = ?, xmlUrl = ?, displayOnStartup = ?, "
5445 "displayEmbeddedImages = ?, displayNews = ?, layoutDirection = ?, "
5446 "label = ?, duplicateNewsMode = ?, addSingleNewsAnyDateOn = ?, avoidedOldSingleNewsDateOn = ?, avoidedOldSingleNewsDate = ?,"
5447 " authentication = ?, disableUpdate = ?, "
5448 "javaScriptEnable = ? WHERE id == ?");
5449 q.addBindValue(properties.general.text);
5450 q.addBindValue(properties.general.url);
5451 q.addBindValue(properties.general.displayOnStartup);
5452 q.addBindValue(properties.display.displayEmbeddedImages);
5453 q.addBindValue(properties.display.displayNews);
5454 q.addBindValue(properties.display.layoutDirection);
5455 if (properties.general.starred)
5456 q.addBindValue("starred");
5457 else
5458 q.addBindValue("");
5459 q.addBindValue(properties.general.duplicateNewsMode ? 1 : 0);
5460 q.addBindValue(properties.general.addSingleNewsAnyDateOn ? 1 : 0);
5461 q.addBindValue(properties.general.avoidedOldSingleNewsDateOn ? 1 : 0);
5462 q.addBindValue(properties.general.avoidedOldSingleNewsDate);
5463 q.addBindValue(properties.authentication.on ? 1 : 0);
5464 q.addBindValue(properties.general.disableUpdate ? 1 : 0);
5465 q.addBindValue(properties.display.javaScriptEnable);
5466 q.addBindValue(feedId);
5467 q.exec();
5468
5469
5470 indexColumnsStr = "";
5471 if ((properties.column.columns != properties.columnDefault.columns) ||
5472 (properties.column.sortBy != properties.columnDefault.sortBy) ||
5473 (properties.column.sortType != properties.columnDefault.sortType)) {
5474 for (int i = 0; i < properties.column.columns.count(); ++i) {
5475 int index = properties.column.columns.at(i);
5476 indexColumnsStr.append(",");
5477 indexColumnsStr.append(QString::number(index));
5478 }
5479 indexColumnsStr.append(",");
5480 } else {
5481 properties.column.sortBy = 0;
5482 properties.column.sortType = 0;
5483 }
5484
5485 q.prepare("UPDATE feeds SET columns = ?, sort = ?, sortType = ? WHERE id == ?");
5486 q.addBindValue(indexColumnsStr);
5487 q.addBindValue(properties.column.sortBy);
5488 q.addBindValue(properties.column.sortType);
5489 q.addBindValue(feedId);
5490 q.exec();
5491
5492 QModelIndex indexColumns = feedsModel_->indexSibling(index, "columns");
5493 QModelIndex indexSort = feedsModel_->indexSibling(index, "sort");
5494 QModelIndex indexSortType = feedsModel_->indexSibling(index, "sortType");
5495 feedsModel_->setData(indexColumns, indexColumnsStr);
5496 feedsModel_->setData(indexSort, properties.column.sortBy);
5497 feedsModel_->setData(indexSortType, properties.column.sortType);
5498
5499 if (!isFeed) {
5500 QQueue<int> parentIds;
5501 parentIds.enqueue(feedId);
5502 while (!parentIds.empty()) {
5503 int parentId = parentIds.dequeue();
5504 q.exec(QString("SELECT id, xmlUrl FROM feeds WHERE parentId='%1'").
5505 arg(parentId));
5506 while (q.next()) {
5507 int id = q.value(0).toInt();
5508 QString xmlUrl = q.value(1).toString();
5509
5510 QSqlQuery q1;
5511 q1.prepare("UPDATE feeds SET columns = ?, sort = ?, sortType = ? WHERE id == ?");
5512 q1.addBindValue(indexColumnsStr);
5513 q1.addBindValue(properties.column.sortBy);
5514 q1.addBindValue(properties.column.sortType);
5515 q1.addBindValue(id);
5516 q1.exec();
5517
5518 QPersistentModelIndex index1 = feedsModel_->indexById(id);
5519 indexColumns = feedsModel_->indexSibling(index1, "columns");
5520 indexSort = feedsModel_->indexSibling(index1, "sort");
5521 indexSortType = feedsModel_->indexSibling(index1, "sortType");
5522 feedsModel_->setData(indexColumns, indexColumnsStr);
5523 feedsModel_->setData(indexSort, properties.column.sortBy);
5524 feedsModel_->setData(indexSortType, properties.column.sortType);
5525
5526 if (currentNewsTab->feedId_ == id)
5527 currentNewsTab->newsHeader_->setColumns(index1);
5528
5529 if (xmlUrl.isEmpty())
5530 parentIds.enqueue(id);
5531 }
5532 }
5533 }
5534
5535 if (currentNewsTab->feedId_ == feedId)
5536 currentNewsTab->newsHeader_->setColumns(index);
5537
5538
5539 if (!(!feedsModel_->dataField(index, "authentication").toInt() && !properties.authentication.on)) {
5540 q.prepare("SELECT * FROM passwords WHERE server=?");
5541 q.addBindValue(url.host());
5542 q.exec();
5543 if (q.next()) {
5544 q.prepare("UPDATE passwords SET username = ?, password = ? WHERE server=?");
5545 q.addBindValue(properties.authentication.user);
5546 q.addBindValue(properties.authentication.pass.toUtf8().toBase64());
5547 q.addBindValue(url.host());
5548 q.exec();
5549 } else if (properties.authentication.on) {
5550 q.prepare("INSERT INTO passwords (server, username, password) "
5551 "VALUES (:server, :username, :password)");
5552 q.bindValue(":server", url.host());
5553 q.bindValue(":username", properties.authentication.user);
5554 q.bindValue(":password", properties.authentication.pass.toUtf8().toBase64());
5555 q.exec();
5556 }
5557 }
5558
5559 QPersistentModelIndex indexText = feedsModel_->indexSibling(index, "text");
5560 QPersistentModelIndex indexUrl = feedsModel_->indexSibling(index, "xmlUrl");
5561 QPersistentModelIndex indexStartup = feedsModel_->indexSibling(index, "displayOnStartup");
5562 QModelIndex indexImages = feedsModel_->indexSibling(index, "displayEmbeddedImages");
5563 QModelIndex indexNews = feedsModel_->indexSibling(index, "displayNews");
5564 QModelIndex indexRTL = feedsModel_->indexSibling(index, "layoutDirection");
5565 QModelIndex indexLabel = feedsModel_->indexSibling(index, "label");
5566 QModelIndex indexDuplicate = feedsModel_->indexSibling(index, "duplicateNewsMode");
5567 QModelIndex indexaddSingleNewsAnyDateOn = feedsModel_->indexSibling(index, "addSingleNewsAnyDateOn");
5568 QModelIndex indexavoidedOldSingleNewsDateOn = feedsModel_->indexSibling(index, "avoidedOldSingleNewsDateOn");
5569 QModelIndex indexavoidedOldSingleNewsDate = feedsModel_->indexSibling(index, "avoidedOldSingleNewsDate");
5570 QModelIndex indexAuthentication = feedsModel_->indexSibling(index, "authentication");
5571 QModelIndex indexDisableUpdate = feedsModel_->indexSibling(index, "disableUpdate");
5572 QModelIndex indexJavaScript = feedsModel_->indexSibling(index, "javaScriptEnable");
5573 feedsModel_->setData(indexText, properties.general.text);
5574 feedsModel_->setData(indexUrl, properties.general.url);
5575 feedsModel_->setData(indexStartup, properties.general.displayOnStartup);
5576 feedsModel_->setData(indexImages, properties.display.displayEmbeddedImages);
5577 feedsModel_->setData(indexNews, properties.display.displayNews);
5578 feedsModel_->setData(indexRTL, properties.display.layoutDirection);
5579 feedsModel_->setData(indexLabel, properties.general.starred ? "starred" : "");
5580 feedsModel_->setData(indexDuplicate, properties.general.duplicateNewsMode ? 1 : 0);
5581 feedsModel_->setData(indexaddSingleNewsAnyDateOn, properties.general.addSingleNewsAnyDateOn ? 1 : 0);
5582 feedsModel_->setData(indexavoidedOldSingleNewsDateOn, properties.general.avoidedOldSingleNewsDateOn ? 1 : 0);
5583 feedsModel_->setData(indexavoidedOldSingleNewsDate, properties.general.avoidedOldSingleNewsDate);
5584 feedsModel_->setData(indexAuthentication, properties.authentication.on ? 1 : 0);
5585 feedsModel_->setData(indexDisableUpdate, properties.general.disableUpdate ? 1 : 0);
5586 feedsModel_->setData(indexJavaScript, properties.display.javaScriptEnable);
5587
5588 if (!properties.general.updateEnable ||
5589 (properties.general.updateEnable != updateFeedsEnable_) ||
5590 (properties.general.updateInterval != updateFeedsInterval_) ||
5591 (properties.general.intervalType != updateFeedsIntervalType_)) {
5592 q.prepare("UPDATE feeds SET updateIntervalEnable = ?, updateInterval = ?, "
5593 "updateIntervalType = ? WHERE id == ?");
5594 q.addBindValue(properties.general.updateEnable ? 1 : 0);
5595 q.addBindValue(properties.general.updateInterval);
5596 q.addBindValue(properties.general.intervalType);
5597 q.addBindValue(feedId);
5598 q.exec();
5599
5600 QPersistentModelIndex indexUpdateEnable = feedsModel_->indexSibling(index, "updateIntervalEnable");
5601 QPersistentModelIndex indexUpdateInterval = feedsModel_->indexSibling(index, "updateInterval");
5602 QPersistentModelIndex indexIntervalType = feedsModel_->indexSibling(index, "updateIntervalType");
5603 feedsModel_->setData(indexUpdateEnable, properties.general.updateEnable ? 1 : 0);
5604 feedsModel_->setData(indexUpdateInterval, properties.general.updateInterval);
5605 feedsModel_->setData(indexIntervalType, properties.general.intervalType);
5606
5607 int updateInterval = properties.general.updateInterval;
5608 int updateIntervalType = properties.general.intervalType;
5609 if (updateIntervalType == 0)
5610 updateInterval = updateInterval*60;
5611 else if (updateIntervalType == 1)
5612 updateInterval = updateInterval*60*60;
5613
5614 if (!isFeed) {
5615 QQueue<int> parentIds;
5616 parentIds.enqueue(feedId);
5617 while (!parentIds.empty()) {
5618 int parentId = parentIds.dequeue();
5619 q.exec(QString("SELECT id, xmlUrl FROM feeds WHERE parentId='%1'").
5620 arg(parentId));
5621 while (q.next()) {
5622 int id = q.value(0).toInt();
5623 QString xmlUrl = q.value(1).toString();
5624
5625 QSqlQuery q1;
5626 q1.prepare("UPDATE feeds SET updateIntervalEnable = ?, updateInterval = ?, "
5627 "updateIntervalType = ? WHERE id == ?");
5628 q1.addBindValue(properties.general.updateEnable ? 1 : 0);
5629 q1.addBindValue(properties.general.updateInterval);
5630 q1.addBindValue(properties.general.intervalType);
5631 q1.addBindValue(id);
5632 q1.exec();
5633
5634 QPersistentModelIndex index1 = feedsModel_->indexById(id);
5635 indexUpdateEnable = feedsModel_->indexSibling(index1, "updateIntervalEnable");
5636 indexUpdateInterval = feedsModel_->indexSibling(index1, "updateInterval");
5637 indexIntervalType = feedsModel_->indexSibling(index1, "updateIntervalType");
5638 feedsModel_->setData(indexUpdateEnable, properties.general.updateEnable ? 1 : 0);
5639 feedsModel_->setData(indexUpdateInterval, properties.general.updateInterval);
5640 feedsModel_->setData(indexIntervalType, properties.general.intervalType);
5641
5642 if (!xmlUrl.isEmpty()) {
5643 if (properties.general.updateEnable) {
5644 updateFeedsIntervalSec_.insert(id, updateInterval);
5645 updateFeedsTimeCount_.insert(id, 0);
5646 } else {
5647 updateFeedsIntervalSec_.remove(id);
5648 updateFeedsTimeCount_.remove(id);
5649 }
5650 } else {
5651 parentIds.enqueue(id);
5652 }
5653 }
5654 }
5655 } else {
5656 if (properties.general.updateEnable) {
5657 updateFeedsIntervalSec_.insert(feedId, updateInterval);
5658 updateFeedsTimeCount_.insert(feedId, 0);
5659 } else {
5660 updateFeedsIntervalSec_.remove(feedId);
5661 updateFeedsTimeCount_.remove(feedId);
5662 }
5663 }
5664 } else {
5665 q.prepare("UPDATE feeds SET updateIntervalEnable = -1 WHERE id == ?");
5666 q.addBindValue(feedId);
5667 q.exec();
5668
5669 QPersistentModelIndex indexUpdateEnable = feedsModel_->indexSibling(index, "updateIntervalEnable");
5670 feedsModel_->setData(indexUpdateEnable, "-1");
5671
5672 updateFeedsIntervalSec_.remove(feedId);
5673 updateFeedsTimeCount_.remove(feedId);
5674 }
5675
5676 if (properties.general.image != properties_tmp.general.image) {
5677 q.prepare("UPDATE feeds SET image = ? WHERE id == ?");
5678 q.addBindValue(properties.general.image.toBase64());
5679 q.addBindValue(feedId);
5680 q.exec();
5681 slotIconFeedUpdate(feedId, properties.general.image);
5682 }
5683
5684 if ((properties.display.layoutDirection != properties_tmp.display.layoutDirection) &&
5685 !isFeed) {
5686 QQueue<int> parentIds;
5687 parentIds.enqueue(feedId);
5688 while (!parentIds.empty()) {
5689 int parentId = parentIds.dequeue();
5690 q.exec(QString("SELECT id, xmlUrl FROM feeds WHERE parentId='%1'").arg(parentId));
5691 while (q.next()) {
5692 int id = q.value(0).toInt();
5693 QString xmlUrl = q.value(1).toString();
5694
5695 QSqlQuery q1;
5696 q1.prepare("UPDATE feeds SET layoutDirection = ? WHERE id == ?");
5697 q1.addBindValue(properties.display.layoutDirection);
5698 q1.addBindValue(id);
5699 q1.exec();
5700
5701 QPersistentModelIndex index1 = feedsModel_->indexById(id);
5702 indexRTL = feedsModel_->indexSibling(index1, "layoutDirection");
5703 feedsModel_->setData(indexRTL, properties.display.layoutDirection);
5704
5705 for (int i = 0; i < stackedWidget_->count(); i++) {
5706 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
5707 if (widget->feedId_ == id) {
5708 widget->setSettings();
5709 }
5710 }
5711
5712 if (xmlUrl.isEmpty())
5713 parentIds.enqueue(id);
5714 }
5715 }
5716 }
5717
5718 for (int i = 0; i < stackedWidget_->count(); i++) {
5719 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
5720 if (widget->feedId_ == feedId) {
5721 if (properties.general.text != properties_tmp.general.text) {
5722 widget->setTextTab(properties.general.text);
5723 }
5724 if ((properties.display.layoutDirection != properties_tmp.display.layoutDirection) ||
5725 (properties.display.javaScriptEnable != properties_tmp.display.javaScriptEnable)) {
5726 widget->setSettings();
5727 }
5728 }
5729 }
5730
5731 if ((properties.general.disableUpdate != properties_tmp.general.disableUpdate) &&
5732 !isFeed) {
5733 QQueue<int> parentIds;
5734 parentIds.enqueue(feedId);
5735 while (!parentIds.empty()) {
5736 int parentId = parentIds.dequeue();
5737 q.exec(QString("SELECT id, xmlUrl FROM feeds WHERE parentId='%1'").arg(parentId));
5738 while (q.next()) {
5739 int id = q.value(0).toInt();
5740 QString xmlUrl = q.value(1).toString();
5741
5742 QSqlQuery q1;
5743 q1.prepare("UPDATE feeds SET disableUpdate = ? WHERE id == ?");
5744 q1.addBindValue(properties.general.disableUpdate ? 1 : 0);
5745 q1.addBindValue(id);
5746 q1.exec();
5747
5748 QPersistentModelIndex index1 = feedsModel_->indexById(id);
5749 indexDisableUpdate = feedsModel_->indexSibling(index1, "disableUpdate");
5750 feedsModel_->setData(indexDisableUpdate, properties.general.disableUpdate ? 1 : 0);
5751
5752 if (xmlUrl.isEmpty())
5753 parentIds.enqueue(id);
5754 }
5755 }
5756 }
5757
5758 if (!mainApp->storeDBMemory())
5759 db_.commit();
5760 }
5761
5762 /** @brief Update tray information: icon and tooltip text
5763 *---------------------------------------------------------------------------*/
slotRefreshInfoTray(int newCount,int unreadCount)5764 void MainWindow::slotRefreshInfoTray(int newCount, int unreadCount)
5765 {
5766 if (!unreadCount)
5767 categoriesTree_->topLevelItem(CategoriesTreeWidget::UnreadItem)->setText(4, "");
5768 else
5769 categoriesTree_->topLevelItem(CategoriesTreeWidget::UnreadItem)->setText(4, QString("(%1)").arg(unreadCount));
5770 QFont font = categoriesTree_->topLevelItem(CategoriesTreeWidget::UnreadItem)->font(0);
5771 if (unreadCount)
5772 font.setBold(true);
5773 else
5774 font.setBold(false);
5775 categoriesTree_->topLevelItem(CategoriesTreeWidget::UnreadItem)->setFont(0, font);
5776
5777 if (!showTrayIcon_) return;
5778
5779 // Setting tooltip text
5780 QString info =
5781 "QuiteRSS\n" +
5782 QString(tr("New News: %1")).arg(newCount) +
5783 QString("\n") +
5784 QString(tr("Unread News: %1")).arg(unreadCount);
5785 traySystem->setToolTip(info);
5786
5787 // Display new number or unread number of news
5788 if (behaviorIconTray_ > CHANGE_ICON_TRAY) {
5789 int trayCount = (behaviorIconTray_ == UNREAD_COUNT_ICON_TRAY) ? unreadCount : newCount;
5790 // Display icon with number
5791 if (trayCount != 0) {
5792 // Prepare number
5793 QString trayCountStr;
5794 QFont font("Consolas");
5795 if (trayCount > 99) {
5796 font.setBold(false);
5797 if (trayCount < 1000) {
5798 font.setPixelSize(60);
5799 trayCountStr = QString::number(trayCount);
5800 } else {
5801 font.setPixelSize(86);
5802 trayCountStr = "#";
5803 }
5804 } else {
5805 font.setBold(true);
5806 font.setPixelSize(90);
5807 trayCountStr = QString::number(trayCount);
5808 }
5809
5810 // Draw icon, text above it, and set this icon to tray icon
5811 QPixmap icon(128, 128);
5812 icon.fill(Qt::transparent);
5813 QPainter trayPainter;
5814 trayPainter.begin(&icon);
5815 trayPainter.setRenderHint(QPainter::SmoothPixmapTransform, true);
5816 trayPainter.setRenderHint(QPainter::TextAntialiasing, true);
5817 QRect rectangle(0, 0, 128, 128);
5818 QLinearGradient gradient(rectangle.bottomLeft(), rectangle.topLeft());
5819 QColor color("#117C04");
5820 gradient.setColorAt(0, color.light());
5821 gradient.setColorAt(0.5, color);
5822 gradient.setColorAt(1, color.light());
5823 trayPainter.setBrush(gradient);
5824 trayPainter.drawRoundedRect(rectangle, 20, 20);
5825 trayPainter.setFont(font);
5826 trayPainter.setPen("#FFFFFF");
5827 trayPainter.drawText(rectangle, Qt::AlignVCenter | Qt::AlignHCenter,
5828 trayCountStr);
5829 trayPainter.end();
5830 traySystem->setIcon(icon);
5831 }
5832 // Draw icon without number
5833 else {
5834 traySystem->setIcon(QIcon(":/images/quiterss128"));
5835 }
5836 }
5837 }
5838
5839 /** @brief Prepare feed icon for storing in DB
5840 *---------------------------------------------------------------------------*/
slotIconFeedPreparing(QString feedUrl,QByteArray byteArray,QString format)5841 void MainWindow::slotIconFeedPreparing(QString feedUrl, QByteArray byteArray,
5842 QString format)
5843 {
5844 QPixmap icon;
5845 if (icon.loadFromData(byteArray)) {
5846 icon = icon.scaled(16, 16, Qt::IgnoreAspectRatio,
5847 Qt::SmoothTransformation);
5848 QByteArray faviconData;
5849 QBuffer buffer(&faviconData);
5850 buffer.open(QIODevice::WriteOnly);
5851 if (icon.save(&buffer, "ICO")) {
5852 emit signalIconFeedReady(feedUrl, faviconData);
5853 }
5854 } else if (icon.loadFromData(byteArray, format.toUtf8().data())) {
5855 icon = icon.scaled(16, 16, Qt::IgnoreAspectRatio,
5856 Qt::SmoothTransformation);
5857 QByteArray faviconData;
5858 QBuffer buffer(&faviconData);
5859 buffer.open(QIODevice::WriteOnly);
5860 if (icon.save(&buffer, "ICO")) {
5861 emit signalIconFeedReady(feedUrl, faviconData);
5862 }
5863 }
5864 }
5865
5866 /** @brief Update feed icon in model and view
5867 *---------------------------------------------------------------------------*/
slotIconFeedUpdate(int feedId,QByteArray faviconData)5868 void MainWindow::slotIconFeedUpdate(int feedId, QByteArray faviconData)
5869 {
5870 QModelIndex index = feedsModel_->indexById(feedId);
5871 if (index.isValid()) {
5872 QModelIndex indexImage = feedsModel_->indexSibling(index, "image");
5873 feedsModel_->setData(indexImage, faviconData.toBase64());
5874 feedsView_->viewport()->update();
5875 }
5876
5877 if (defaultIconFeeds_) return;
5878
5879 for (int i = 0; i < stackedWidget_->count(); i++) {
5880 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
5881 if (widget->feedId_ == feedId) {
5882 QPixmap iconTab;
5883 if (!faviconData.isNull()) {
5884 iconTab.loadFromData(faviconData);
5885 } else {
5886 iconTab.load(":/images/feed");
5887 }
5888 widget->newsIconTitle_->setPixmap(iconTab);
5889 }
5890 }
5891 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb)
5892 currentNewsTab->newsView_->viewport()->update();
5893 }
5894 // ----------------------------------------------------------------------------
slotPlaySound(const QString & path)5895 void MainWindow::slotPlaySound(const QString &path)
5896 {
5897 QString soundPath = mainApp->absolutePath(path);
5898
5899 if (!QFile::exists(soundPath)) {
5900 qWarning() << QString("Error playing sound: %1").arg(soundPath);
5901 return;
5902 }
5903
5904 bool playing = false;
5905 Settings settings;
5906 bool useMediaPlayer = settings.value("Settings/useMediaPlayer", true).toBool();
5907
5908 if (useMediaPlayer) {
5909 #ifdef HAVE_QT5
5910 if (mediaPlayer_ == NULL) {
5911 playlist_ = new QMediaPlaylist(this);
5912 mediaPlayer_ = new QMediaPlayer(this);
5913 mediaPlayer_->setPlaylist(playlist_);
5914 connect(mediaPlayer_, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
5915 this, SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus)));
5916 connect(mediaPlayer_, SIGNAL(error(QMediaPlayer::Error)),
5917 this, SLOT(mediaError(QMediaPlayer::Error)));
5918 }
5919
5920 playlist_->addMedia(QUrl::fromLocalFile(soundPath));
5921 if (playlist_->currentIndex() == -1) {
5922 playlist_->setCurrentIndex(1);
5923 mediaPlayer_->play();
5924 }
5925
5926 playing = true;
5927 #else
5928 #ifdef HAVE_PHONON
5929 if (mediaPlayer_ == NULL) {
5930 mediaPlayer_ = new Phonon::MediaObject(this);
5931 audioOutput_ = new Phonon::AudioOutput(Phonon::MusicCategory, this);
5932 Phonon::createPath(mediaPlayer_, audioOutput_);
5933 connect(mediaPlayer_, SIGNAL(stateChanged(Phonon::State,Phonon::State)),
5934 this, SLOT(mediaStateChanged(Phonon::State,Phonon::State)));
5935 }
5936
5937 if (mediaPlayer_->state() == Phonon::ErrorState)
5938 mediaPlayer_->clear();
5939
5940 if ((mediaPlayer_->state() != Phonon::PausedState) &&
5941 (mediaPlayer_->state() != Phonon::StoppedState)) {
5942 mediaPlayer_->enqueue(soundPath);
5943 }
5944 else {
5945 mediaPlayer_->setCurrentSource(soundPath);
5946 }
5947 mediaPlayer_->play();
5948
5949 playing = true;
5950 #endif
5951 #endif
5952 }
5953
5954 if (!playing) {
5955 #if defined(Q_OS_WIN) || defined(Q_OS_OS2)
5956 QSound::play(soundPath);
5957 #else
5958 QProcess::startDetached(QString("play %1").arg(soundPath));
5959 #endif
5960 }
5961 }
5962
5963 #ifdef HAVE_QT5
mediaStatusChanged(QMediaPlayer::MediaStatus status)5964 void MainWindow::mediaStatusChanged(QMediaPlayer::MediaStatus status)
5965 {
5966 if (status == QMediaPlayer::EndOfMedia) {
5967 playlist_->removeMedia(0);
5968 }
5969 }
5970
mediaError(QMediaPlayer::Error error)5971 void MainWindow::mediaError(QMediaPlayer::Error error)
5972 {
5973 QTextCodec *codec = QTextCodec::codecForLocale();
5974 qCritical() << QString("Error Media: %1 - %2").
5975 arg(error).
5976 arg(codec->toUnicode(mediaPlayer_->errorString().toUtf8()));
5977 }
5978 #endif
5979
5980 #ifdef HAVE_PHONON
mediaStateChanged(Phonon::State newstate,Phonon::State)5981 void MainWindow::mediaStateChanged(Phonon::State newstate, Phonon::State)
5982 {
5983 if (newstate == Phonon::ErrorState) {
5984 QTextCodec *codec = QTextCodec::codecForLocale();
5985 qCritical() << QString("Error Phonon: %1 - %2").
5986 arg(mediaPlayer_->errorType()).
5987 arg(codec->toUnicode(mediaPlayer_->errorString().toUtf8()));
5988 }
5989 }
5990 #endif
5991
slotPlaySoundNewNews()5992 void MainWindow::slotPlaySoundNewNews()
5993 {
5994 if (!playSoundNewNews_ && soundNewNews_) {
5995 slotPlaySound(soundNotifyPath_);
5996 playSoundNewNews_ = true;
5997 }
5998 }
5999
6000 // ----------------------------------------------------------------------------
showNewsFiltersDlg(bool newFilter)6001 void MainWindow::showNewsFiltersDlg(bool newFilter)
6002 {
6003 NewsFiltersDialog *newsFiltersDialog = new NewsFiltersDialog(this);
6004 if (newFilter) {
6005 newsFiltersDialog->filtersTree_->setCurrentItem(
6006 newsFiltersDialog->filtersTree_->topLevelItem(
6007 newsFiltersDialog->filtersTree_->topLevelItemCount()-1));
6008 }
6009
6010 newsFiltersDialog->exec();
6011
6012 delete newsFiltersDialog;
6013 }
6014 // ----------------------------------------------------------------------------
showFilterRulesDlg()6015 void MainWindow::showFilterRulesDlg()
6016 {
6017 if (!feedsView_->selectIndex().isValid()) return;
6018
6019 int feedId = feedsView_->selectId_;
6020
6021 FilterRulesDialog *filterRulesDialog = new FilterRulesDialog(
6022 this, -1, feedId);
6023
6024 QModelIndex index = feedsModel_->indexById(feedId);
6025 QString text = feedsModel_->dataField(index, "text").toString();
6026 filterRulesDialog->filterName_->setText(QString("'%1'").arg(text));
6027
6028 int result = filterRulesDialog->exec();
6029 if (result == QDialog::Rejected) {
6030 delete filterRulesDialog;
6031 return;
6032 }
6033
6034 delete filterRulesDialog;
6035
6036 showNewsFiltersDlg(true);
6037 }
6038 // ----------------------------------------------------------------------------
slotUpdateAppCheck()6039 void MainWindow::slotUpdateAppCheck()
6040 {
6041 updateAppDialog_ = new UpdateAppDialog(mainApp->language(), this, false);
6042 connect(updateAppDialog_, SIGNAL(signalNewVersion(QString)),
6043 this, SLOT(slotNewVersion(QString)), Qt::QueuedConnection);
6044 }
6045 // ----------------------------------------------------------------------------
slotNewVersion(const QString & newVersion)6046 void MainWindow::slotNewVersion(const QString &newVersion)
6047 {
6048 updateAppDialog_->disconnectObjects();
6049 delete updateAppDialog_;
6050 updateAppDialog_ = NULL;
6051
6052 if (!newVersion.isEmpty()) {
6053 traySystem->showMessage(tr("Check for updates"),
6054 tr("A new version of QuiteRSS..."));
6055 connect(traySystem, SIGNAL(messageClicked()),
6056 this, SLOT(slotShowUpdateAppDlg()));
6057 }
6058 }
6059
6060 /** @brief Process Key_Up in feeds tree
6061 *---------------------------------------------------------------------------*/
slotFeedUpPressed()6062 void MainWindow::slotFeedUpPressed()
6063 {
6064 QModelIndex indexBefore = feedsView_->currentIndex();
6065 QModelIndex indexAfter;
6066
6067 // Jump to bottom in case of the most top index
6068 if (!indexBefore.isValid())
6069 indexAfter = feedsProxyModel_->index(feedsProxyModel_->rowCount()-1, "text");
6070 else
6071 indexAfter = feedsView_->indexAbove(indexBefore);
6072
6073 // There is no "upper" index
6074 if (!indexAfter.isValid()) return;
6075
6076 feedsView_->setCurrentIndex(indexAfter);
6077 slotFeedClicked(indexAfter);
6078 }
6079
6080 /** @brief Process Key_Down in feeds tree
6081 *---------------------------------------------------------------------------*/
slotFeedDownPressed()6082 void MainWindow::slotFeedDownPressed()
6083 {
6084 QModelIndex indexBefore = feedsView_->currentIndex();
6085 QModelIndex indexAfter;
6086
6087 // Jump to top in case of the most bottom index
6088 if (!indexBefore.isValid())
6089 indexAfter = feedsProxyModel_->index(0, "text");
6090 else
6091 indexAfter = feedsView_->indexBelow(indexBefore);
6092
6093 // There is no "downer" index
6094 if (!indexAfter.isValid()) return;
6095
6096 feedsView_->setCurrentIndex(indexAfter);
6097 slotFeedClicked(indexAfter);
6098 }
6099
6100 /** @brief Process previous feed shortcut
6101 *---------------------------------------------------------------------------*/
slotFeedPrevious()6102 void MainWindow::slotFeedPrevious()
6103 {
6104 QModelIndex indexBefore = feedsView_->currentIndex();
6105 if (!indexBefore.isValid())
6106 indexBefore = feedsProxyModel_->index(feedsProxyModel_->rowCount()-1, feedsView_->columnIndex("text"));
6107
6108 QModelIndex indexAfter = feedsView_->indexPrevious(indexBefore);
6109
6110 // There is no "upper" index
6111 if (!indexAfter.isValid()) return;
6112 feedsView_->clearSelection();
6113
6114 feedsView_->setCurrentIndex(indexAfter);
6115 slotFeedClicked(indexAfter);
6116 }
6117
6118 /** @brief Process next feed shortcut
6119 *---------------------------------------------------------------------------*/
slotFeedNext()6120 void MainWindow::slotFeedNext()
6121 {
6122 QModelIndex indexBefore = feedsView_->currentIndex();
6123 if (!indexBefore.isValid())
6124 indexBefore = feedsProxyModel_->index(0, feedsView_->columnIndex("text"));
6125
6126 QModelIndex indexAfter = feedsView_->indexNext(indexBefore);
6127
6128 // There is no "downer" index
6129 if (!indexAfter.isValid()) return;
6130 feedsView_->clearSelection();
6131
6132 feedsView_->setCurrentIndex(indexAfter);
6133 slotFeedClicked(indexAfter);
6134 }
6135
6136 /** @brief Process Key_Home in feeds tree
6137 *---------------------------------------------------------------------------*/
slotFeedHomePressed()6138 void MainWindow::slotFeedHomePressed()
6139 {
6140 QModelIndex index = feedsProxyModel_->index(0, "text");
6141 feedsView_->setCurrentIndex(index);
6142 slotFeedClicked(index);
6143 }
6144
6145 /** @brief Process Key_End in feeds tree
6146 *---------------------------------------------------------------------------*/
slotFeedEndPressed()6147 void MainWindow::slotFeedEndPressed()
6148 {
6149 QModelIndex index = feedsProxyModel_->index(feedsProxyModel_->rowCount()-1, "text");
6150 feedsView_->setCurrentIndex(index);
6151 slotFeedClicked(index);
6152 }
6153
6154 /** @brief Process pressing PageUp-key in feeds tree
6155 *----------------------------------------------------------------------------*/
slotFeedPageUpPressed()6156 void MainWindow::slotFeedPageUpPressed()
6157 {
6158 int row = 0;
6159 QModelIndex index = feedsView_->currentIndex();
6160 if (index.isValid())
6161 row = index.row() - feedsView_->verticalScrollBar()->pageStep();
6162 if (row < 0)
6163 row = 0;
6164 index = feedsProxyModel_->index(row, "text");
6165
6166 feedsView_->setCurrentIndex(index);
6167 slotFeedClicked(index);
6168 }
6169
6170 /** @brief Process pressing PageDown-key in feeds tree
6171 *----------------------------------------------------------------------------*/
slotFeedPageDownPressed()6172 void MainWindow::slotFeedPageDownPressed()
6173 {
6174 int row = 0;
6175 QModelIndex index = feedsView_->currentIndex();
6176 if (index.isValid())
6177 row = index.row() + feedsView_->verticalScrollBar()->pageStep();
6178 if (row >= feedsProxyModel_->rowCount())
6179 row = feedsProxyModel_->rowCount()-1;
6180 index = feedsProxyModel_->index(row, "text");
6181
6182 feedsView_->setCurrentIndex(index);
6183 slotFeedClicked(index);
6184 }
6185
6186 /** @brief Set application style
6187 *---------------------------------------------------------------------------*/
setStyleApp(QAction * pAct)6188 void MainWindow::setStyleApp(QAction *pAct)
6189 {
6190 Settings settings;
6191
6192 settings.setValue("Settings/styleApplication", pAct->objectName());
6193
6194 QString fileName(mainApp->resourcesDir());
6195 if (pAct->objectName() == "systemStyle_") {
6196 fileName.append("/style/system.qss");
6197 } else if (pAct->objectName() == "system2Style_") {
6198 fileName.append("/style/system2.qss");
6199 } else if (pAct->objectName() == "darkStyle_") {
6200 fileName.append("/style/dark.qss");
6201 } else if (pAct->objectName() == "orangeStyle_") {
6202 fileName.append("/style/orange.qss");
6203 } else if (pAct->objectName() == "purpleStyle_") {
6204 fileName.append("/style/purple.qss");
6205 } else if (pAct->objectName() == "pinkStyle_") {
6206 fileName.append("/style/pink.qss");
6207 } else if (pAct->objectName() == "grayStyle_") {
6208 fileName.append("/style/gray.qss");
6209 } else {
6210 fileName.append("/style/green.qss");
6211 }
6212
6213 QString userStyleBrowser = "";
6214 if (pAct->objectName() == "darkStyle_") {
6215 userStyleBrowser = mainApp->styleSheetWebDarkFile();
6216 feedsModel_->textColor_ = "#e1e0e1";
6217 newsListTextColor_ = "#e1e0e1";
6218 newsListBackgroundColor_ = "#464546";
6219 newNewsTextColor_ = "#e1e0e1";
6220 unreadNewsTextColor_ = "#e1e0e1";
6221 newsBackgroundColor_ = "#464546";
6222 newsTitleBackgroundColor_ = "#464546";
6223 titleColor_ = "#e1e0e1";
6224 newsTextColor_ = "#e1e0e1";
6225 dateColor_ = "#a5a5a5";
6226 authorColor_ = "#a5a5a5";
6227 notifierTextColor_ = "#e1e0e1";
6228 notifierBackgroundColor_ = "#464546";
6229 transparencyNotify_ = 40;
6230 alternatingRowColors_ = "#3a393a";
6231 } else {
6232 QString windowTextColor = qApp->palette().brush(QPalette::WindowText).color().name();
6233 feedsModel_->textColor_ = windowTextColor;
6234 newsListTextColor_ = windowTextColor;
6235 newsListBackgroundColor_ = "";
6236 newNewsTextColor_ = windowTextColor;
6237 unreadNewsTextColor_ = windowTextColor;
6238 newsBackgroundColor_ = "#FFFFFF";
6239 newsTitleBackgroundColor_ = "#FFFFFF";
6240 titleColor_ = "#0066CC";
6241 newsTextColor_ = "#000000";
6242 dateColor_ = "#666666";
6243 authorColor_ = "#666666";
6244 notifierTextColor_ = windowTextColor;
6245 notifierBackgroundColor_ = "#FFFFFF";
6246 transparencyNotify_ = 60;
6247 alternatingRowColors_ = qApp->palette().color(QPalette::AlternateBase).name();
6248 }
6249
6250 settings.beginGroup("Settings");
6251 settings.setValue("userStyleBrowser", userStyleBrowser);
6252 settings.setValue("transparencyNotify", transparencyNotify_);
6253 settings.endGroup();
6254 settings.beginGroup("Color");
6255 settings.setValue("feedsListTextColor", feedsModel_->textColor_);
6256 settings.setValue("newsListTextColor", newsListTextColor_);
6257 settings.setValue("newsListBackgroundColor", newsListBackgroundColor_);
6258 settings.setValue("newNewsTextColor", newNewsTextColor_);
6259 settings.setValue("unreadNewsTextColor", unreadNewsTextColor_);
6260 settings.setValue("titleColor", titleColor_);
6261 settings.setValue("newsTextColor", newsTextColor_);
6262 settings.setValue("newsTitleBackgroundColor", newsTitleBackgroundColor_);
6263 settings.setValue("newsBackgroundColor", newsBackgroundColor_);
6264 settings.setValue("dateColor", dateColor_);
6265 settings.setValue("authorColor", authorColor_);
6266 settings.setValue("notifierTextColor", notifierTextColor_);
6267 settings.setValue("notifierBackgroundColor", notifierBackgroundColor_);
6268 settings.setValue("alternatingRowColors", alternatingRowColors_);
6269 settings.endGroup();
6270
6271 QFile file(fileName);
6272 if (!file.open(QFile::ReadOnly)) {
6273 file.setFileName(":/style/systemStyle");
6274 file.open(QFile::ReadOnly);
6275 }
6276 qApp->setStyleSheet(QLatin1String(file.readAll()));
6277 file.close();
6278
6279 mainSplitter_->setStyleSheet(
6280 QString("QSplitter::handle {background: qlineargradient("
6281 "x1: 0, y1: 0, x2: 0, y2: 1,"
6282 "stop: 0 %1, stop: 0.07 %2);}").
6283 arg(feedsPanel_->palette().background().color().name()).
6284 arg(qApp->palette().color(QPalette::Dark).name()));
6285
6286 mainApp->reloadUserStyleBrowser();
6287 if (currentNewsTab != NULL) {
6288 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb)
6289 currentNewsTab->newsHeader_->saveStateColumns(currentNewsTab);
6290 currentNewsTab->setSettings(false);
6291 }
6292 }
6293
6294 /** Switch focus forward between feed tree, news list and browser
6295 *---------------------------------------------------------------------------*/
slotSwitchFocus()6296 void MainWindow::slotSwitchFocus()
6297 {
6298 if (feedsView_->hasFocus()) {
6299 newsView_->setFocus();
6300 } else if (newsView_->hasFocus()) {
6301 currentNewsTab->webView_->setFocus();
6302 } else {
6303 feedsView_->setFocus();
6304 }
6305 }
6306
6307 /** @brief Switch focus backward between feed tree, news list and browser
6308 *---------------------------------------------------------------------------*/
slotSwitchPrevFocus()6309 void MainWindow::slotSwitchPrevFocus()
6310 {
6311 if (feedsView_->hasFocus()) {
6312 currentNewsTab->webView_->setFocus();
6313 } else if (currentNewsTab->webView_->hasFocus()) {
6314 newsView_->setFocus();
6315 } else {
6316 feedsView_->setFocus();
6317 }
6318 }
6319
6320 /** @brief Open feed in a new tab
6321 *---------------------------------------------------------------------------*/
slotOpenFeedNewTab()6322 void MainWindow::slotOpenFeedNewTab()
6323 {
6324 if (stackedWidget_->count() && currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
6325 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_, FeedReadSwitchingTab, currentNewsTab);
6326 currentNewsTab->newsHeader_->saveStateColumns(currentNewsTab);
6327 Settings settings;
6328 settings.setValue("NewsTabSplitterState", currentNewsTab->newsTabWidgetSplitter_->saveState());
6329 }
6330
6331 QModelIndexList indexList = feedsView_->selectionModel()->selectedRows(0);
6332 if (indexList.count() <= 1) {
6333 indexList.clear();
6334 indexList.append(feedsProxyModel_->mapFromSource(feedsView_->selectIndex()));
6335 }
6336 QModelIndex index = indexList.takeFirst();
6337 feedsView_->selectIdEn_ = false;
6338 feedsView_->setCurrentIndex(index);
6339 slotFeedSelected(feedsProxyModel_->mapToSource(index), true);
6340
6341 foreach (QModelIndex indexProxy, indexList) {
6342 QModelIndex index = feedsProxyModel_->mapToSource(indexProxy);
6343 creatFeedTab(feedsModel_->dataField(index, "id").toInt(),
6344 feedsModel_->dataField(index, "parentId").toInt());
6345 }
6346 }
6347
slotOpenCategoryNewTab()6348 void MainWindow::slotOpenCategoryNewTab()
6349 {
6350 slotCategoriesClicked(categoriesTree_->currentItem(), 0, true);
6351 }
6352
6353 /** @brief Close tab with \a index
6354 *---------------------------------------------------------------------------*/
slotCloseTab(int index)6355 void MainWindow::slotCloseTab(int index)
6356 {
6357 if (index != 0) {
6358 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(index);
6359
6360 setFeedRead(widget->type_, widget->feedId_, FeedReadClosingTab, widget);
6361
6362 stackedWidget_->removeWidget(widget);
6363 tabBar_->removeTab(index);
6364 widget->disconnectObjects();
6365 widget->newsTitleLabel_->deleteLater();
6366 widget->deleteLater();
6367 }
6368 }
6369
6370 /** @brief Switch to tab with index \a index
6371 *---------------------------------------------------------------------------*/
slotTabCurrentChanged(int index)6372 void MainWindow::slotTabCurrentChanged(int index)
6373 {
6374 if (!stackedWidget_->count()) return;
6375 if (tabBar_->closingTabState_ == TabBar::CloseTabOtherIndex) return;
6376
6377 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(index);
6378
6379 if ((widget->type_ == NewsTabWidget::TabTypeFeed) || (widget->type_ >= NewsTabWidget::TabTypeWeb))
6380 categoriesTree_->setCurrentIndex(QModelIndex());
6381 if (widget->type_ != NewsTabWidget::TabTypeFeed) {
6382 feedsView_->setCurrentIndex(QModelIndex());
6383 feedProperties_->setEnabled(false);
6384 }
6385
6386 if (index == TAB_WIDGET_PERMANENT) {
6387 feedsWidgetVisibleAct_->setChecked(showFeedsTabPermanent_);
6388 slotVisibledFeedsWidget();
6389 } else {
6390 if (hideFeedsOpenTab_) {
6391 feedsWidgetVisibleAct_->setChecked(false);
6392 slotVisibledFeedsWidget();
6393 }
6394 }
6395
6396 stackedWidget_->setCurrentIndex(index);
6397
6398 if (!updateCurrentTab_) return;
6399
6400 if ((tabBar_->closingTabState_ == TabBar::CloseTabIdle) && (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb)) {
6401 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_, FeedReadSwitchingTab, currentNewsTab);
6402
6403 currentNewsTab->newsHeader_->saveStateColumns(currentNewsTab);
6404 Settings settings;
6405 settings.setValue("NewsTabSplitterState", currentNewsTab->newsTabWidgetSplitter_->saveState());
6406 }
6407
6408 if (widget->type_ == NewsTabWidget::TabTypeFeed) {
6409 if (widget->feedId_ == 0)
6410 widget->hide();
6411 currentNewsTab = (NewsTabWidget*)stackedWidget_->widget(index);
6412 currentNewsTab->setSettings(false);
6413 currentNewsTab->retranslateStrings();
6414 currentNewsTab->setBrowserPosition();
6415
6416 newsModel_ = currentNewsTab->newsModel_;
6417 newsView_ = currentNewsTab->newsView_;
6418
6419 QModelIndex feedIndex = feedsProxyModel_->mapFromSource(feedsModel_->indexById(widget->feedId_));
6420 feedsView_->setCurrentIndex(feedIndex);
6421 feedProperties_->setEnabled(feedIndex.isValid());
6422
6423 setFeedsFilter(false);
6424
6425 slotUpdateNews(NewsTabWidget::RefreshWithPos);
6426 if (widget->isVisible())
6427 newsView_->setFocus();
6428 else
6429 feedsView_->setFocus();
6430
6431 statusUnread_->setVisible(widget->feedId_);
6432 statusAll_->setVisible(widget->feedId_);
6433 } else if (widget->type_ == NewsTabWidget::TabTypeWeb) {
6434 statusUnread_->setVisible(false);
6435 statusAll_->setVisible(false);
6436 currentNewsTab = widget;
6437 currentNewsTab->setSettings(false);
6438 currentNewsTab->retranslateStrings();
6439 currentNewsTab->webView_->setFocus();
6440 } else if (widget->type_ == NewsTabWidget::TabTypeDownloads) {
6441 statusUnread_->setVisible(false);
6442 statusAll_->setVisible(false);
6443 mainApp->downloadManager()->show();
6444 currentNewsTab = widget;
6445 currentNewsTab->retranslateStrings();
6446 } else {
6447 QList<QTreeWidgetItem *> treeItems;
6448 if (widget->type_ == NewsTabWidget::TabTypeLabel) {
6449 treeItems = categoriesTree_->findItems(QString::number(widget->labelId_),
6450 Qt::MatchFixedString|Qt::MatchRecursive,
6451 2);
6452 } else {
6453 treeItems = categoriesTree_->findItems(QString::number(widget->type_),
6454 Qt::MatchFixedString,
6455 1);
6456 }
6457 categoriesTree_->setCurrentItem(treeItems.at(0));
6458
6459 currentNewsTab = (NewsTabWidget*)stackedWidget_->widget(index);
6460 currentNewsTab->setSettings(false);
6461 currentNewsTab->retranslateStrings();
6462 currentNewsTab->setBrowserPosition();
6463
6464 newsModel_ = currentNewsTab->newsModel_;
6465 newsView_ = currentNewsTab->newsView_;
6466
6467 slotUpdateNews(NewsTabWidget::RefreshWithPos);
6468 newsView_->setFocus();
6469
6470 int unreadCount = widget->getUnreadCount(categoriesTree_->currentItem()->text(4));
6471 int allCount = widget->newsModel_->rowCount();
6472 statusUnread_->setText(QString(" " + tr("Unread: %1") + " ").arg(unreadCount));
6473 statusAll_->setText(QString(" " + tr("All: %1") + " ").arg(allCount));
6474
6475 statusUnread_->setVisible(widget->type_ != NewsTabWidget::TabTypeDel);
6476 statusAll_->setVisible(true);
6477 }
6478
6479 setTextTitle(widget->newsTitleLabel_->toolTip(), widget);
6480 }
6481
6482 /** @brief Process tab moving
6483 *----------------------------------------------------------------------------*/
slotTabMoved(int fromIndex,int toIndex)6484 void MainWindow::slotTabMoved(int fromIndex, int toIndex)
6485 {
6486 stackedWidget_->insertWidget(toIndex, stackedWidget_->widget(fromIndex));
6487 }
6488
6489 /** @brief Manage displaying columns in feed tree
6490 *---------------------------------------------------------------------------*/
feedsColumnVisible(QAction * action)6491 void MainWindow::feedsColumnVisible(QAction *action)
6492 {
6493 int idx = action->data().toInt();
6494 if (action->isChecked())
6495 feedsView_->showColumn(idx);
6496 else
6497 feedsView_->hideColumn(idx);
6498 }
6499
setNewsLayout(QAction * action)6500 void MainWindow::setNewsLayout(QAction *action)
6501 {
6502 newsLayout_ = action->data().toInt();
6503 switch (newsLayout_) {
6504 case 1:
6505 layoutToggle_->setIcon(QIcon(":/images/layout_newspaper"));
6506 break;
6507 default:
6508 layoutToggle_->setIcon(QIcon(":/images/layout_classic"));
6509 }
6510 currentNewsTab->setNewsLayout();
6511 }
6512
setNewsLayout()6513 void MainWindow::setNewsLayout()
6514 {
6515 if ((newsLayout_ + 1) >= layoutGroup_->actions().count())
6516 layoutGroup_->actions().at(0)->setChecked(true);
6517 else
6518 layoutGroup_->actions().at(newsLayout_ + 1)->setChecked(true);
6519 setNewsLayout(layoutGroup_->checkedAction());
6520 }
6521
6522 /** @brief Set browser position
6523 *---------------------------------------------------------------------------*/
setBrowserPosition(QAction * action)6524 void MainWindow::setBrowserPosition(QAction *action)
6525 {
6526 browserPosition_ = action->data().toInt();
6527 currentNewsTab->setBrowserPosition();
6528 }
6529
6530 /** @brief Create tab with browser only (without news list)
6531 *---------------------------------------------------------------------------*/
createWebTab(QUrl url)6532 QWebPage *MainWindow::createWebTab(QUrl url)
6533 {
6534 NewsTabWidget *widget = new NewsTabWidget(this, NewsTabWidget::TabTypeWeb);
6535 int indexTab = addTab(widget);
6536 widget->setTextTab(tr("Loading..."));
6537
6538 if (openNewsTab_ == NEW_TAB_FOREGROUND) {
6539 currentNewsTab = widget;
6540 emit signalSetCurrentTab(indexTab);
6541 }
6542
6543 widget->setSettings();
6544 widget->retranslateStrings();
6545
6546 openNewsTab_ = 0;
6547
6548 if (!url.isEmpty()) {
6549 widget->locationBar_->setText(url.toString());
6550 widget->webView_->load(url);
6551 }
6552
6553 return widget->webView_->page();
6554 }
6555 // ----------------------------------------------------------------------------
creatFeedTab(int feedId,int feedParId)6556 void MainWindow::creatFeedTab(int feedId, int feedParId)
6557 {
6558 QSqlQuery q;
6559 q.exec(QString("SELECT text, image, currentNews, xmlUrl FROM feeds WHERE id=='%1'").
6560 arg(feedId));
6561
6562 if (q.next()) {
6563 NewsTabWidget *widget = new NewsTabWidget(this, NewsTabWidget::TabTypeFeed, feedId, feedParId);
6564 addTab(widget);
6565 widget->setSettings();
6566 widget->retranslateStrings();
6567 widget->setBrowserPosition();
6568
6569 bool isFeed = true;
6570 if (q.value(3).toString().isEmpty())
6571 isFeed = false;
6572
6573 // Set icon and title for tab
6574 QPixmap iconTab;
6575 QByteArray byteArray = q.value(1).toByteArray();
6576 if (!isFeed) {
6577 iconTab.load(":/images/folder");
6578 } else {
6579 if (byteArray.isNull() || defaultIconFeeds_) {
6580 iconTab.load(":/images/feed");
6581 } else if (isFeed) {
6582 iconTab.loadFromData(QByteArray::fromBase64(byteArray));
6583 }
6584 }
6585 widget->newsIconTitle_->setPixmap(iconTab);
6586 widget->setTextTab(q.value(0).toString());
6587
6588 QString feedIdFilter;
6589 if (feedsModel_->isFolder(feedsModel_->indexById(feedId))) {
6590 feedIdFilter = QString("(%1) AND ").arg(getIdFeedsString(feedId));
6591 } else {
6592 feedIdFilter = QString("feedId=%1 AND ").arg(feedId);
6593 }
6594
6595 if (newsFilterGroup_->checkedAction()->objectName() == "filterNewsAll_") {
6596 feedIdFilter.append("deleted = 0");
6597 } else if (newsFilterGroup_->checkedAction()->objectName() == "filterNewsNew_") {
6598 feedIdFilter.append(QString("new = 1 AND deleted = 0"));
6599 } else if (newsFilterGroup_->checkedAction()->objectName() == "filterNewsUnread_") {
6600 feedIdFilter.append(QString("read < 2 AND deleted = 0"));
6601 } else if (newsFilterGroup_->checkedAction()->objectName() == "filterNewsStar_") {
6602 feedIdFilter.append(QString("starred = 1 AND deleted = 0"));
6603 } else if (newsFilterGroup_->checkedAction()->objectName() == "filterNewsNotStarred_") {
6604 feedIdFilter.append(QString("starred = 0 AND deleted = 0"));
6605 } else if (newsFilterGroup_->checkedAction()->objectName() == "filterNewsUnreadStar_") {
6606 feedIdFilter.append(QString("(read < 2 OR starred = 1) AND deleted = 0"));
6607 } else if (newsFilterGroup_->checkedAction()->objectName() == "filterNewsLastDay_") {
6608 feedIdFilter.append(QString("(published >= datetime('now', '-1 day')) AND deleted = 0"));
6609 } else if (newsFilterGroup_->checkedAction()->objectName() == "filterNewsLastWeek_") {
6610 feedIdFilter.append(QString("(published >= datetime('now', '-7 day')) AND deleted = 0"));
6611 }
6612 widget->newsModel_->setFilter(feedIdFilter);
6613
6614 if (widget->newsModel_->rowCount() != 0) {
6615 while (widget->newsModel_->canFetchMore())
6616 widget->newsModel_->fetchMore();
6617 }
6618
6619 currentNewsTab->loadNewspaper();
6620
6621 // focus feed has displayed before
6622 int newsRow = -1;
6623 int newsId = widget->newsModel_->index(newsRow, widget->newsModel_->fieldIndex("id")).data(Qt::EditRole).toInt();
6624 if (openingFeedAction_ == 0) {
6625 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("id"));
6626 QModelIndexList indexList = newsModel_->match(index, Qt::EditRole, newsId);
6627 if (indexList.count()) newsRow = indexList.first().row();
6628 } else if (openingFeedAction_ == 1) newsRow = 0;
6629
6630 widget->newsView_->setCurrentIndex(widget->newsModel_->index(newsRow, widget->newsModel_->fieldIndex("title")));
6631 if (newsRow == -1) widget->newsView_->verticalScrollBar()->setValue(newsRow);
6632
6633 if ((openingFeedAction_ < 2) && openNewsWebViewOn_) {
6634 widget->slotNewsViewSelected(widget->newsModel_->index(newsRow, widget->newsModel_->fieldIndex("title")));
6635 } else {
6636 widget->slotNewsViewSelected(widget->newsModel_->index(-1, widget->newsModel_->fieldIndex("title")));
6637 QSqlQuery q;
6638 QString qStr = QString("UPDATE feeds SET currentNews='%1' WHERE id=='%2'").
6639 arg(newsId).arg(feedId);
6640 q.exec(qStr);
6641 }
6642 }
6643 }
6644
6645 /** @brief Open news using Enter key
6646 *---------------------------------------------------------------------------*/
slotOpenNewsWebView()6647 void MainWindow::slotOpenNewsWebView()
6648 {
6649 if (!newsView_->hasFocus()) return;
6650 currentNewsTab->slotNewsViewSelected(newsView_->currentIndex());
6651 }
6652 // ----------------------------------------------------------------------------
slotNewsUpPressed()6653 void MainWindow::slotNewsUpPressed()
6654 {
6655 currentNewsTab->slotNewsUpPressed();
6656 }
6657 // ----------------------------------------------------------------------------
slotNewsDownPressed()6658 void MainWindow::slotNewsDownPressed()
6659 {
6660 currentNewsTab->slotNewsDownPressed();
6661 }
6662 // ----------------------------------------------------------------------------
slotNewsPageUpPressed()6663 void MainWindow::slotNewsPageUpPressed()
6664 {
6665 currentNewsTab->slotNewsPageUpPressed();
6666 }
6667 // ----------------------------------------------------------------------------
slotNewsPageDownPressed()6668 void MainWindow::slotNewsPageDownPressed()
6669 {
6670 currentNewsTab->slotNewsPageDownPressed();
6671 }
6672 // ----------------------------------------------------------------------------
markNewsRead()6673 void MainWindow::markNewsRead()
6674 {
6675 currentNewsTab->markNewsRead();
6676 }
6677 // ----------------------------------------------------------------------------
markAllNewsRead()6678 void MainWindow::markAllNewsRead()
6679 {
6680 currentNewsTab->markAllNewsRead();
6681 }
6682 // ----------------------------------------------------------------------------
markNewsStar()6683 void MainWindow::markNewsStar()
6684 {
6685 currentNewsTab->markNewsStar();
6686 }
6687 // ----------------------------------------------------------------------------
deleteNews()6688 void MainWindow::deleteNews()
6689 {
6690 currentNewsTab->deleteNews();
6691 }
6692 // ----------------------------------------------------------------------------
deleteAllNewsList()6693 void MainWindow::deleteAllNewsList()
6694 {
6695 currentNewsTab->deleteAllNewsList();
6696 }
6697 // ----------------------------------------------------------------------------
restoreNews()6698 void MainWindow::restoreNews()
6699 {
6700 currentNewsTab->restoreNews();
6701 }
6702 // ----------------------------------------------------------------------------
openInBrowserNews()6703 void MainWindow::openInBrowserNews()
6704 {
6705 currentNewsTab->openInBrowserNews();
6706 }
6707 // ----------------------------------------------------------------------------
openInExternalBrowserNews()6708 void MainWindow::openInExternalBrowserNews()
6709 {
6710 currentNewsTab->openInExternalBrowserNews();
6711 }
6712 // ----------------------------------------------------------------------------
slotOpenNewsNewTab()6713 void MainWindow::slotOpenNewsNewTab()
6714 {
6715 openNewsTab_ = NEW_TAB_FOREGROUND;
6716 currentNewsTab->openNewsNewTab();
6717 }
6718 // ----------------------------------------------------------------------------
slotOpenNewsBackgroundTab()6719 void MainWindow::slotOpenNewsBackgroundTab()
6720 {
6721 openNewsTab_ = NEW_TAB_BACKGROUND;
6722 currentNewsTab->openNewsNewTab();
6723 }
6724
6725 /** @brief Copy news URL-link
6726 *----------------------------------------------------------------------------*/
slotCopyLinkNews()6727 void MainWindow::slotCopyLinkNews()
6728 {
6729 currentNewsTab->slotCopyLinkNews();
6730 }
6731
slotShowLabelsMenu()6732 void MainWindow::slotShowLabelsMenu()
6733 {
6734 currentNewsTab->showLabelsMenu();
6735 }
6736 // ----------------------------------------------------------------------------
slotPageUpWebView()6737 void MainWindow::slotPageUpWebView()
6738 {
6739 QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_PageUp, Qt::NoModifier);
6740 QApplication::sendEvent(currentNewsTab->webView_->page(), &keyEvent);
6741 }
6742
slotPageDownWebView()6743 void MainWindow::slotPageDownWebView()
6744 {
6745 QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_PageDown, Qt::NoModifier);
6746 QApplication::sendEvent(currentNewsTab->webView_->page(), &keyEvent);
6747 }
6748 /** @brief Reload full model
6749 * @details Performs: reload model, reset proxy model, restore focus
6750 *---------------------------------------------------------------------------*/
feedsModelReload(bool checkFilter)6751 void MainWindow::feedsModelReload(bool checkFilter)
6752 {
6753 if (checkFilter) {
6754 if (feedsFilterGroup_->checkedAction()->objectName() != "filterFeedsAll_") {
6755 setFeedsFilter(false);
6756 }
6757 slotFeedsViewportUpdate();
6758 return;
6759 }
6760
6761 int topRow = feedsView_->verticalScrollBar()->value();
6762 QModelIndex feedIndex = feedsProxyModel_->mapToSource(feedsView_->currentIndex());
6763 int feedId = feedsModel_->idByIndex(feedIndex);
6764
6765 feedsView_->refresh();
6766
6767 feedIndex = feedsProxyModel_->mapFromSource(feedId);
6768 feedsView_->selectIdEn_ = false;
6769 feedsView_->setCurrentIndex(feedIndex);
6770 feedsView_->verticalScrollBar()->setValue(topRow);
6771 }
6772 // ----------------------------------------------------------------------------
setCurrentTab(int index,bool updateCurrentTab)6773 void MainWindow::setCurrentTab(int index, bool updateCurrentTab)
6774 {
6775 updateCurrentTab_ = updateCurrentTab;
6776 tabBar_->setCurrentIndex(index);
6777 updateCurrentTab_ = true;
6778 }
6779
6780 /** @brief Set focus to search field (CTRL+F)
6781 *---------------------------------------------------------------------------*/
findText()6782 void MainWindow::findText()
6783 {
6784 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
6785 if (!currentNewsTab->findText_->hasFocus())
6786 currentNewsTab->findText_->setFocus();
6787 else
6788 newsView_->setFocus();
6789 }
6790 }
6791
6792 /** @brief Show notification on inbox news
6793 *---------------------------------------------------------------------------*/
showNotification(bool bShowRecentNews)6794 void MainWindow::showNotification(bool bShowRecentNews/*=false*/)
6795 {
6796 Settings settings;
6797 settings.setValue("Flags/updatingFeeds", false);
6798
6799 bool showNotify = true;
6800
6801 if (showNotifyInactiveApp_)
6802 {
6803 showNotify = !isActiveWindow();
6804 }
6805
6806 NewNewsData& curNews = (bShowRecentNews ? recentNews : newNews);
6807
6808 if (curNews.idFeedList_.isEmpty() || !showNotify || !showNotifyOn_)
6809 {
6810 clearNotification();
6811 return;
6812 }
6813
6814 if (fullscreenModeNotify_) {
6815 #if defined(Q_OS_WIN)
6816 HWND hWnd = GetForegroundWindow();
6817 RECT appBounds;
6818 RECT rc;
6819 GetWindowRect(GetDesktopWindow(), &rc);
6820
6821 if ((hWnd != GetDesktopWindow())
6822 #ifdef HAVE_QT5
6823 && (hWnd != GetShellWindow())
6824 #endif
6825 ) {
6826 GetWindowRect(hWnd, &appBounds);
6827 if ((rc.top == appBounds.top) && (rc.bottom == appBounds.bottom) &&
6828 (rc.left == appBounds.left) && (rc.right == appBounds.right)) {
6829 return;
6830 }
6831 }
6832 #endif
6833 }
6834
6835 timerTrayOpenNotify.stop();
6836
6837
6838 if (notificationWidget != NULL)
6839 {
6840 delete notificationWidget;
6841 }
6842
6843 notificationWidget = new NotificationWidget(curNews.idFeedList_, curNews.cntNewsList_,
6844 idColorList_, colorList_, this);
6845
6846 if (!bShowRecentNews)
6847 {
6848 clearNotification();
6849 }
6850
6851 connect(notificationWidget, SIGNAL(signalShow()), this, SLOT(showWindows()));
6852 connect(notificationWidget, SIGNAL(signalClose()),
6853 this, SLOT(deleteNotification()));
6854 connect(notificationWidget, SIGNAL(signalOpenNews(int, int)),
6855 this, SLOT(slotOpenNew(int, int)));
6856 connect(notificationWidget, SIGNAL(signalOpenExternalBrowser(QUrl)),
6857 this, SLOT(slotOpenNewBrowser(QUrl)));
6858 connect(notificationWidget, SIGNAL(signalMarkRead(int,int,int)),
6859 this, SLOT(slotMarkReadNewsInNotification(int,int,int)));
6860 connect(notificationWidget, SIGNAL(signalDeleteNews(int,int)),
6861 this, SLOT(slotDeleteNewsInNotification(int,int)));
6862 connect(notificationWidget, SIGNAL(signalMarkAllRead()),
6863 this, SLOT(slotMarkAllReadNewsInNotification()));
6864
6865 notificationWidget->show();
6866 }
6867
6868 /** @brief Delete notification widget
6869 *---------------------------------------------------------------------------*/
deleteNotification()6870 void MainWindow::deleteNotification()
6871 {
6872 notificationWidget->deleteLater();
6873 notificationWidget = NULL;
6874 }
6875
clearNotification(bool bClearRecentNews)6876 void MainWindow::clearNotification(bool bClearRecentNews/*=false*/)
6877 {
6878 newNews.idFeedList_.clear();
6879 newNews.cntNewsList_.clear();
6880
6881 if (bClearRecentNews)
6882 {
6883 recentNews.idFeedList_.clear();
6884 recentNews.cntNewsList_.clear();
6885
6886 idColorList_.clear();
6887 colorList_.clear();
6888 }
6889 }
6890
slotAddColorList(int id,const QString & color)6891 void MainWindow::slotAddColorList(int id, const QString &color)
6892 {
6893 if (idColorList_.indexOf(id) == -1)
6894 {
6895 idColorList_.append(id);
6896 colorList_.append(color);
6897 }
6898 }
6899
6900 /** @brief Show news on click in notification window
6901 *---------------------------------------------------------------------------*/
slotOpenNew(int feedId,int newsId)6902 void MainWindow::slotOpenNew(int feedId, int newsId)
6903 {
6904 openingFeedAction_ = 0;
6905 openNewsWebViewOn_ = true;
6906
6907 QSqlQuery q;
6908 q.exec(QString("UPDATE feeds SET currentNews='%1' WHERE id=='%2'").arg(newsId).arg(feedId));
6909
6910 QModelIndex feedIndex = feedsModel_->indexById(feedId);
6911 feedsView_->setCurrentIndex(feedsProxyModel_->mapFromSource(feedIndex));
6912 feedsModel_->setData(feedsModel_->indexSibling(feedIndex, "currentNews"),
6913 newsId);
6914
6915 if (stackedWidget_->count() && currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
6916 currentNewsTab->newsHeader_->saveStateColumns(currentNewsTab);
6917 }
6918
6919 // Search open tab containing this feed
6920 int indexTab = -1;
6921 for (int i = 0; i < stackedWidget_->count(); i++) {
6922 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
6923 if (widget->feedId_ == feedId) {
6924 indexTab = i;
6925 break;
6926 }
6927 }
6928
6929 if (indexTab == -1) {
6930 if (tabBar_->currentIndex() != TAB_WIDGET_PERMANENT) {
6931 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_, FeedReadSwitchingTab, currentNewsTab);
6932
6933 updateCurrentTab_ = false;
6934 tabBar_->setCurrentIndex(TAB_WIDGET_PERMANENT);
6935 updateCurrentTab_ = true;
6936
6937 currentNewsTab = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
6938 newsModel_ = currentNewsTab->newsModel_;
6939 newsView_ = currentNewsTab->newsView_;
6940 } else {
6941 if (stackedWidget_->count() && currentNewsTab->type_ != NewsTabWidget::TabTypeFeed) {
6942 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_, FeedReadSwitchingFeed, currentNewsTab);
6943 } else {
6944 // Mark previous feed Read while switching to another feed
6945 setFeedRead(NewsTabWidget::TabTypeFeed, feedIdOld_, FeedReadSwitchingFeed, 0, feedId);
6946 }
6947
6948 categoriesTree_->setCurrentIndex(QModelIndex());
6949 }
6950 } else {
6951 tabBar_->setCurrentIndex(indexTab);
6952 }
6953 slotFeedSelected(feedIndex);
6954 feedsView_->repaint();
6955 feedIdOld_ = feedId;
6956
6957 Settings settings;
6958 openingFeedAction_ = settings.value("/Settings/openingFeedAction", 0).toInt();
6959 openNewsWebViewOn_ = settings.value("/Settings/openNewsWebViewOn", true).toBool();
6960 showWindows();
6961 newsView_->setFocus();
6962 }
6963
6964 /** @brief Open news in external browser on click in notification window
6965 *---------------------------------------------------------------------------*/
slotOpenNewBrowser(const QUrl & url)6966 void MainWindow::slotOpenNewBrowser(const QUrl &url)
6967 {
6968 currentNewsTab->openUrl(url);
6969 }
6970
slotMarkReadNewsInNotification(int feedId,int newsId,int read)6971 void MainWindow::slotMarkReadNewsInNotification(int feedId, int newsId, int read)
6972 {
6973 QSqlQuery q;
6974 bool showNews = false;
6975 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
6976 int cnt = newsModel_->rowCount();
6977 for (int i = 0; i < cnt; ++i) {
6978 if (newsId == newsModel_->index(i, newsModel_->fieldIndex("id")).data().toInt()) {
6979 if (read == 1) {
6980 if (newsModel_->index(i, newsModel_->fieldIndex("new")).data(Qt::EditRole).toInt() == 1) {
6981 newsModel_->setData(
6982 newsModel_->index(i, newsModel_->fieldIndex("new")),
6983 0);
6984 q.exec(QString("UPDATE news SET new=0 WHERE id=='%1'").arg(newsId));
6985 }
6986 if (newsModel_->index(i, newsModel_->fieldIndex("read")).data(Qt::EditRole).toInt() == 0) {
6987 newsModel_->setData(
6988 newsModel_->index(i, newsModel_->fieldIndex("read")),
6989 1);
6990 q.exec(QString("UPDATE news SET read=1 WHERE id=='%1'").arg(newsId));
6991 }
6992 } else {
6993 if (newsModel_->index(i, newsModel_->fieldIndex("read")).data(Qt::EditRole).toInt() != 0) {
6994 newsModel_->setData(
6995 newsModel_->index(i, newsModel_->fieldIndex("read")),
6996 0);
6997 q.exec(QString("UPDATE news SET read=0 WHERE id=='%1'").arg(newsId));
6998 }
6999 }
7000
7001 newsView_->viewport()->update();
7002 showNews = true;
7003 break;
7004 }
7005 }
7006 }
7007
7008 if (!showNews) {
7009 q.exec(QString("UPDATE news SET new=0, read='%1' WHERE id=='%2'").
7010 arg(read).arg(newsId));
7011 }
7012
7013 slotUpdateStatus(feedId);
7014 recountCategoryCounts();
7015 }
7016
slotDeleteNewsInNotification(int feedId,int newsId)7017 void MainWindow::slotDeleteNewsInNotification(int feedId, int newsId)
7018 {
7019 mainApp->sqlQueryExec(QString("UPDATE news SET new=0, read=2, deleted=1, deleteDate='%1' WHERE id=='%2'").
7020 arg(QDateTime::currentDateTime().toString(Qt::ISODate)).
7021 arg(newsId));
7022
7023 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
7024 for (int i = 0; i < newsModel_->rowCount(); ++i) {
7025 if (newsId == newsModel_->index(i, newsModel_->fieldIndex("id")).data().toInt()) {
7026 newsModel_->setData(newsModel_->index(i, newsModel_->fieldIndex("new")), 0);
7027 newsModel_->setData(newsModel_->index(i, newsModel_->fieldIndex("read")), 2);
7028 newsModel_->setData(newsModel_->index(i, newsModel_->fieldIndex("deleted")), 1);
7029 newsModel_->setData(newsModel_->index(i, newsModel_->fieldIndex("deleteDate")),
7030 QDateTime::currentDateTime().toString(Qt::ISODate));
7031
7032 newsModel_->submitAll();
7033
7034 while (newsModel_->canFetchMore())
7035 newsModel_->fetchMore();
7036
7037 currentNewsTab->loadNewspaper(NewsTabWidget::RefreshWithPos);
7038
7039 QModelIndex curIndex;
7040 if (i == newsModel_->rowCount())
7041 curIndex = newsModel_->index(i-1, newsModel_->fieldIndex("title"));
7042 else if (i > newsModel_->rowCount())
7043 curIndex = newsModel_->index(i-1, newsModel_->fieldIndex("title"));
7044 else
7045 curIndex = newsModel_->index(i, newsModel_->fieldIndex("title"));
7046 newsView_->setCurrentIndex(curIndex);
7047 currentNewsTab->slotNewsViewSelected(curIndex);
7048 break;
7049 }
7050 }
7051 }
7052
7053 slotUpdateStatus(feedId);
7054 recountCategoryCounts();
7055 }
7056
slotMarkAllReadNewsInNotification()7057 void MainWindow::slotMarkAllReadNewsInNotification()
7058 {
7059 if (NotificationWidget *notificationWidget = qobject_cast<NotificationWidget*>(sender())) {
7060 QList<int> idFeedList = notificationWidget->idFeedList();
7061 QList<int> idNewsList = notificationWidget->idNewsList();
7062
7063 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
7064 for (int i = 0; i < newsModel_->rowCount(); ++i) {
7065 if (idNewsList.contains(newsModel_->index(i, newsModel_->fieldIndex("id")).data().toInt())) {
7066 newsModel_->setData(
7067 newsModel_->index(i, newsModel_->fieldIndex("new")), 0);
7068 newsModel_->setData(
7069 newsModel_->index(i, newsModel_->fieldIndex("read")), 1);
7070 }
7071 }
7072 newsView_->viewport()->update();
7073 }
7074
7075 foreach (int newsId, idNewsList) {
7076 mainApp->sqlQueryExec(QString("UPDATE news SET new=0, read=1 WHERE id=='%1'").
7077 arg(newsId));
7078 }
7079
7080 foreach (int feedId, idFeedList) {
7081 slotUpdateStatus(feedId);
7082 }
7083 recountCategoryCounts();
7084 }
7085 }
7086
7087 // ----------------------------------------------------------------------------
slotFindFeeds(QString)7088 void MainWindow::slotFindFeeds(QString)
7089 {
7090 if (!findFeedsWidget_->isVisible()) return;
7091
7092 setFeedsFilter(false);
7093 }
7094 // ----------------------------------------------------------------------------
slotSelectFind()7095 void MainWindow::slotSelectFind()
7096 {
7097 slotFindFeeds(findFeeds_->text());
7098 }
7099 // ----------------------------------------------------------------------------
findFeedVisible(bool visible)7100 void MainWindow::findFeedVisible(bool visible)
7101 {
7102 findFeedsWidget_->setVisible(visible);
7103 if (visible) {
7104 findFeeds_->setFocus();
7105 } else {
7106 findFeedAct_->setChecked(false);
7107 findFeeds_->clear();
7108 // Call filter explicitly, because invisible widget don't calls it
7109 setFeedsFilter(false);
7110 }
7111 }
7112
7113 /** @brief Totally remove news
7114 *---------------------------------------------------------------------------*/
cleanUp()7115 void MainWindow::cleanUp()
7116 {
7117 CleanUpWizard *cleanUpWizard = new CleanUpWizard(this);
7118 cleanUpWizard->exec();
7119 delete cleanUpWizard;
7120 }
7121
7122 /** @brief Zooming in browser
7123 *---------------------------------------------------------------------------*/
browserZoom(QAction * action)7124 void MainWindow::browserZoom(QAction *action)
7125 {
7126 if (currentNewsTab->type_ == NewsTabWidget::TabTypeDownloads) return;
7127
7128 if (action->objectName() == "zoomInAct") {
7129 if (currentNewsTab->webView_->zoomFactor() < 5.0)
7130 currentNewsTab->webView_->setZoomFactor(currentNewsTab->webView_->zoomFactor()+0.1);
7131 } else if (action->objectName() == "zoomOutAct") {
7132 if (currentNewsTab->webView_->zoomFactor() > 0.3)
7133 currentNewsTab->webView_->setZoomFactor(currentNewsTab->webView_->zoomFactor()-0.1);
7134 } else {
7135 currentNewsTab->webView_->setZoomFactor(1);
7136 }
7137 }
7138
7139 /** @brief Call default e-mail application to report the problem
7140 *---------------------------------------------------------------------------*/
slotReportProblem()7141 void MainWindow::slotReportProblem()
7142 {
7143 QDesktopServices::openUrl(QUrl("https://github.com/QuiteRSS/quiterss/issues"));
7144 }
7145
7146 /** @brief Print browser page
7147 *---------------------------------------------------------------------------*/
slotPrint(QWebFrame * frame)7148 void MainWindow::slotPrint(QWebFrame *frame)
7149 {
7150 if (currentNewsTab->type_ == NewsTabWidget::TabTypeDownloads) return;
7151
7152 QPrinter printer;
7153 printer.setDocName(tr("Web Page"));
7154 QPrintDialog *printDlg = new QPrintDialog(&printer);
7155 if (!frame)
7156 connect(printDlg, SIGNAL(accepted(QPrinter*)), currentNewsTab->webView_, SLOT(print(QPrinter*)));
7157 else
7158 connect(printDlg, SIGNAL(accepted(QPrinter*)), frame, SLOT(print(QPrinter*)));
7159 printDlg->exec();
7160 printDlg->deleteLater();
7161 }
7162
7163 /** @brief Call print preview dialog
7164 *---------------------------------------------------------------------------*/
slotPrintPreview(QWebFrame * frame)7165 void MainWindow::slotPrintPreview(QWebFrame *frame)
7166 {
7167 if (currentNewsTab->type_ == NewsTabWidget::TabTypeDownloads) return;
7168
7169 QPrinter printer;
7170 printer.setDocName(tr("Web Page"));
7171 QPrintPreviewDialog *prevDlg = new QPrintPreviewDialog(&printer);
7172 prevDlg->setWindowFlags(prevDlg->windowFlags() | Qt::WindowMaximizeButtonHint);
7173 prevDlg->resize(650, 800);
7174 if (!frame)
7175 connect(prevDlg, SIGNAL(paintRequested(QPrinter*)), currentNewsTab->webView_, SLOT(print(QPrinter*)));
7176 else
7177 connect(prevDlg, SIGNAL(paintRequested(QPrinter*)), frame, SLOT(print(QPrinter*)));
7178 prevDlg->exec();
7179 prevDlg->deleteLater();
7180 }
7181 // ----------------------------------------------------------------------------
setFullScreen()7182 void MainWindow::setFullScreen()
7183 {
7184 if (!isFullScreen()) {
7185 // hide menu
7186 menuBar()->hide();
7187 #ifdef HAVE_X11
7188 show();
7189 raise();
7190 setWindowState(windowState() | Qt::WindowFullScreen);
7191 #else
7192 setWindowState(windowState() | Qt::WindowFullScreen);
7193 #endif
7194 } else {
7195 if (showMenuBarAct_->isChecked())
7196 menuBar()->show();
7197 setWindowState(windowState() & ~Qt::WindowFullScreen);
7198 }
7199 }
7200 // ----------------------------------------------------------------------------
setStayOnTop()7201 void MainWindow::setStayOnTop()
7202 {
7203 isMinimizeToTray_ = true;
7204
7205 int state = windowState();
7206
7207 if (stayOnTopAct_->isChecked())
7208 setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
7209 else
7210 setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
7211
7212 if ((state & Qt::WindowFullScreen) || (state & Qt::WindowMaximized)) {
7213 Settings settings;
7214 restoreGeometry(settings.value("GeometryState").toByteArray());
7215 }
7216 setWindowState((Qt::WindowState)state);
7217 show();
7218
7219 isMinimizeToTray_ = false;
7220 }
7221
showMenuBar()7222 void MainWindow::showMenuBar()
7223 {
7224 if (showMenuBarAct_->isChecked()) {
7225 mainMenuButton_->hide();
7226 if (isFullScreen())
7227 menuBar()->hide();
7228 else
7229 menuBar()->show();
7230 } else {
7231 mainMenuButton_->show();
7232 menuBar()->hide();
7233 }
7234 }
7235
7236 /** @brief Move index after drag&drop operations
7237 * @param indexWhat index that is moving
7238 * @param indexWhere index, where to move
7239 *---------------------------------------------------------------------------*/
slotMoveIndex(const QModelIndex & indexWhere,int how)7240 void MainWindow::slotMoveIndex(const QModelIndex &indexWhere, int how)
7241 {
7242 feedsView_->setCursor(Qt::WaitCursor);
7243
7244 QModelIndexList indexList = feedsView_->selectionModel()->selectedRows(0);
7245 for (int i = 0; i < indexList.count(); i++) {
7246 QModelIndex indexWhat = feedsProxyModel_->mapToSource(indexList[i]);
7247 int feedIdWhat = feedsModel_->idByIndex(indexWhat);
7248 int feedParIdWhat = feedsModel_->paridByIndex(indexWhat);
7249 int feedIdWhere = feedsModel_->idByIndex(indexWhere);
7250 int feedParIdWhere = feedsModel_->paridByIndex(indexWhere);
7251
7252 // Repair rowToParent
7253 QSqlQuery q;
7254 if (how == 2) {
7255 // Move to another folder
7256 QList<int> idList;
7257 q.exec(QString("SELECT id FROM feeds WHERE parentId='%1' ORDER BY rowToParent").
7258 arg(feedParIdWhat));
7259 while (q.next()) {
7260 if (feedIdWhat != q.value(0).toInt())
7261 idList << q.value(0).toInt();
7262 }
7263 for (int i = 0; i < idList.count(); i++) {
7264 q.exec(QString("UPDATE feeds SET rowToParent='%1' WHERE id=='%2'").
7265 arg(i).arg(idList.at(i)));
7266 }
7267
7268 int rowToParent = 0;
7269 q.exec(QString("SELECT count(id) FROM feeds WHERE parentId='%1'").
7270 arg(feedIdWhere));
7271 if (q.next()) rowToParent = q.value(0).toInt();
7272
7273 q.exec(QString("UPDATE feeds SET parentId='%1', rowToParent='%2' WHERE id=='%3'").
7274 arg(feedIdWhere).arg(rowToParent).arg(feedIdWhat));
7275
7276 QList<int> categoriesList;
7277 categoriesList << feedParIdWhat << feedIdWhere;
7278 recountFeedCategories(categoriesList);
7279 } else if (feedParIdWhat == feedParIdWhere) {
7280 // Move inside folder
7281 QList<int> idList;
7282 q.exec(QString("SELECT id FROM feeds WHERE parentId='%1' ORDER BY rowToParent").
7283 arg(feedParIdWhat));
7284 while (q.next()) {
7285 idList << q.value(0).toInt();
7286 }
7287
7288 int rowWhat = feedsModel_->dataField(indexWhat, "rowToParent").toInt();
7289 int rowWhere = feedsModel_->dataField(indexWhere, "rowToParent").toInt();
7290 if ((rowWhat < rowWhere) && (how != 1)) rowWhere--;
7291 else if (how == 1) rowWhere++;
7292 idList.insert(rowWhere, idList.takeAt(rowWhat));
7293
7294 for (int i = 0; i < idList.count(); i++) {
7295 q.exec(QString("UPDATE feeds SET rowToParent='%1' WHERE id=='%2'").
7296 arg(i).arg(idList.at(i)));
7297 }
7298 } else {
7299 // Move in another folder beside feeds
7300 QList<int> idList;
7301 q.exec(QString("SELECT id FROM feeds WHERE parentId='%1' ORDER BY rowToParent").
7302 arg(feedParIdWhat));
7303 while (q.next()) {
7304 if (feedIdWhat != q.value(0).toInt())
7305 idList << q.value(0).toInt();
7306 }
7307 for (int i = 0; i < idList.count(); i++) {
7308 q.exec(QString("UPDATE feeds SET rowToParent='%1' WHERE id=='%2'").
7309 arg(i).arg(idList.at(i)));
7310 }
7311
7312 //
7313
7314 idList.clear();
7315 q.exec(QString("SELECT id FROM feeds WHERE parentId='%1' ORDER BY rowToParent").
7316 arg(feedParIdWhere));
7317 while (q.next()) {
7318 idList << q.value(0).toInt();
7319 }
7320
7321 int rowWhere = feedsModel_->dataField(indexWhere, "rowToParent").toInt();
7322 if (how == 1) rowWhere++;
7323 idList.insert(rowWhere, feedIdWhat);
7324
7325 for (int i = 0; i < idList.count(); i++) {
7326 q.exec(QString("UPDATE feeds SET rowToParent='%1' WHERE id=='%2'").
7327 arg(i).arg(idList.at(i)));
7328 }
7329
7330 q.exec(QString("UPDATE feeds SET parentId='%1' WHERE id=='%2'").
7331 arg(feedParIdWhere).arg(feedIdWhat));
7332
7333 QList<int> categoriesList;
7334 categoriesList << feedParIdWhat << feedParIdWhere;
7335 recountFeedCategories(categoriesList);
7336 }
7337 }
7338
7339 feedsView_->refresh();
7340
7341 feedsView_->setCurrentIndex(feedsProxyModel_->mapFromSource(feedIdOld_));
7342
7343 feedsView_->setCursor(Qt::ArrowCursor);
7344 }
7345
7346 /** @brief Process clicks in feeds tree
7347 * @param item Item that was clicked
7348 *---------------------------------------------------------------------------*/
slotCategoriesClicked(QTreeWidgetItem * item,int,bool createTab)7349 void MainWindow::slotCategoriesClicked(QTreeWidgetItem *item, int, bool createTab)
7350 {
7351 if (stackedWidget_->count() && currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
7352 currentNewsTab->newsHeader_->saveStateColumns(currentNewsTab);
7353 Settings settings;
7354 settings.setValue("NewsTabSplitterState", currentNewsTab->newsTabWidgetSplitter_->saveState());
7355 }
7356
7357 int type = item->text(1).toInt();
7358 NewsTabWidget::TabType tabType = static_cast<NewsTabWidget::TabType>(type);
7359
7360 int indexTab = -1;
7361 if (!createTab) {
7362 for (int i = 0; i < stackedWidget_->count(); i++) {
7363 NewsTabWidget *widget = (NewsTabWidget*)stackedWidget_->widget(i);
7364 if (widget->type_ == tabType) {
7365 if (widget->type_ == NewsTabWidget::TabTypeLabel) {
7366 if (widget->labelId_ == item->text(2).toInt()) {
7367 indexTab = i;
7368 break;
7369 }
7370 }
7371 else {
7372 indexTab = i;
7373 break;
7374 }
7375 }
7376 }
7377 }
7378
7379 if (indexTab == -1) {
7380 if (createTab) {
7381 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_,
7382 FeedReadSwitchingTab, currentNewsTab);
7383
7384 NewsTabWidget *widget = new NewsTabWidget(this, tabType);
7385 indexTab = addTab(widget);
7386 createNewsTab(indexTab);
7387 }
7388 else {
7389 feedsView_->setCurrentIndex(QModelIndex());
7390 feedProperties_->setEnabled(false);
7391
7392 if (tabBar_->currentIndex() != TAB_WIDGET_PERMANENT) {
7393 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_,
7394 FeedReadSwitchingTab, currentNewsTab);
7395
7396 QModelIndex curIndex = categoriesTree_->currentIndex();
7397 updateCurrentTab_ = false;
7398 tabBar_->setCurrentIndex(TAB_WIDGET_PERMANENT);
7399 updateCurrentTab_ = true;
7400 categoriesTree_->setCurrentIndex(curIndex);
7401
7402 currentNewsTab = (NewsTabWidget*)stackedWidget_->widget(TAB_WIDGET_PERMANENT);
7403 newsModel_ = currentNewsTab->newsModel_;
7404 newsView_ = currentNewsTab->newsView_;
7405 } else {
7406 setFeedRead(currentNewsTab->type_, currentNewsTab->feedId_,
7407 FeedReadSwitchingFeed, currentNewsTab);
7408 }
7409
7410 currentNewsTab->type_ = tabType;
7411 currentNewsTab->feedId_ = -1;
7412 currentNewsTab->feedParId_ = -1;
7413 currentNewsTab->setSettings(true, false);
7414 currentNewsTab->setVisible(true);
7415 }
7416
7417 // Set icon and title of current tab
7418 currentNewsTab->newsIconTitle_->setPixmap(item->icon(0).pixmap(16,16));
7419 currentNewsTab->setTextTab(item->text(0));
7420
7421 currentNewsTab->labelId_ = item->text(2).toInt();
7422
7423 switch (type) {
7424 case NewsTabWidget::TabTypeUnread:
7425 currentNewsTab->categoryFilterStr_ = "feedId > 0 AND deleted = 0 AND read < 2";
7426 break;
7427 case NewsTabWidget::TabTypeStar:
7428 currentNewsTab->categoryFilterStr_ = "feedId > 0 AND deleted = 0 AND starred = 1";
7429 break;
7430 case NewsTabWidget::TabTypeDel:
7431 currentNewsTab->categoryFilterStr_ = "feedId > 0 AND deleted = 1";
7432 break;
7433 case NewsTabWidget::TabTypeLabel:
7434 if (currentNewsTab->labelId_ != 0) {
7435 currentNewsTab->categoryFilterStr_ =
7436 QString("feedId > 0 AND deleted = 0 AND label LIKE '%,%1,%'").
7437 arg(currentNewsTab->labelId_);
7438 } else {
7439 currentNewsTab->categoryFilterStr_ =
7440 QString("feedId > 0 AND deleted = 0 AND label!='' AND label!=','");
7441 }
7442 break;
7443 }
7444 // ... add filter from "search"
7445 QString filterStr = currentNewsTab->categoryFilterStr_;
7446 QString objectName = currentNewsTab->findText_->findGroup_->checkedAction()->objectName();
7447 if (objectName != "findInBrowserAct") {
7448 QString findText = currentNewsTab->findText_->text();
7449 if (!findText.isEmpty()) {
7450 findText = findText.replace("'", "''").toUpper();
7451 if (objectName == "findTitleAct") {
7452 filterStr.append(
7453 QString(" AND UPPER(title) LIKE '%%1%'").arg(findText));
7454 } else if (objectName == "findAuthorAct") {
7455 filterStr.append(
7456 QString(" AND UPPER(author_name) LIKE '%%1%'").arg(findText));
7457 } else if (objectName == "findCategoryAct") {
7458 filterStr.append(
7459 QString(" AND UPPER(category) LIKE '%%1%'").arg(findText));
7460 } else if (objectName == "findContentAct") {
7461 filterStr.append(
7462 QString(" AND (UPPER(content) LIKE '%%1%' OR UPPER(description) LIKE '%%1%')").
7463 arg(findText));
7464 } else if (objectName == "findLinkAct") {
7465 filterStr.append(
7466 QString(" AND link_href LIKE '%%1%'").
7467 arg(findText));
7468 } else {
7469 filterStr.append(
7470 QString(" AND (UPPER(title) LIKE '%%1%' OR UPPER(author_name) LIKE '%%1%' "
7471 "OR UPPER(category) LIKE '%%1%' OR UPPER(content) LIKE '%%1%' "
7472 "OR UPPER(description) LIKE '%%1%')").
7473 arg(findText));
7474 }
7475 }
7476 }
7477 newsModel_->setFilter(filterStr);
7478
7479 if (newsModel_->rowCount() != 0) {
7480 while (newsModel_->canFetchMore())
7481 newsModel_->fetchMore();
7482 }
7483
7484 if (type == NewsTabWidget::TabTypeDel){
7485 currentNewsTab->newsHeader_->setSortIndicator(newsModel_->fieldIndex("deleteDate"),
7486 Qt::DescendingOrder);
7487 } else {
7488 if ((currentNewsTab->newsHeader_->sortIndicatorSection() == newsModel_->fieldIndex("read")) ||
7489 currentNewsTab->newsHeader_->sortIndicatorSection() == newsModel_->fieldIndex("starred")) {
7490 currentNewsTab->slotSort(currentNewsTab->newsHeader_->sortIndicatorSection(),
7491 currentNewsTab->newsHeader_->sortIndicatorOrder());
7492 }
7493 }
7494
7495 currentNewsTab->loadNewspaper();
7496
7497 // Search previous displayed news of the feed
7498 int newsRow = -1;
7499 if (openingFeedAction_ == 0) {
7500 int newsIdCur = item->text(3).toInt();
7501 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("id"));
7502 QModelIndexList indexList = newsModel_->match(index, Qt::EditRole, newsIdCur);
7503
7504 if (!indexList.isEmpty()) newsRow = indexList.first().row();
7505 } else if (openingFeedAction_ == 1) {
7506 newsRow = 0;
7507 } else if (openingFeedAction_ == 3) {
7508 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("read"));
7509 QModelIndexList indexList;
7510 if (newsView_->header()->sortIndicatorOrder() == Qt::DescendingOrder)
7511 indexList = newsModel_->match(index, Qt::EditRole, 0, -1);
7512 else
7513 indexList = newsModel_->match(index, Qt::EditRole, 0);
7514
7515 if (!indexList.isEmpty()) newsRow = indexList.last().row();
7516 }
7517
7518 // Display previous displayed news of the feed
7519 newsView_->setCurrentIndex(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
7520 if (newsRow == -1) newsView_->verticalScrollBar()->setValue(newsRow);
7521
7522 if ((openingFeedAction_ != 2) && openNewsWebViewOn_) {
7523 currentNewsTab->slotNewsViewSelected(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
7524 } else {
7525 currentNewsTab->slotNewsViewSelected(newsModel_->index(-1, newsModel_->fieldIndex("title")));
7526 }
7527
7528 if (createTab)
7529 emit signalSetCurrentTab(indexTab);
7530 } else {
7531 emit signalSetCurrentTab(indexTab, true);
7532 }
7533
7534 int unreadCount = currentNewsTab->getUnreadCount(categoriesTree_->currentItem()->text(4));
7535 int allCount = currentNewsTab->newsModel_->rowCount();
7536 statusUnread_->setText(QString(" " + tr("Unread: %1") + " ").arg(unreadCount));
7537 statusAll_->setText(QString(" " + tr("All: %1") + " ").arg(allCount));
7538
7539 statusUnread_->setVisible(currentNewsTab->type_ != NewsTabWidget::TabTypeDel);
7540 statusAll_->setVisible(true);
7541 }
7542
clearDeleted()7543 void MainWindow::clearDeleted()
7544 {
7545 QSqlQuery q;
7546 q.exec("UPDATE news SET description='', content='', received='', "
7547 "author_name='', author_uri='', author_email='', "
7548 "category='', new='', read='', starred='', label='', "
7549 "deleteDate='', feedParentId='', deleted=2 WHERE deleted==1");
7550
7551 if (currentNewsTab->type_ == NewsTabWidget::TabTypeDel) {
7552 currentNewsTab->newsModel_->select();
7553 currentNewsTab->slotNewsViewSelected(QModelIndex());
7554 }
7555
7556 recountCategoryCounts();
7557 }
7558
slotMarkReadCategory(QTreeWidgetItem * item)7559 void MainWindow::slotMarkReadCategory(QTreeWidgetItem *item)
7560 {
7561 int type = item->text(1).toInt();
7562 int labelId = item->text(2).toInt();
7563
7564 if ((currentNewsTab->type_ == type) && (currentNewsTab->labelId_ == labelId)) {
7565 currentNewsTab->markAllNewsRead();
7566 }
7567 else {
7568 emit signalMarkReadCategory(type, labelId);
7569 recountCategoryCounts();
7570 }
7571 }
7572
7573 /** @brief Show/Hide categories tree
7574 *---------------------------------------------------------------------------*/
showNewsCategoriesTree()7575 void MainWindow::showNewsCategoriesTree()
7576 {
7577 if (categoriesTree_->isHidden()) {
7578 showCategoriesButton_->setIcon(QIcon(":/images/images/panel_hide.png"));
7579 showCategoriesButton_->setToolTip(tr("Hide Categories"));
7580 categoriesTree_->show();
7581 feedsSplitter_->restoreState(feedsWidgetSplitterState_);
7582 } else {
7583 feedsWidgetSplitterState_ = feedsSplitter_->saveState();
7584 showCategoriesButton_->setIcon(QIcon(":/images/images/panel_show.png"));
7585 showCategoriesButton_->setToolTip(tr("Show Categories"));
7586 categoriesTree_->hide();
7587 QList <int> sizes;
7588 sizes << height() << 20;
7589 feedsSplitter_->setSizes(sizes);
7590 }
7591 }
7592
7593 /** @brief Move splitter between feeds tree and categories tree
7594 *---------------------------------------------------------------------------*/
feedsSplitterMoved(int pos,int)7595 void MainWindow::feedsSplitterMoved(int pos, int)
7596 {
7597 if (categoriesTree_->isHidden()) {
7598 int height = pos + categoriesPanel_->height() + 2;
7599 if (height < feedsSplitter_->height()) {
7600 showCategoriesButton_->setIcon(QIcon(":/images/images/panel_hide.png"));
7601 showCategoriesButton_->setToolTip(tr("Hide Categories"));
7602 categoriesTree_->show();
7603 recountCategoryCounts();
7604 }
7605 }
7606 }
7607
7608 /** @brief Set specified label for news
7609 *---------------------------------------------------------------------------*/
setLabelNews(QAction * action)7610 void MainWindow::setLabelNews(QAction *action)
7611 {
7612 if (currentNewsTab->type_ >= NewsTabWidget::TabTypeWeb) return;
7613
7614 newsLabelAction_->setIcon(action->icon());
7615 newsLabelAction_->setToolTip(action->text());
7616 newsLabelAction_->setData(action->data());
7617
7618 currentNewsTab->setLabelNews(action->data().toInt());
7619 }
7620
7621 /** @brief Set last chosen label for news
7622 *---------------------------------------------------------------------------*/
setDefaultLabelNews()7623 void MainWindow::setDefaultLabelNews()
7624 {
7625 if (currentNewsTab->type_ >= NewsTabWidget::TabTypeWeb) return;
7626
7627 currentNewsTab->setLabelNews(newsLabelAction_->data().toInt());
7628 }
7629
7630 /** @brief Get Label that belong to current news
7631 *---------------------------------------------------------------------------*/
getLabelNews()7632 void MainWindow::getLabelNews()
7633 {
7634 for (int i = 0; i < newsLabelGroup_->actions().count(); i++) {
7635 newsLabelGroup_->actions().at(i)->setChecked(false);
7636 }
7637
7638 if (currentNewsTab->type_ >= NewsTabWidget::TabTypeWeb) return;
7639
7640 QList<QModelIndex> indexes = newsView_->selectionModel()->selectedRows(
7641 newsModel_->fieldIndex("label"));
7642 if (!indexes.count()) return;
7643
7644 if (indexes.count() == 1) {
7645 QModelIndex index = indexes.at(0);
7646 QStringList strLabelIdList = index.data(Qt::EditRole).toString().split(",", QString::SkipEmptyParts);
7647 foreach (QString strLabelId, strLabelIdList) {
7648 for (int i = 0; i < newsLabelGroup_->actions().count(); i++) {
7649 if (newsLabelGroup_->actions().at(i)->data().toString() == strLabelId)
7650 newsLabelGroup_->actions().at(i)->setChecked(true);
7651 }
7652 }
7653 } else {
7654 for (int i = 0; i < newsLabelGroup_->actions().count(); i++) {
7655 bool check = false;
7656 QString strLabelId = newsLabelGroup_->actions().at(i)->data().toString();
7657 for (int y = indexes.count()-1; y >= 0; --y) {
7658 QModelIndex index = indexes.at(y);
7659 QString strIdLabels = index.data(Qt::EditRole).toString();
7660 if (!strIdLabels.contains(QString(",%1,").arg(strLabelId))) {
7661 check = false;
7662 break;
7663 }
7664 check = true;
7665 }
7666 newsLabelGroup_->actions().at(i)->setChecked(check);
7667 }
7668 }
7669 }
7670
7671 /** @brief Add tab widget to tabs stack widget
7672 *---------------------------------------------------------------------------*/
addTab(NewsTabWidget * widget)7673 int MainWindow::addTab(NewsTabWidget *widget)
7674 {
7675 int indexTab;
7676 if (openNewTabNextToActive_) {
7677 if (stackedWidget_->count()) tabBar_->insertTab(tabBar_->currentIndex()+1, "");
7678 indexTab = stackedWidget_->insertWidget(stackedWidget_->currentIndex()+1, widget);
7679 }
7680 else {
7681 if (stackedWidget_->count()) tabBar_->addTab("");
7682 indexTab = stackedWidget_->addWidget(widget);
7683 }
7684 tabBar_->setTabButton(indexTab,
7685 QTabBar::LeftSide,
7686 widget->newsTitleLabel_);
7687
7688 return indexTab;
7689 }
7690
7691 // ----------------------------------------------------------------------------
reduceNewsList()7692 void MainWindow::reduceNewsList()
7693 {
7694 currentNewsTab->reduceNewsList();
7695 }
7696 // ----------------------------------------------------------------------------
increaseNewsList()7697 void MainWindow::increaseNewsList()
7698 {
7699 currentNewsTab->increaseNewsList();
7700 }
7701
7702 /** @brief Save browser current page to file
7703 *---------------------------------------------------------------------------*/
slotSavePageAs()7704 void MainWindow::slotSavePageAs()
7705 {
7706 if (currentNewsTab->type_ == NewsTabWidget::TabTypeDownloads) return;
7707
7708 QString fileName = currentNewsTab->webView_->title();
7709 if (newsLayout_ == 0) {
7710 if (fileName == "news_descriptions") {
7711 int row = currentNewsTab->newsView_->currentIndex().row();
7712 fileName = currentNewsTab->newsModel_->dataField(row, "title").toString();
7713 }
7714 } else {
7715 if (currentNewsTab->type_ == NewsTabWidget::TabTypeFeed) {
7716 QModelIndex feedIndex = feedsView_->currentIndex();
7717 feedIndex = feedsProxyModel_->mapToSource(feedIndex);
7718 fileName = feedsModel_->dataField(feedIndex, "text").toString();
7719 } else {
7720 fileName = categoriesTree_->currentItem()->text(0);
7721 }
7722 }
7723 QString title = fileName.trimmed();
7724
7725 fileName = fileName.trimmed();
7726 fileName = fileName.replace(QzRegExp("[:\"]"), "_");
7727 fileName = QDir::toNativeSeparators(QDir::homePath() + "/" + fileName);
7728 fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
7729 fileName,
7730 QString(tr("HTML-Files (*.%1)") + ";;" + tr("Text files (*.%2)"))
7731 .arg("html").arg("txt"));
7732 if (fileName.isNull()) return;
7733
7734 QFile file(fileName);
7735 if (!file.open(QIODevice::WriteOnly)) {
7736 statusBar()->showMessage(tr("Save As: can't open a file"), 3000);
7737 return;
7738 }
7739 QFileInfo fileInfo(fileName);
7740 if (fileInfo.suffix() == "txt") {
7741 file.write(currentNewsTab->webView_->page()->mainFrame()->toPlainText().toUtf8());
7742 } else {
7743 QString html = currentNewsTab->webView_->page()->mainFrame()->toHtml();
7744 QzRegExp reg("news_descriptions", Qt::CaseInsensitive);
7745 html = html.replace(reg, title);
7746 reg.setPattern("<img class=\"quiterss-img\"[^>]+\\>");
7747 html = html.remove(reg);
7748 QTextCodec *codec = QTextCodec::codecForHtml(html.toUtf8(),
7749 QTextCodec::codecForName("UTF-8"));
7750 file.write(codec->fromUnicode(html));
7751 }
7752 file.close();
7753 }
7754
slotSavePageAsDescript()7755 void MainWindow::slotSavePageAsDescript()
7756 {
7757 currentNewsTab->savePageAsDescript();
7758 }
7759
7760 /** @brief Restore last deleted news
7761 *---------------------------------------------------------------------------*/
restoreLastNews()7762 void MainWindow::restoreLastNews()
7763 {
7764 QSqlQuery q;
7765 q.exec("SELECT id, feedId FROM news WHERE deleted=1 AND deleteDate!='' ORDER BY deleteDate DESC");
7766 if (q.next()) {
7767 QModelIndex curIndex = newsView_->currentIndex();
7768 int newsIdCur = newsModel_->index(curIndex.row(), newsModel_->fieldIndex("id")).data().toInt();
7769
7770 int newsId = q.value(0).toInt();
7771 int feedId = q.value(1).toInt();
7772 q.exec(QString("UPDATE news SET deleted=0, deleteDate='' WHERE id=='%1'").
7773 arg(newsId));
7774
7775 newsModel_->select();
7776
7777 while (newsModel_->canFetchMore())
7778 newsModel_->fetchMore();
7779
7780 currentNewsTab->loadNewspaper(NewsTabWidget::RefreshWithPos);
7781
7782 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("id"));
7783 QModelIndexList indexList = newsModel_->match(index, Qt::EditRole, newsIdCur);
7784 if (indexList.count()) {
7785 int newsRow = indexList.first().row();
7786 newsView_->setCurrentIndex(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
7787 }
7788 slotUpdateStatus(feedId);
7789 recountCategoryCounts();
7790 }
7791 }
7792
7793 /** @brief Switch to next unread news
7794 *---------------------------------------------------------------------------*/
nextUnreadNews()7795 void MainWindow::nextUnreadNews()
7796 {
7797 if (currentNewsTab->type_ >= NewsTabWidget::TabTypeWeb) return;
7798 newsView_->clearSelection();
7799
7800 int newsRow = currentNewsTab->findUnreadNews(true);
7801
7802 if (newsRow == -1) {
7803 if (currentNewsTab->type_ != NewsTabWidget::TabTypeFeed) return;
7804
7805 QModelIndex indexPrevUnread = QModelIndex();
7806 if (feedsView_->currentIndex().isValid())
7807 indexPrevUnread = feedsView_->indexNextUnread(feedsView_->currentIndex(), 1);
7808 if (!indexPrevUnread.isValid()) {
7809 indexPrevUnread = feedsView_->indexNextUnread(QModelIndex(), 1);
7810 }
7811 if (indexPrevUnread.isValid()) {
7812 if (changeBehaviorActionNUN_)
7813 openingFeedAction_ = 4;
7814 else
7815 openingFeedAction_ = 3;
7816 feedsView_->clearSelection();
7817 feedsView_->setCurrentIndex(indexPrevUnread);
7818 slotFeedClicked(indexPrevUnread);
7819
7820 if (tabBar_->currentIndex() != TAB_WIDGET_PERMANENT) {
7821 QModelIndex index = newsModel_->index(0, newsModel_->fieldIndex("read"));
7822 QModelIndexList indexList;
7823 if ((newsView_->header()->sortIndicatorOrder() == Qt::DescendingOrder) &&
7824 (openingFeedAction_ != 4))
7825 indexList = newsModel_->match(index, Qt::EditRole, 0, -1);
7826 else
7827 indexList = newsModel_->match(index, Qt::EditRole, 0);
7828
7829 if (!indexList.isEmpty()) newsRow = indexList.last().row();
7830
7831 // Focus feed news that displayed before
7832 newsView_->setCurrentIndex(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
7833 if (newsRow == -1) newsView_->verticalScrollBar()->setValue(newsRow);
7834
7835 if (openNewsWebViewOn_) {
7836 currentNewsTab->slotNewsViewSelected(newsModel_->index(newsRow, newsModel_->fieldIndex("title")));
7837 }
7838 }
7839
7840 Settings settings;
7841 openingFeedAction_ = settings.value("/Settings/openingFeedAction", 0).toInt();
7842 }
7843 return;
7844 }
7845
7846 int value = newsView_->verticalScrollBar()->value();
7847 int pageStep = newsView_->verticalScrollBar()->pageStep();
7848 if (newsRow > (value + pageStep/2))
7849 newsView_->verticalScrollBar()->setValue(newsRow - pageStep/2);
7850
7851 QModelIndex index = newsModel_->index(newsRow, newsModel_->fieldIndex("title"));
7852 newsView_->setCurrentIndex(index);
7853 currentNewsTab->slotNewsViewSelected(index);
7854 }
7855
7856 /** @brief Switch to previous unread news
7857 *---------------------------------------------------------------------------*/
prevUnreadNews()7858 void MainWindow::prevUnreadNews()
7859 {
7860 if (currentNewsTab->type_ >= NewsTabWidget::TabTypeWeb) return;
7861 newsView_->clearSelection();
7862
7863 int newsRow = currentNewsTab->findUnreadNews(false);
7864
7865 int newsRowCur = newsView_->currentIndex().row();
7866 if ((newsRow >= newsRowCur) || (newsRow == -1)) {
7867 if (currentNewsTab->type_ != NewsTabWidget::TabTypeFeed) return;
7868
7869 QModelIndex indexNextUnread =
7870 feedsView_->indexNextUnread(feedsView_->currentIndex(), 2);
7871 if (indexNextUnread.isValid()) {
7872 openingFeedAction_ = 3;
7873 feedsView_->clearSelection();
7874 feedsView_->setCurrentIndex(indexNextUnread);
7875 slotFeedClicked(indexNextUnread);
7876 Settings settings;
7877 openingFeedAction_ = settings.value("/Settings/openingFeedAction", 0).toInt();
7878 }
7879 return;
7880 }
7881
7882 int value = newsView_->verticalScrollBar()->value();
7883 int pageStep = newsView_->verticalScrollBar()->pageStep();
7884 if (newsRow < (value + pageStep/2))
7885 newsView_->verticalScrollBar()->setValue(newsRow - pageStep/2);
7886
7887 QModelIndex index = newsModel_->index(newsRow, newsModel_->fieldIndex("title"));
7888 newsView_->setCurrentIndex(index);
7889 currentNewsTab->slotNewsViewSelected(index);
7890 }
7891
7892 /** @brief Get feeds ids list string of folder \a idFolder
7893 *---------------------------------------------------------------------------*/
getIdFeedsString(int idFolder,int idException)7894 QString MainWindow::getIdFeedsString(int idFolder, int idException)
7895 {
7896 QList<int> idList = UpdateObject::getIdFeedsInList(db_, idFolder);
7897 if (idList.count()) {
7898 QString str;
7899 foreach (int id, idList) {
7900 if (id == idException) continue;
7901 if (!str.isEmpty()) str.append(" OR ");
7902 str.append(QString("feedId=%1").arg(id));
7903 }
7904 return str;
7905 } else {
7906 return QString("feedId=-1");
7907 }
7908 }
7909
7910 /** @brief Set application title
7911 *---------------------------------------------------------------------------*/
setTextTitle(const QString & text,NewsTabWidget * widget)7912 void MainWindow::setTextTitle(const QString &text, NewsTabWidget *widget)
7913 {
7914 if (currentNewsTab != widget) return;
7915
7916 if (text.isEmpty()) setWindowTitle("QuiteRSS");
7917 else setWindowTitle(QString("%1 - QuiteRSS").arg(text));
7918 }
7919
7920 /** @brief Enable|Disable indent in feeds tree
7921 *---------------------------------------------------------------------------*/
slotIndentationFeedsTree()7922 void MainWindow::slotIndentationFeedsTree()
7923 {
7924 feedsView_->setRootIsDecorated(indentationFeedsTreeAct_->isChecked());
7925 }
7926
7927 // ----------------------------------------------------------------------------
customizeMainToolbar()7928 void MainWindow::customizeMainToolbar()
7929 {
7930 showCustomizeToolbarDlg(customizeMainToolbarAct2_);
7931 }
7932 // ----------------------------------------------------------------------------
showCustomizeToolbarDlg(QAction * action)7933 void MainWindow::showCustomizeToolbarDlg(QAction *action)
7934 {
7935 QToolBar *toolbar = mainToolbar_;
7936 if (action->objectName() == "customizeFeedsToolbarAct") {
7937 toolbar = feedsToolBar_;
7938 } else if (action->objectName() == "customizeNewsToolbarAct") {
7939 if (currentNewsTab->type_ == NewsTabWidget::TabTypeWeb) return;
7940 if (currentNewsTab->type_ == NewsTabWidget::TabTypeDownloads) return;
7941 toolbar = currentNewsTab->newsToolBar_;
7942 }
7943
7944 CustomizeToolbarDialog *toolbarDlg = new CustomizeToolbarDialog(this, toolbar);
7945
7946 toolbarDlg->exec();
7947
7948 delete toolbarDlg;
7949 }
7950
7951 /** @brief Process news sharing
7952 *---------------------------------------------------------------------------*/
slotShareNews(QAction * action)7953 void MainWindow::slotShareNews(QAction *action)
7954 {
7955 currentNewsTab->slotShareNews(action);
7956 }
7957 // ----------------------------------------------------------------------------
showMenuShareNews()7958 void MainWindow::showMenuShareNews()
7959 {
7960 if (mainToolbar_->widgetForAction(shareMenuAct_)) {
7961 QWidget *widget = mainToolbar_->widgetForAction(shareMenuAct_);
7962 if (widget->underMouse()) {
7963 shareMenu_->popup(widget->mapToGlobal(QPoint(0, mainToolbar_->height()-1)));
7964 }
7965 }
7966 if (feedsToolBar_->widgetForAction(shareMenuAct_)) {
7967 QWidget *widget = feedsToolBar_->widgetForAction(shareMenuAct_);
7968 if (widget->underMouse()) {
7969 shareMenu_->popup(widget->mapToGlobal(QPoint(0, feedsToolBar_->height()-1)));
7970 }
7971 }
7972 if (currentNewsTab->type_ < NewsTabWidget::TabTypeWeb) {
7973 if (currentNewsTab->newsToolBar_->widgetForAction(shareMenuAct_)) {
7974 QWidget *widget = currentNewsTab->newsToolBar_->widgetForAction(shareMenuAct_);
7975 if (widget->underMouse()) {
7976 shareMenu_->popup(widget->mapToGlobal(QPoint(0, currentNewsTab->newsToolBar_->height()-1)));
7977 }
7978 }
7979 }
7980 if (currentNewsTab->webToolBar_->widgetForAction(shareMenuAct_)) {
7981 QWidget *widget = currentNewsTab->webToolBar_->widgetForAction(shareMenuAct_);
7982 if (widget->underMouse()) {
7983 shareMenu_->popup(widget->mapToGlobal(QPoint(0, currentNewsTab->webToolBar_->height()-1)));
7984 }
7985 }
7986 }
7987
7988 /** @brief Open feed home page in external browser
7989 *---------------------------------------------------------------------------*/
slotOpenHomeFeed()7990 void MainWindow::slotOpenHomeFeed()
7991 {
7992 QModelIndex index = feedsView_->currentIndex();
7993 if (!index.isValid()) return;
7994 index = feedsProxyModel_->mapToSource(index);
7995
7996 QString homePage = feedsModel_->dataField(index, "htmlUrl").toString();
7997 QDesktopServices::openUrl(homePage);
7998 }
7999
8000 /** @brief Sort feed and folders by title
8001 *---------------------------------------------------------------------------*/
sortedByTitleFeedsTree()8002 void MainWindow::sortedByTitleFeedsTree()
8003 {
8004 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
8005
8006 QList<int> parentIdsPotential;
8007 parentIdsPotential << 0;
8008 while (!parentIdsPotential.empty()) {
8009 int parentId = parentIdsPotential.takeFirst();
8010
8011 // Search children of parent <parentId>
8012 QSqlQuery q;
8013 q.prepare(QString("SELECT id, xmlUrl FROM feeds WHERE parentId=? ORDER BY text COLLATE LOCALE"));
8014 q.addBindValue(parentId);
8015 q.exec();
8016
8017 // assing each child his <rowToParent>
8018 // ... store it in prospactive parent list
8019 int rowToParent = 0;
8020 while (q.next()) {
8021 int parentIdNew = q.value(0).toInt();
8022 QString xmlUrl = q.value(1).toString();
8023
8024 QSqlQuery q2;
8025 q2.prepare("UPDATE feeds SET rowToParent=? WHERE id=?");
8026 q2.addBindValue(rowToParent);
8027 q2.addBindValue(parentIdNew);
8028 q2.exec();
8029
8030 if (xmlUrl.isEmpty())
8031 parentIdsPotential << parentIdNew;
8032 ++rowToParent;
8033 }
8034 }
8035
8036 feedsModelReload();
8037 QApplication::restoreOverrideCursor();
8038 }
8039
8040 // ----------------------------------------------------------------------------
showNewsMenu()8041 void MainWindow::showNewsMenu()
8042 {
8043 if (currentNewsTab)
8044 newsSortByMenu_->setEnabled(currentNewsTab->type_ < NewsTabWidget::TabTypeWeb);
8045 }
8046 // ----------------------------------------------------------------------------
showNewsSortByMenu()8047 void MainWindow::showNewsSortByMenu()
8048 {
8049 if (currentNewsTab->type_ >= NewsTabWidget::TabTypeWeb) return;
8050
8051 QListIterator<QAction *> iter(newsSortByColumnGroup_->actions());
8052 while (iter.hasNext()) {
8053 QAction *nextAction = iter.next();
8054 delete nextAction;
8055 }
8056
8057 int section = currentNewsTab->newsHeader_->sortIndicatorSection();
8058 iter = currentNewsTab->newsHeader_->viewMenu_->actions();
8059 while (iter.hasNext()) {
8060 QAction *nextAction = iter.next();
8061 QAction *newsSortByColumnAct = new QAction(this);
8062 newsSortByColumnAct->setCheckable(true);
8063 newsSortByColumnAct->setText(nextAction->text());
8064 newsSortByColumnAct->setData(nextAction->data());
8065 if (nextAction->data().toInt() == section) {
8066 newsSortByColumnAct->setChecked(true);
8067 }
8068 newsSortByColumnGroup_->addAction(newsSortByColumnAct);
8069 }
8070 newsSortByMenu_->insertActions(newsSortByMenu_->actions().at(0),
8071 newsSortByColumnGroup_->actions());
8072
8073 if (currentNewsTab->newsHeader_->sortIndicatorOrder() == Qt::AscendingOrder) {
8074 newsSortOrderGroup_->actions().at(0)->setChecked(true);
8075 } else {
8076 newsSortOrderGroup_->actions().at(1)->setChecked(true);
8077 }
8078 }
8079 // ----------------------------------------------------------------------------
setNewsSortByColumn()8080 void MainWindow::setNewsSortByColumn()
8081 {
8082 if (currentNewsTab->type_ >= NewsTabWidget::TabTypeWeb) return;
8083
8084 int lIdx = newsSortByColumnGroup_->checkedAction()->data().toInt();
8085 if (newsSortOrderGroup_->actions().at(0)->isChecked()) {
8086 currentNewsTab->newsHeader_->setSortIndicator(lIdx, Qt::AscendingOrder);
8087 } else {
8088 currentNewsTab->newsHeader_->setSortIndicator(lIdx, Qt::DescendingOrder);
8089 }
8090 }
8091 // ----------------------------------------------------------------------------
slotPrevFolder()8092 void MainWindow::slotPrevFolder()
8093 {
8094 QModelIndex indexBefore = feedsView_->currentIndex();
8095 QModelIndex indexAfter;
8096
8097 // Set to bottom folder, if there's no above folder
8098 if (!indexBefore.isValid())
8099 indexAfter = feedsView_->lastFolderInFolder(QModelIndex());
8100 else
8101 indexAfter = feedsView_->indexPreviousFolder(indexBefore);
8102
8103 // there's no "upper" index
8104 if (!indexAfter.isValid()) return;
8105 feedsView_->clearSelection();
8106
8107 feedsView_->setCurrentIndex(indexAfter);
8108 slotFeedClicked(indexAfter);
8109 }
8110 // ----------------------------------------------------------------------------
slotNextFolder()8111 void MainWindow::slotNextFolder()
8112 {
8113 QModelIndex indexBefore = feedsView_->currentIndex();
8114 QModelIndex indexAfter;
8115
8116 // Set to top index, if there's no below index
8117 if (!indexBefore.isValid())
8118 indexAfter = feedsView_->firstFolderInFolder(QModelIndex());
8119 else
8120 indexAfter = feedsView_->indexNextFolder(indexBefore);
8121
8122 // there's no "downer" index
8123 if (!indexAfter.isValid()) return;
8124 feedsView_->clearSelection();
8125
8126 feedsView_->setCurrentIndex(indexAfter);
8127 slotFeedClicked(indexAfter);
8128 }
8129 // ----------------------------------------------------------------------------
slotExpandFolder()8130 void MainWindow::slotExpandFolder()
8131 {
8132 QModelIndex index = feedsView_->currentIndex();
8133 if (!feedsModel_->isFolder(index)) {
8134 index = feedsModel_->parent(index);
8135 }
8136 feedsView_->setExpanded(index, !feedsView_->isExpanded(index));
8137 }
8138 // ----------------------------------------------------------------------------
showDownloadManager(bool activate)8139 void MainWindow::showDownloadManager(bool activate)
8140 {
8141 int indexTab = -1;
8142 NewsTabWidget *widget;
8143 for (int i = 0; i < stackedWidget_->count(); i++) {
8144 widget = (NewsTabWidget*)stackedWidget_->widget(i);
8145 if (widget->type_ == NewsTabWidget::TabTypeDownloads) {
8146 indexTab = i;
8147 break;
8148 }
8149 }
8150
8151 if (indexTab == -1) {
8152 widget = new NewsTabWidget(this, NewsTabWidget::TabTypeDownloads);
8153 indexTab = addTab(widget);
8154 QPixmap iconTab;
8155 iconTab.load(":/images/download");
8156 widget->newsIconTitle_->setPixmap(iconTab);
8157 widget->retranslateStrings();
8158 }
8159
8160 if (activate) {
8161 currentNewsTab = widget;
8162 currentNewsTab->setTextTab(tr("Downloads"));
8163 statusUnread_->setVisible(false);
8164 statusAll_->setVisible(false);
8165 mainApp->downloadManager()->show();
8166 emit signalSetCurrentTab(indexTab);
8167 } else {
8168 widget->setTextTab(tr("Downloads"));
8169 }
8170 }
8171 // ----------------------------------------------------------------------------
updateInfoDownloads(const QString & text)8172 void MainWindow::updateInfoDownloads(const QString &text)
8173 {
8174 NewsTabWidget *widget;
8175 for (int i = 0; i < stackedWidget_->count(); i++) {
8176 widget = (NewsTabWidget*)stackedWidget_->widget(i);
8177 if (widget->type_ == NewsTabWidget::TabTypeDownloads) {
8178 widget->setTextTab(QString("%1 %2").arg(tr("Downloads")).arg(text));
8179 break;
8180 }
8181 }
8182 }
8183
setStatusFeed(int feedId,QString status)8184 void MainWindow::setStatusFeed(int feedId, QString status)
8185 {
8186 QModelIndex index = feedsModel_->indexById(feedId);
8187 if (index.isValid()) {
8188 QModelIndex indexStatus = feedsModel_->indexSibling(index, "status");
8189 feedsModel_->setData(indexStatus, status);
8190 feedsView_->viewport()->update();
8191 }
8192 }
8193
addOurFeed()8194 void MainWindow::addOurFeed()
8195 {
8196 if (mainApp->dbFileExists()) return;
8197
8198 QPixmap icon(":/images/quiterss16");
8199 QByteArray iconData;
8200 QBuffer buffer(&iconData);
8201 buffer.open(QIODevice::WriteOnly);
8202 icon.save(&buffer, "PNG");
8203 buffer.close();
8204
8205 QString xmlUrl = "https://quiterss.org/en/rss.xml";
8206 if (mainApp->language() == "ru")
8207 xmlUrl = "https://quiterss.org/ru/rss.xml";
8208
8209 QSqlQuery q;
8210 q.prepare("INSERT INTO feeds(text, title, xmlUrl, htmlUrl, created, parentId, rowToParent, image) "
8211 "VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
8212 q.addBindValue("QuiteRSS");
8213 q.addBindValue("QuiteRSS");
8214 q.addBindValue(xmlUrl);
8215 q.addBindValue("https://quiterss.org");
8216 q.addBindValue(QDateTime::currentDateTimeUtc().toString(Qt::ISODate));
8217 q.addBindValue(0);
8218 q.addBindValue(0);
8219 q.addBindValue(iconData.toBase64());
8220 q.exec();
8221
8222 feedsModelReload();
8223 }
8224
createBackup()8225 void MainWindow::createBackup()
8226 {
8227 QString backupDir(QDir::currentPath());
8228 Settings settings;
8229 backupDir = settings.value("Settings/backupDir", backupDir).toString();
8230 backupDir = QFileDialog::getExistingDirectory(this, tr("Choose Directory"),
8231 backupDir,
8232 QFileDialog::ShowDirsOnly |
8233 QFileDialog::DontResolveSymlinks);
8234 if (!backupDir.isEmpty()) {
8235 settings.setValue("Settings/backupDir", backupDir);
8236
8237 QFileInfo fileInfo;
8238 QString backupFileName;
8239 QString timeStr(QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss"));
8240
8241 fileInfo.setFile(mainApp->dbFileName());
8242 backupFileName = QString("%1/%2_%3.bak").
8243 arg(backupDir).
8244 arg(fileInfo.fileName()).
8245 arg(timeStr);
8246 QFile::copy(mainApp->dbFileName(), backupFileName);
8247
8248 fileInfo.setFile(settings.fileName());
8249 backupFileName = QString("%1/%2_%3.bak").
8250 arg(backupDir).
8251 arg(fileInfo.fileName()).
8252 arg(timeStr);
8253 QFile::copy(settings.fileName(), backupFileName);
8254 }
8255 }
8256
webViewFullScreen(bool on)8257 void MainWindow::webViewFullScreen(bool on)
8258 {
8259 feedsWidget_->setVisible(!on);
8260 pushButtonNull_->setVisible(!on);
8261 tabBarWidget_->setVisible(!on);
8262 currentNewsTab->newsWidget_->setVisible(!on);
8263 currentNewsTab->webControlPanel_->setVisible(!on);
8264 pushButtonNull_->setVisible(!on);
8265 statusBar()->setVisible(!on);
8266 setFullScreen();
8267 }
8268