This commit is contained in:
Martin Rotter 2016-08-19 10:33:02 +02:00
parent 53e3ce8715
commit 6c12059987
23 changed files with 770 additions and 71 deletions

View file

@ -1,6 +1,9 @@
3.3.4
—————
Added:
▪ RSS Guard now can be compiled WITHOUT QtWebEngine module. Minimal Qt required was also lowered to 5.6.0.
Changed:
▪ Big application core refactoring. Many functions rewritten, some bad code removed.

View file

@ -34,10 +34,14 @@
# make install
#
# Variables:
# USE_WEBENGINE - if specified, then QtWebEngine module for internal web browser is used.
# Otherwise simple text component is used and some features will be disabled.
# PREFIX - specifies base folder to which files are copied during "make install"
# step, defaults to "$$OUT_PWD/usr" on Linux and to "$$OUT_PWD/app" on Windows.
# LRELEASE_EXECUTABLE - specifies the name/path of "lrelease" executable, defaults to "lrelease".
#
#
#
# Other information:
# - supports Windows, Linux, Mac OS X,
# - Qt 5.7 and higher is required,
@ -96,6 +100,10 @@ isEmpty(DESTDIR) {
}
}
isEmpty(USE_WEBENGINE) {
USE_WEBENGINE = true
}
message(rssguard: Shadow copy build directory \"$$OUT_PWD\".)
isEmpty(LRELEASE_EXECUTABLE) {
@ -140,7 +148,7 @@ message(rssguard: Prefix directory: \"$$PREFIX\".)
message(rssguard: Build revision: \"$$APP_REVISION\".)
message(rssguard: lrelease executable name: \"$$LRELEASE_EXECUTABLE\".)
QT += core gui widgets webenginewidgets sql network xml printsupport
QT += core gui widgets sql network xml printsupport # webenginewidgets
CONFIG *= c++11 debug_and_release warn_on
DEFINES *= QT_USE_QSTRINGBUILDER QT_USE_FAST_CONCATENATION QT_USE_FAST_OPERATOR_PLUS UNICODE _UNICODE
VERSION = $$APP_VERSION
@ -149,6 +157,15 @@ MOC_DIR = $$OUT_PWD/moc
RCC_DIR = $$OUT_PWD/rcc
UI_DIR = $$OUT_PWD/ui
equals(USE_WEBENGINE, true) {
message(rssguard: Application will be compiled WITH QtWebEngine module.)
QT += webenginewidgets
DEFINES += USE_WEBENGINE
}
else {
message(rssguard: Application will be compiled without QtWebEngine module. Some features will be disabled.)
}
# Make needed tweaks for RC file getting generated on Windows.
win32 {
RC_ICONS = resources/graphics/rssguard.ico
@ -265,12 +282,6 @@ HEADERS += src/core/feeddownloader.h \
src/services/tt-rss/ttrssrecyclebin.h \
src/services/tt-rss/ttrssserviceentrypoint.h \
src/services/tt-rss/ttrssserviceroot.h \
src/gui/webviewer.h \
src/gui/webbrowser.h \
src/network-web/webpage.h \
src/gui/locationlineedit.h \
src/network-web/googlesuggest.h \
src/gui/discoverfeedsbutton.h \
src/gui/settings/settingspanel.h \
src/gui/settings/settingsgeneral.h \
src/gui/settings/settingsdatabase.h \
@ -386,12 +397,6 @@ SOURCES += src/core/feeddownloader.cpp \
src/services/tt-rss/ttrssrecyclebin.cpp \
src/services/tt-rss/ttrssserviceentrypoint.cpp \
src/services/tt-rss/ttrssserviceroot.cpp \
src/gui/webviewer.cpp \
src/gui/webbrowser.cpp \
src/network-web/webpage.cpp \
src/gui/locationlineedit.cpp \
src/network-web/googlesuggest.cpp \
src/gui/discoverfeedsbutton.cpp \
src/gui/settings/settingspanel.cpp \
src/gui/settings/settingsgeneral.cpp \
src/gui/settings/settingsdatabase.cpp \
@ -428,6 +433,34 @@ FORMS += src/gui/toolbareditor.ui \
src/gui/settings/settingsfeedsmessages.ui \
src/gui/settings/settingsdownloads.ui
equals(USE_WEBENGINE, true) {
HEADERS += src/gui/locationlineedit.h \
src/gui/webviewer.h \
src/gui/webbrowser.h \
src/gui/discoverfeedsbutton.h \
src/network-web/googlesuggest.h \
src/network-web/webpage.h
SOURCES += src/gui/locationlineedit.cpp \
src/gui/webviewer.cpp \
src/gui/webbrowser.cpp \
src/gui/discoverfeedsbutton.cpp \
src/network-web/googlesuggest.cpp \
src/network-web/webpage.cpp
}
else {
HEADERS += src/gui/messagepreviewer.h \
src/gui/messagetextbrowser.h \
src/gui/newspaperpreviewer.h
SOURCES += src/gui/messagepreviewer.cpp \
src/gui/messagetextbrowser.cpp \
src/gui/newspaperpreviewer.cpp
FORMS += src/gui/messagepreviewer.ui \
src/gui/newspaperpreviewer.ui
}
TRANSLATIONS += localization/qtbase-cs.ts \
localization/qtbase-da.ts \
localization/qtbase-de.ts \

View file

@ -88,17 +88,19 @@ void MessagesModel::loadMessages(RootItem *item) {
}
bool MessagesModel::setMessageImportantById(int id, RootItem::Importance important) {
Q_UNUSED(important)
for (int i = 0; i < rowCount(); i++) {
int found_id = data(i, MSG_DB_ID_INDEX, Qt::EditRole).toInt();
if (found_id == id) {
bool set = setData(index(i, MSG_DB_IMPORTANT_INDEX), important);
bool result;
if (set) {
if (result = switchMessageImportance(i)) {
emit dataChanged(index(i, 0), index(i, MSG_DB_CUSTOM_HASH_INDEX));
}
return set;
return result;
}
}
@ -285,13 +287,13 @@ bool MessagesModel::setMessageReadById(int id, RootItem::ReadStatus read) {
int found_id = data(i, MSG_DB_ID_INDEX, Qt::EditRole).toInt();
if (found_id == id) {
bool set = setData(index(i, MSG_DB_READ_INDEX), read);
bool result;
if (set) {
if (result = setMessageRead(i, read)) {
emit dataChanged(index(i, 0), index(i, MSG_DB_CUSTOM_HASH_INDEX));
}
return set;
return result;
}
}

View file

@ -173,7 +173,11 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionSelectPreviousMessage;
actions << m_ui->m_actionSelectNextUnreadMessage;
actions << m_ui->m_actionExpandCollapseItem;
#if defined(USE_WEBENGINE)
actions << m_ui->m_actionTabNewWebBrowser;
#endif
actions << m_ui->m_actionTabsCloseAll;
actions << m_ui->m_actionTabsCloseAllExceptCurrent;
@ -200,6 +204,11 @@ void FormMain::prepareMenus() {
qDebug("Creating tray icon menu.");
}
#if !defined(USE_WEBENGINE)
m_ui->m_menuWebBrowserTabs->removeAction(m_ui->m_actionTabNewWebBrowser);
m_ui->m_menuWebBrowserTabs->setTitle(tr("Tabs"));
#endif
}
void FormMain::switchFullscreenMode() {

View file

@ -37,11 +37,17 @@
#include "gui/messagebox.h"
#include "gui/messagestoolbar.h"
#include "gui/feedstoolbar.h"
#include "gui/webbrowser.h"
#include "gui/dialogs/formdatabasecleanup.h"
#include "gui/dialogs/formmain.h"
#include "exceptions/applicationexception.h"
#if defined(USE_WEBENGINE)
#include "gui/webbrowser.h"
#else
#include "gui/messagepreviewer.h"
#endif
#include <QVBoxLayout>
#include <QSplitter>
#include <QToolBar>
@ -65,7 +71,11 @@ FeedMessageViewer::FeedMessageViewer(QWidget *parent)
m_toolBarMessages(new MessagesToolBar(tr("Toolbar for messages"), this)),
m_messagesView(new MessagesView(this)),
m_feedsView(new FeedsView(this)),
#if defined(USE_WEBENGINE)
m_messagesBrowser(new WebBrowser(this)) {
#else
m_messagesBrowser(new MessagePreviewer(this)) {
#endif
initialize();
initializeViews();
loadMessageViewerFonts();
@ -76,9 +86,11 @@ FeedMessageViewer::~FeedMessageViewer() {
qDebug("Destroying FeedMessageViewer instance.");
}
#if defined(USE_WEBENGINE)
WebBrowser *FeedMessageViewer::webBrowser() const {
return m_messagesBrowser;
}
#endif
FeedsView *FeedMessageViewer::feedsView() const {
return m_feedsView;
@ -200,11 +212,12 @@ void FeedMessageViewer::createConnections() {
// Message changers.
connect(m_messagesView, SIGNAL(currentMessageRemoved()), m_messagesBrowser, SLOT(clear()));
connect(m_messagesView, SIGNAL(currentMessageChanged(Message,RootItem*)), m_messagesBrowser, SLOT(loadMessage(Message,RootItem*)));
connect(m_messagesBrowser, SIGNAL(markMessageRead(int,RootItem::ReadStatus)),
m_messagesView->sourceModel(), SLOT(setMessageReadById(int,RootItem::ReadStatus)));
connect(m_messagesBrowser, SIGNAL(markMessageImportant(int,RootItem::Importance)),
m_messagesView->sourceModel(), SLOT(setMessageImportantById(int,RootItem::Importance)));
// If user selects feeds, load their messages.
connect(m_feedsView, SIGNAL(itemSelected(RootItem*)), m_messagesView, SLOT(loadItem(RootItem*)));

View file

@ -24,8 +24,12 @@
#include <QTextBrowser>
#if defined(USE_WEBENGINE)
class WebBrowser;
#else
class MessagePreviewer;
#endif
class MessagesView;
class MessagesToolBar;
class FeedsToolBar;
@ -44,7 +48,10 @@ class FeedMessageViewer : public TabContent {
explicit FeedMessageViewer(QWidget *parent = 0);
virtual ~FeedMessageViewer();
#if defined(USE_WEBENGINE)
WebBrowser *webBrowser() const;
#endif
FeedsView *feedsView() const;
MessagesView *messagesView() const;
MessagesToolBar *messagesToolBar() const;
@ -102,7 +109,12 @@ class FeedMessageViewer : public TabContent {
FeedsView *m_feedsView;
QWidget *m_feedsWidget;
QWidget *m_messagesWidget;
#if defined(USE_WEBENGINE)
WebBrowser *m_messagesBrowser;
#else
MessagePreviewer *m_messagesBrowser;
#endif
};
#endif // FEEDMESSAGEVIEWER_H

192
src/gui/messagepreviewer.cpp Executable file
View file

@ -0,0 +1,192 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
//
// RSS Guard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// RSS Guard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
#include "gui/messagepreviewer.h"
#include "miscellaneous/application.h"
#include "network-web/webfactory.h"
#include "miscellaneous/databasequeries.h"
#include "gui/messagebox.h"
#include "gui/dialogs/formmain.h"
#include "services/abstract/serviceroot.h"
#include <QScrollBar>
#include <QToolBar>
#include <QToolTip>
void MessagePreviewer::createConnections() {
connect(m_ui->m_txtMessage, &QTextBrowser::anchorClicked, [=](const QUrl &url) {
if (!url.isEmpty()) {
// User clicked some URL. Open it in external browser or download?
MessageBox box(qApp->mainForm());
box.setText(tr("You clicked some link. You can download the link contents or open it in external web browser."));
box.setInformativeText(tr("What action do you want to take?"));
box.setDetailedText(url.toString());
QAbstractButton *btn_open = box.addButton(tr("Open in external browser"), QMessageBox::ActionRole);
QAbstractButton *btn_download = box.addButton(tr("Download"), QMessageBox::ActionRole);
QAbstractButton *btn_cancel = box.addButton(QMessageBox::Cancel);
box.setDefaultButton(QMessageBox::Cancel);
box.exec();
if (box.clickedButton() == btn_open) {
WebFactory::instance()->openUrlInExternalBrowser(url.toString());
}
else if (box.clickedButton() == btn_download) {
qApp->downloadManager()->download(url);
}
btn_download->deleteLater();
btn_open->deleteLater();
btn_cancel->deleteLater();
}
else {
MessageBox::show(qApp->mainForm(), QMessageBox::Warning, tr("Incorrect link"),
tr("Selected hyperlink is invalid."));
}
});
connect(m_actionMarkRead = m_toolBar->addAction(qApp->icons()->fromTheme("mail-mark-read"), tr("Mark message as read")),
&QAction::triggered,
this,
&MessagePreviewer::markMessageAsRead);
connect(m_actionMarkUnread = m_toolBar->addAction(qApp->icons()->fromTheme("mail-mark-unread"), tr("Mark message as unread")),
&QAction::triggered,
this,
&MessagePreviewer::markMessageAsUnread);
connect(m_actionSwitchImportance = m_toolBar->addAction(qApp->icons()->fromTheme("mail-mark-important"), tr("Switch message importance")),
&QAction::triggered,
this,
&MessagePreviewer::switchMessageImportance);
connect(m_ui->m_txtMessage,
static_cast<void (QTextBrowser::*)(const QString&)>(&QTextBrowser::highlighted),
[=](const QString &text) {
Q_UNUSED(text)
QToolTip::showText(QCursor::pos(), tr("Click this link to download it or open it with external browser."), this);
});
}
MessagePreviewer::MessagePreviewer(QWidget *parent) : QWidget(parent),
m_ui(new Ui::MessagePreviewer), m_pictures(QStringList()) {
m_ui->setupUi(this);
m_ui->m_txtMessage->viewport()->setAutoFillBackground(true);
m_toolBar = new QToolBar(this);
m_toolBar->setOrientation(Qt::Vertical);
m_ui->m_layout->addWidget(m_toolBar, 0, 0, -1, 1);
createConnections();
m_actionSwitchImportance->setCheckable(true);
reloadFontSettings();
clear();
}
MessagePreviewer::~MessagePreviewer() {
}
void MessagePreviewer::reloadFontSettings() {
const Settings *settings = qApp->settings();
QFont fon;
fon.fromString(settings->value(GROUP(Messages),
SETTING(Messages::PreviewerFontStandard)).toString());
m_ui->m_txtMessage->setFont(fon);
}
void MessagePreviewer::clear() {
m_ui->m_txtMessage->clear();
m_pictures.clear();
hide();
}
void MessagePreviewer::hideToolbar() {
m_toolBar->setVisible(false);
}
void MessagePreviewer::loadMessage(const Message &message, RootItem *root) {
m_message = message;
m_root = root;
if (!m_root.isNull()) {
m_actionSwitchImportance->setChecked(m_message.m_isImportant);
m_ui->m_txtMessage->setHtml(prepareHtmlForMessage(m_message));
updateButtons();
show();
m_ui->m_txtMessage->verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum);
}
}
void MessagePreviewer::markMessageAsRead() {
if (!m_root.isNull()) {
emit markMessageRead(m_message.m_id, RootItem::Read);
m_message.m_isRead = true;
updateButtons();
}
}
void MessagePreviewer::markMessageAsUnread() {
if (!m_root.isNull()) {
emit markMessageRead(m_message.m_id, RootItem::Unread);
m_message.m_isRead = false;
updateButtons();
}
}
void MessagePreviewer::switchMessageImportance(bool checked) {
if (!m_root.isNull()) {
emit markMessageImportant(m_message.m_id, checked ? RootItem::Important : RootItem::NotImportant);
m_message.m_isImportant = checked;
}
}
void MessagePreviewer::updateButtons() {
m_actionMarkRead->setEnabled(!m_message.m_isRead);
m_actionMarkUnread->setEnabled(m_message.m_isRead);
}
QString MessagePreviewer::prepareHtmlForMessage(const Message &message) {
QString html = QString("<h2 align=\"center\">%1</h2>").arg(message.m_title);
html += QString("[url] <a href=\"%1\">%1</a><br/>").arg(message.m_url);
foreach (const Enclosure &enc, message.m_enclosures) {
html += QString("[%2] <a href=\"%1\">%1</a><br/>").arg(enc.m_url, enc.m_mimeType);
}
int offset = 0;
QRegExp imgTagRegex("\\<img[^\\>]*src\\s*=\\s*\"([^\"]*)\"[^\\>]*\\>", Qt::CaseInsensitive);
imgTagRegex.setMinimal(true);
while( (offset = imgTagRegex.indexIn(message.m_contents, offset)) != -1){
m_pictures.append(imgTagRegex.cap(1));
offset += imgTagRegex.matchedLength();
html += QString("[%2] <a href=\"%1\">%1</a><br/>").arg(imgTagRegex.cap(1), tr("image"));
}
html += "<br/>";
html += message.m_contents;
return html;
}

77
src/gui/messagepreviewer.h Executable file
View file

@ -0,0 +1,77 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
//
// RSS Guard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// RSS Guard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
#ifndef MESSAGEPREVIEWER_H
#define MESSAGEPREVIEWER_H
#include <QWidget>
#include "ui_messagepreviewer.h"
#include "core/message.h"
#include "services/abstract/rootitem.h"
#include <QPointer>
namespace Ui {
class MessagePreviewer;
}
class QToolBar;
class MessagePreviewer : public QWidget {
Q_OBJECT
public:
explicit MessagePreviewer(QWidget *parent = 0);
virtual ~MessagePreviewer();
void reloadFontSettings();
public slots:
void clear();
void hideToolbar();
void loadMessage(const Message &message, RootItem *root);
private slots:
void markMessageAsRead();
void markMessageAsUnread();
void switchMessageImportance(bool checked);
signals:
void markMessageRead(int id, RootItem::ReadStatus read);
void markMessageImportant(int id, RootItem::Importance important);
void requestMessageListReload(bool mark_current_as_read);
private:
void createConnections();
void updateButtons();
QString prepareHtmlForMessage(const Message &message);
QToolBar *m_toolBar;
QScopedPointer<Ui::MessagePreviewer> m_ui;
Message m_message;
QStringList m_pictures;
QPointer<RootItem> m_root;
QAction *m_actionMarkRead;
QAction *m_actionMarkUnread;
QAction *m_actionSwitchImportance;
};
#endif // MESSAGEPREVIEWER_H

56
src/gui/messagepreviewer.ui Executable file
View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MessagePreviewer</class>
<widget class="QWidget" name="MessagePreviewer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>502</width>
<height>396</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="m_layout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="MessageTextBrowser" name="m_txtMessage">
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
<property name="openLinks">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MessageTextBrowser</class>
<extends>QTextBrowser</extends>
<header>messagetextbrowser.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View file

@ -25,7 +25,7 @@
#include "network-web/webfactory.h"
#include "gui/dialogs/formmain.h"
#include "gui/messagebox.h"
#include "gui/webbrowser.h"
#include "gui/styleditemdelegatewithoutfocus.h"
#include <QKeyEvent>
@ -194,7 +194,9 @@ void MessagesView::mousePressEvent(QMouseEvent *event) {
const QModelIndex mapped_index = m_proxyModel->mapToSource(clicked_index);
if (mapped_index.column() == MSG_DB_IMPORTANT_INDEX) {
m_sourceModel->switchMessageImportance(mapped_index.row());
if (m_sourceModel->switchMessageImportance(mapped_index.row())) {
emit currentMessageChanged(m_sourceModel->messageAt(mapped_index.row()), m_sourceModel->loadedItem());
}
}
}
@ -502,17 +504,6 @@ void MessagesView::filterMessages(MessagesModel::MessageHighlighter filter) {
m_sourceModel->highlightMessages(filter);
}
void MessagesView::createNewspaperView(RootItem *selected_item, const QList<Message> &messages) {
WebBrowser *prev = new WebBrowser(this);
int index = qApp->mainForm()->tabWidget()->addTab(prev,
qApp->icons()->fromTheme(QSL("text-x-script")),
tr("Newspaper view"),
TabBar::Closable);
qApp->mainForm()->tabWidget()->setCurrentIndex(index);
prev->loadMessages(messages, selected_item);
}
void MessagesView::adjustColumns() {
if (header()->count() > 0 && !m_columnsAdjusted) {
m_columnsAdjusted = true;

View file

@ -78,8 +78,6 @@ class MessagesView : public QTreeView {
void searchMessages(const QString &pattern);
void filterMessages(MessagesModel::MessageHighlighter filter);
void createNewspaperView(RootItem *selected_item, const QList<Message> &messages);
private slots:
// Marks given indexes as selected.
void reselectIndexes(const QModelIndexList &indexes);

35
src/gui/messagetextbrowser.cpp Executable file
View file

@ -0,0 +1,35 @@
#include "gui/messagetextbrowser.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "network-web/networkfactory.h"
MessageTextBrowser::MessageTextBrowser(QWidget *parent) : QTextBrowser(parent) {
}
MessageTextBrowser::~MessageTextBrowser() {
}
QVariant MessageTextBrowser::loadResource(int type, const QUrl &name) {
Q_UNUSED(name)
switch (type) {
case QTextDocument::ImageResource: {
if (m_imagePlaceholder.isNull()) {
m_imagePlaceholder = qApp->icons()->miscPixmap(QSL("image-placeholder")).scaledToWidth(20, Qt::FastTransformation);
}
emit imageRequested(name.toString());
return m_imagePlaceholder;
}
default:
return QVariant();
}
}
void MessageTextBrowser::wheelEvent(QWheelEvent *e) {
QTextBrowser::wheelEvent(e);
qApp->settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, font().toString());
}

27
src/gui/messagetextbrowser.h Executable file
View file

@ -0,0 +1,27 @@
#ifndef MESSAGETEXTBROWSER_H
#define MESSAGETEXTBROWSER_H
#include <QTextBrowser>
class MessageTextBrowser : public QTextBrowser {
Q_OBJECT
public:
explicit MessageTextBrowser(QWidget *parent = 0);
virtual ~MessageTextBrowser();
QVariant loadResource(int type, const QUrl &name);
signals:
void imageRequested(const QString &image_url);
protected:
void wheelEvent(QWheelEvent *e);
private:
QPixmap m_imagePlaceholder;
};
#endif // MESSAGETEXTBROWSER_H

66
src/gui/newspaperpreviewer.cpp Executable file
View file

@ -0,0 +1,66 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
//
// RSS Guard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// RSS Guard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
#include "gui/newspaperpreviewer.h"
#include "gui/messagepreviewer.h"
#include "gui/dialogs/formmain.h"
#include "miscellaneous/application.h"
#include <QScrollBar>
NewspaperPreviewer::NewspaperPreviewer(RootItem *root, QList<Message> messages, QWidget *parent)
: TabContent(parent), m_ui(new Ui::NewspaperPreviewer), m_root(root), m_messages(messages) {
m_ui->setupUi(this);
connect(m_ui->m_btnShowMoreMessages, SIGNAL(clicked(bool)), this, SLOT(showMoreMessages()));
showMoreMessages();
}
NewspaperPreviewer::~NewspaperPreviewer() {
}
void NewspaperPreviewer::showMoreMessages() {
if (!m_root.isNull()) {
int current_scroll = m_ui->scrollArea->verticalScrollBar()->value();
for (int i = 0; i < 10 && !m_messages.isEmpty(); i++) {
Message msg = m_messages.takeFirst();
MessagePreviewer *prev = new MessagePreviewer(this);
QMargins margins = prev->layout()->contentsMargins();
connect(prev, SIGNAL(requestMessageListReload(bool)), this, SIGNAL(requestMessageListReload(bool)));
margins.setRight(0);
prev->hideToolbar();
prev->layout()->setContentsMargins(margins);
prev->setFixedHeight(300);
prev->loadMessage(msg, m_root);
m_ui->m_layout->insertWidget(m_ui->m_layout->count() - 2, prev);
}
m_ui->m_btnShowMoreMessages->setText(tr("Show more messages (%n remaining)", "", m_messages.size()));
m_ui->m_btnShowMoreMessages->setEnabled(!m_messages.isEmpty());
m_ui->scrollArea->verticalScrollBar()->setValue(current_scroll);
}
else {
qApp->showGuiMessage(tr("Cannot show more messages"),
tr("Cannot show more messages because parent feed was removed."),
QSystemTrayIcon::Warning,
qApp->mainForm(), true);
}
}

58
src/gui/newspaperpreviewer.h Executable file
View file

@ -0,0 +1,58 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2016 by Martin Rotter <rotter.martinos@gmail.com>
//
// RSS Guard is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// RSS Guard is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
#ifndef NEWSPAPERPREVIEWER_H
#define NEWSPAPERPREVIEWER_H
#include <QWidget>
#include "gui/tabcontent.h"
#include "ui_newspaperpreviewer.h"
#include "core/message.h"
#include "services/abstract/rootitem.h"
#include <QPointer>
namespace Ui {
class NewspaperPreviewer;
}
class RootItem;
class NewspaperPreviewer : public TabContent {
Q_OBJECT
public:
explicit NewspaperPreviewer(RootItem *root, QList<Message> messages, QWidget *parent = 0);
virtual ~NewspaperPreviewer();
private slots:
void showMoreMessages();
signals:
void requestMessageListReload(bool mark_current_as_read);
private:
QScopedPointer<Ui::NewspaperPreviewer> m_ui;
QPointer<RootItem> m_root;
QList<Message> m_messages;
};
#endif // NEWSPAPERPREVIEWER_H

102
src/gui/newspaperpreviewer.ui Executable file
View file

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewspaperPreviewer</class>
<widget class="QWidget" name="NewspaperPreviewer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>398</width>
<height>298</height>
</rect>
</property>
<layout class="QVBoxLayout" name="m_layout">
<item>
<layout class="QHBoxLayout" name="m_btnLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_btnShowMoreMessages">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>246</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -20,8 +20,9 @@
#include <QWidget>
#if defined(USE_WEBENGINE)
class WebBrowser;
#endif
// Base class for all widgets which are placed inside tabs of TabWidget
class TabContent : public QWidget {
@ -43,9 +44,11 @@ class TabContent : public QWidget {
m_index = index;
}
#if defined(USE_WEBENGINE)
// Obtains instance contained in this TabContent or nullptr.
// This can be used for obtaining the menu from the instance and so on.
virtual WebBrowser *webBrowser() const = 0;
#endif
protected:
int m_index;

View file

@ -26,10 +26,17 @@
#include "gui/messagesview.h"
#include "gui/feedsview.h"
#include "gui/feedmessageviewer.h"
#include "gui/webbrowser.h"
#include "gui/plaintoolbutton.h"
#include "gui/dialogs/formmain.h"
#if defined(USE_WEBENGINE)
#include "gui/webbrowser.h"
#else
#include "network-web/webfactory.h"
#include "gui/newspaperpreviewer.h"
#endif
#include <QMenu>
#include <QToolButton>
@ -200,11 +207,19 @@ void TabWidget::closeAllTabs() {
}
int TabWidget::addNewspaperView(RootItem *root, const QList<Message> &messages) {
#if defined(USE_WEBENGINE)
WebBrowser *prev = new WebBrowser(this);
#else
NewspaperPreviewer *prev = new NewspaperPreviewer(root, messages, this);
#endif
int index = addTab(prev, qApp->icons()->fromTheme(QSL("format-justify-fill")), tr("Newspaper view"), TabBar::Closable);
setCurrentIndex(index);
#if defined(USE_WEBENGINE)
prev->loadMessages(messages, root);
#endif
return index;
}
@ -222,6 +237,8 @@ int TabWidget::addLinkedBrowser(const QString &initial_url) {
}
int TabWidget::addBrowser(bool move_after_current, bool make_active, const QUrl &initial_url) {
#if defined(USE_WEBENGINE)
// Create new WebBrowser.
WebBrowser *browser = new WebBrowser(this);
int final_index;
@ -258,6 +275,14 @@ int TabWidget::addBrowser(bool move_after_current, bool make_active, const QUrl
}
return final_index;
#else
Q_UNUSED(move_after_current)
Q_UNUSED(make_active)
WebFactory::instance()->openUrlInExternalBrowser(initial_url.toString());
return -1;
#endif
}
void TabWidget::removeTab(int index, bool clear_from_memory) {

View file

@ -262,19 +262,8 @@ void WebBrowser::markMessageAsRead(int id, bool read) {
if (!m_root.isNull()) {
Message *msg = findMessage(id);
if (msg != nullptr && m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(),
QList<Message>() << *msg,
read ? RootItem::Read : RootItem::Unread)) {
DatabaseQueries::markMessagesReadUnread(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(msg->m_id),
read ? RootItem::Read : RootItem::Unread);
m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(),
QList<Message>() << *msg,
read ? RootItem::Read : RootItem::Unread);
emit markMessageRead(msg->m_id, read ? RootItem::Read : RootItem::Unread);
msg->m_isRead = read ? RootItem::Read : RootItem::Unread;
}
emit markMessageRead(msg->m_id, read ? RootItem::Read : RootItem::Unread);
msg->m_isRead = read ? RootItem::Read : RootItem::Unread;
}
}
@ -282,23 +271,8 @@ void WebBrowser::switchMessageImportance(int id, bool checked) {
if (!m_root.isNull()) {
Message *msg = findMessage(id);
if (msg != nullptr && m_root->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(*msg,
msg->m_isImportant ?
RootItem::NotImportant :
RootItem::Important))) {
DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(msg->m_id));
m_root->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(*msg,
msg->m_isImportant ?
RootItem::NotImportant :
RootItem::Important));
emit markMessageImportant(msg->m_id, msg->m_isImportant ? RootItem::NotImportant : RootItem::Important);
msg->m_isImportant = checked;
}
emit markMessageImportant(msg->m_id, msg->m_isImportant ? RootItem::NotImportant : RootItem::Important);
msg->m_isImportant = checked;
}
}

View file

@ -137,7 +137,14 @@ void WebViewer::clear() {
QWebEngineView *WebViewer::createWindow(QWebEnginePage::WebWindowType type) {
Q_UNUSED(type)
return qApp->mainForm()->tabWidget()->widget(qApp->mainForm()->tabWidget()->addBrowser(false, false))->webBrowser()->viewer();
int index = qApp->mainForm()->tabWidget()->addBrowser(false, false);
if (index >= 0) {
return qApp->mainForm()->tabWidget()->widget(qApp->mainForm()->tabWidget()->addBrowser(false, false))->webBrowser()->viewer();
}
else {
return nullptr;
}
}
void WebViewer::wheelEvent(QWheelEvent *event) {

View file

@ -37,9 +37,11 @@
#include <QSessionManager>
#include <QThread>
#include <QProcess>
#if defined(USE_WEBENGINE)
#include <QWebEngineProfile>
#include <QWebEngineDownloadItem>
#endif
Application::Application(const QString &id, bool run_minimal_without_gui, int &argc, char **argv)
: QtSingleApplication(id, argc, argv),
@ -50,8 +52,11 @@ Application::Application(const QString &id, bool run_minimal_without_gui, int &a
connect(this, SIGNAL(aboutToQuit()), this, SLOT(onAboutToQuit()));
connect(this, SIGNAL(commitDataRequest(QSessionManager&)), this, SLOT(onCommitData(QSessionManager&)));
connect(this, SIGNAL(saveStateRequest(QSessionManager&)), this, SLOT(onSaveState(QSessionManager&)));
#if defined(USE_WEBENGINE)
connect(QWebEngineProfile::defaultProfile(), SIGNAL(downloadRequested(QWebEngineDownloadItem*)),
this, SLOT(downloadRequested(QWebEngineDownloadItem*)));
#endif
}
Application::~Application() {
@ -361,11 +366,13 @@ void Application::onAboutToQuit() {
}
}
#if defined(USE_WEBENGINE)
void Application::downloadRequested(QWebEngineDownloadItem *download_item) {
downloadManager()->download(download_item->url());
download_item->cancel();
download_item->deleteLater();
}
#endif
void Application::onFeedUpdatesStarted() {
}

View file

@ -115,7 +115,10 @@ class Application : public QtSingleApplication {
void onCommitData(QSessionManager &manager);
void onSaveState(QSessionManager &manager);
void onAboutToQuit();
#if defined(USE_WEBENGINE)
void downloadRequested(QWebEngineDownloadItem*download_item);
#endif
void onFeedUpdatesStarted();
void onFeedUpdatesProgress(const Feed *feed, int current, int total);

View file

@ -91,6 +91,10 @@ class DownloadItem : public QWidget {
bool m_canceledFileSelect;
};
#if defined(USE_WEBENGINE)
class WebBrowser;
#endif
class DownloadManager : public TabContent {
Q_OBJECT
Q_PROPERTY(RemovePolicy removePolicy READ removePolicy WRITE setRemovePolicy)
@ -108,9 +112,11 @@ class DownloadManager : public TabContent {
explicit DownloadManager(QWidget *parent = 0);
virtual ~DownloadManager();
#if defined(USE_WEBENGINE)
WebBrowser *webBrowser() const {
return nullptr;
}
#endif
QNetworkAccessManager *networkManager() const;