Reformated using astyle, added some astyle scripts.

This commit is contained in:
Martin Rotter 2017-07-21 06:53:23 +02:00
parent 14473722b0
commit 208284e80d
304 changed files with 34084 additions and 34464 deletions

26
.astylerc Executable file
View File

@ -0,0 +1,26 @@
--style=java
--indent=spaces=2
--indent-classes
--indent-namespaces
--indent-switches
--indent-labels
--indent-preproc-define
--indent-col1-comments
--max-continuation-indent=100
--break-blocks=all
--unpad-paren
--delete-empty-lines
--pad-oper
--pad-comma
--pad-header
--align-pointer=type
--align-reference=type
--break-closing-braces
--break-one-line-headers
--add-braces
--convert-tabs
--close-templates
--max-code-length=200
--lineend=linux
-t -p
-M60Ucv

64
astyle-format-all.sh Executable file
View File

@ -0,0 +1,64 @@
#!/bin/bash
#
# This file is part of RSS Guard.
#
# Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
# Copyright (C) 2010-2014 by David Rosca <nowrep@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/>.
function usage {
echo "Usage: $0 \"root-directory\"..."
exit 1
}
if [ $# -eq 0 ]; then
usage
fi
ASTYLE_CMD="astyle"
ASTYLE_RC=".astylerc"
# Check all args.
for dir in "$@"; do
if [ ! -d "${dir}" ]; then
echo "\"${dir}\" is not a directory..."
usage
fi
done
# Run the thing.
for dir in "$@"; do
pushd "${dir}"
if [ ! -r "$ASTYLE_RC" ]; then
echo "No $ASTYLE_RC in pwd \"$PWD\"..."
continue
fi
for f in $(find . \
-name '*.c' \
-o -name '*.cc' \
-o -name '*.cpp' \
-o -name '*.h' \
-o -name '*.hh' \
-o -name '*.hpp'); do
"${ASTYLE_CMD}" --options="$ASTYLE_RC" "${f}"
done
# Remove backup files.
find . -name "*.orig" | xargs --no-run-if-empty rm -v
popd
done

View File

@ -1,178 +1,170 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/feeddownloader.h"
#include "services/abstract/feed.h"
#include "definitions/definitions.h"
#include <QThread>
#include <QDebug>
#include <QThreadPool>
#include <QMutexLocker>
#include <QString>
FeedDownloader::FeedDownloader(QObject *parent)
: QObject(parent), m_feeds(QList<Feed*>()), m_mutex(new QMutex()), m_threadPool(new QThreadPool(this)),
m_results(FeedDownloadResults()), m_feedsUpdated(0),
m_feedsUpdating(0), m_feedsOriginalCount(0) {
qRegisterMetaType<FeedDownloadResults>("FeedDownloadResults");
m_threadPool->setMaxThreadCount(FEED_DOWNLOADER_MAX_THREADS);
}
FeedDownloader::~FeedDownloader() {
m_mutex->tryLock();
m_mutex->unlock();
delete m_mutex;
qDebug("Destroying FeedDownloader instance.");
}
bool FeedDownloader::isUpdateRunning() const {
return !m_feeds.isEmpty() || m_feedsUpdating > 0;
}
void FeedDownloader::updateAvailableFeeds() {
while (!m_feeds.isEmpty()) {
connect(m_feeds.first(), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished,
(Qt::ConnectionType) (Qt::UniqueConnection | Qt::AutoConnection));
if (m_threadPool->tryStart(m_feeds.first())) {
m_feeds.removeFirst();
m_feedsUpdating++;
}
else {
// We want to start update of some feeds but all working threads are occupied.
break;
}
}
}
void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) {
QMutexLocker locker(m_mutex);
if (feeds.isEmpty()) {
qDebug("No feeds to update in worker thread, aborting update.");
finalizeUpdate();
}
else {
qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'.";
m_feeds = feeds;
m_feedsOriginalCount = m_feeds.size();
m_results.clear();
m_feedsUpdated = m_feedsUpdating = 0;
// Job starts now.
emit updateStarted();
updateAvailableFeeds();
}
}
void FeedDownloader::stopRunningUpdate() {
m_threadPool->clear();
m_feeds.clear();
}
void FeedDownloader::oneFeedUpdateFinished(const QList<Message> &messages, bool error_during_obtaining) {
QMutexLocker locker(m_mutex);
m_feedsUpdated++;
m_feedsUpdating--;
Feed *feed = qobject_cast<Feed*>(sender());
disconnect(feed, &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished);
// Now, we check if there are any feeds we would like to update too.
updateAvailableFeeds();
// Now make sure, that messages are actually stored to SQL in a locked state.
qDebug().nospace() << "Saving messages of feed "
<< feed->id() << " in thread: \'"
<< QThread::currentThreadId() << "\'.";
int updated_messages = feed->updateMessages(messages, error_during_obtaining);
/*
QMetaObject::invokeMethod(feed, "updateMessages", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, updated_messages),
Q_ARG(QList<Message>, messages));
*/
if (updated_messages > 0) {
m_results.appendUpdatedFeed(QPair<QString,int>(feed->title(), updated_messages));
}
qDebug("Made progress in feed updates, total feeds count %d/%d (id of feed is %d).", m_feedsUpdated, m_feedsOriginalCount, feed->id());
emit updateProgress(feed, m_feedsUpdated, m_feedsOriginalCount);
if (m_feeds.isEmpty() && m_feedsUpdating <= 0) {
finalizeUpdate();
}
}
void FeedDownloader::finalizeUpdate() {
qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'.";
m_results.sort();
// Update of feeds has finished.
// NOTE: This means that now "update lock" can be unlocked
// and feeds can be added/edited/deleted and application
// can eventually quit.
emit updateFinished(m_results);
}
FeedDownloadResults::FeedDownloadResults() : m_updatedFeeds(QList<QPair<QString,int> >()) {
}
QString FeedDownloadResults::overview(int how_many_feeds) const {
QStringList result;
for (int i = 0, number_items_output = qMin(how_many_feeds, m_updatedFeeds.size()); i < number_items_output; i++) {
result.append(m_updatedFeeds.at(i).first + QSL(": ") + QString::number(m_updatedFeeds.at(i).second));
}
QString res_str = result.join(QSL("\n"));
if (m_updatedFeeds.size() > how_many_feeds) {
res_str += QObject::tr("\n\n+ %n other feeds.", 0, m_updatedFeeds.size() - how_many_feeds);
}
return res_str;
}
void FeedDownloadResults::appendUpdatedFeed(const QPair<QString,int> &feed) {
m_updatedFeeds.append(feed);
}
void FeedDownloadResults::sort() {
qSort(m_updatedFeeds.begin(), m_updatedFeeds.end(), FeedDownloadResults::lessThan);
}
bool FeedDownloadResults::lessThan(const QPair<QString, int> &lhs, const QPair<QString, int> &rhs) {
return lhs.second > rhs.second;
}
void FeedDownloadResults::clear() {
m_updatedFeeds.clear();
}
QList<QPair<QString,int> > FeedDownloadResults::updatedFeeds() const {
return m_updatedFeeds;
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/feeddownloader.h"
#include "services/abstract/feed.h"
#include "definitions/definitions.h"
#include <QThread>
#include <QDebug>
#include <QThreadPool>
#include <QMutexLocker>
#include <QString>
FeedDownloader::FeedDownloader(QObject* parent)
: QObject(parent), m_feeds(QList<Feed*>()), m_mutex(new QMutex()), m_threadPool(new QThreadPool(this)),
m_results(FeedDownloadResults()), m_feedsUpdated(0),
m_feedsUpdating(0), m_feedsOriginalCount(0) {
qRegisterMetaType<FeedDownloadResults>("FeedDownloadResults");
m_threadPool->setMaxThreadCount(FEED_DOWNLOADER_MAX_THREADS);
}
FeedDownloader::~FeedDownloader() {
m_mutex->tryLock();
m_mutex->unlock();
delete m_mutex;
qDebug("Destroying FeedDownloader instance.");
}
bool FeedDownloader::isUpdateRunning() const {
return !m_feeds.isEmpty() || m_feedsUpdating > 0;
}
void FeedDownloader::updateAvailableFeeds() {
while (!m_feeds.isEmpty()) {
connect(m_feeds.first(), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished,
(Qt::ConnectionType)(Qt::UniqueConnection | Qt::AutoConnection));
if (m_threadPool->tryStart(m_feeds.first())) {
m_feeds.removeFirst();
m_feedsUpdating++;
}
else {
// We want to start update of some feeds but all working threads are occupied.
break;
}
}
}
void FeedDownloader::updateFeeds(const QList<Feed*>& feeds) {
QMutexLocker locker(m_mutex);
if (feeds.isEmpty()) {
qDebug("No feeds to update in worker thread, aborting update.");
finalizeUpdate();
}
else {
qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'.";
m_feeds = feeds;
m_feedsOriginalCount = m_feeds.size();
m_results.clear();
m_feedsUpdated = m_feedsUpdating = 0;
// Job starts now.
emit updateStarted();
updateAvailableFeeds();
}
}
void FeedDownloader::stopRunningUpdate() {
m_threadPool->clear();
m_feeds.clear();
}
void FeedDownloader::oneFeedUpdateFinished(const QList<Message>& messages, bool error_during_obtaining) {
QMutexLocker locker(m_mutex);
m_feedsUpdated++;
m_feedsUpdating--;
Feed* feed = qobject_cast<Feed*>(sender());
disconnect(feed, &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished);
// Now, we check if there are any feeds we would like to update too.
updateAvailableFeeds();
// Now make sure, that messages are actually stored to SQL in a locked state.
qDebug().nospace() << "Saving messages of feed "
<< feed->id() << " in thread: \'"
<< QThread::currentThreadId() << "\'.";
int updated_messages = feed->updateMessages(messages, error_during_obtaining);
/*
QMetaObject::invokeMethod(feed, "updateMessages", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, updated_messages),
Q_ARG(QList<Message>, messages));
*/
if (updated_messages > 0) {
m_results.appendUpdatedFeed(QPair<QString, int>(feed->title(), updated_messages));
}
qDebug("Made progress in feed updates, total feeds count %d/%d (id of feed is %d).", m_feedsUpdated, m_feedsOriginalCount, feed->id());
emit updateProgress(feed, m_feedsUpdated, m_feedsOriginalCount);
if (m_feeds.isEmpty() && m_feedsUpdating <= 0) {
finalizeUpdate();
}
}
void FeedDownloader::finalizeUpdate() {
qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'.";
m_results.sort();
// Update of feeds has finished.
// NOTE: This means that now "update lock" can be unlocked
// and feeds can be added/edited/deleted and application
// can eventually quit.
emit updateFinished(m_results);
}
FeedDownloadResults::FeedDownloadResults() : m_updatedFeeds(QList<QPair<QString, int>>()) {
}
QString FeedDownloadResults::overview(int how_many_feeds) const {
QStringList result;
for (int i = 0, number_items_output = qMin(how_many_feeds, m_updatedFeeds.size()); i < number_items_output; i++) {
result.append(m_updatedFeeds.at(i).first + QSL(": ") + QString::number(m_updatedFeeds.at(i).second));
}
QString res_str = result.join(QSL("\n"));
if (m_updatedFeeds.size() > how_many_feeds) {
res_str += QObject::tr("\n\n+ %n other feeds.", 0, m_updatedFeeds.size() - how_many_feeds);
}
return res_str;
}
void FeedDownloadResults::appendUpdatedFeed(const QPair<QString, int>& feed) {
m_updatedFeeds.append(feed);
}
void FeedDownloadResults::sort() {
qSort(m_updatedFeeds.begin(), m_updatedFeeds.end(), FeedDownloadResults::lessThan);
}
bool FeedDownloadResults::lessThan(const QPair<QString, int>& lhs, const QPair<QString, int>& rhs) {
return lhs.second > rhs.second;
}
void FeedDownloadResults::clear() {
m_updatedFeeds.clear();
}
QList<QPair<QString, int>> FeedDownloadResults::updatedFeeds() const {
return m_updatedFeeds;
}

View File

@ -1,104 +1,104 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDDOWNLOADER_H
#define FEEDDOWNLOADER_H
#include <QObject>
#include <QPair>
#include "core/message.h"
class Feed;
class QThreadPool;
class QMutex;
// Represents results of batch feed updates.
class FeedDownloadResults {
public:
explicit FeedDownloadResults();
QList<QPair<QString,int> > updatedFeeds() const;
QString overview(int how_many_feeds) const;
void appendUpdatedFeed(const QPair<QString,int> &feed);
void sort();
void clear();
static bool lessThan(const QPair<QString,int> &lhs, const QPair<QString,int> &rhs);
private:
// QString represents title if the feed, int represents count of newly downloaded messages.
QList<QPair<QString,int> > m_updatedFeeds;
};
// This class offers means to "update" feeds and "special" categories.
// NOTE: This class is used within separate thread.
class FeedDownloader : public QObject {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedDownloader(QObject *parent = 0);
virtual ~FeedDownloader();
bool isUpdateRunning() const;
public slots:
// Performs update of all feeds from the "feeds" parameter.
// New messages are downloaded for each feed and they
// are stored persistently in the database.
// Appropriate signals are emitted.
void updateFeeds(const QList<Feed*> &feeds);
// Stops running update.
void stopRunningUpdate();
private slots:
void oneFeedUpdateFinished(const QList<Message> &messages, bool error_during_obtaining);
signals:
// Emitted if feed updates started.
void updateStarted();
// Emitted if all items from update queue are
// processed.
void updateFinished(FeedDownloadResults updated_feeds);
// Emitted if any item is processed.
// "Current" number indicates count of processed feeds
// and "total" number indicates total number of feeds
// which were in the initial queue.
void updateProgress(const Feed *feed, int current, int total);
private:
void updateAvailableFeeds();
void finalizeUpdate();
QList<Feed*> m_feeds;
QMutex *m_mutex;
QThreadPool *m_threadPool;
FeedDownloadResults m_results;
int m_feedsUpdated;
int m_feedsUpdating;
int m_feedsOriginalCount;
};
#endif // FEEDDOWNLOADER_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDDOWNLOADER_H
#define FEEDDOWNLOADER_H
#include <QObject>
#include <QPair>
#include "core/message.h"
class Feed;
class QThreadPool;
class QMutex;
// Represents results of batch feed updates.
class FeedDownloadResults {
public:
explicit FeedDownloadResults();
QList<QPair<QString, int>> updatedFeeds() const;
QString overview(int how_many_feeds) const;
void appendUpdatedFeed(const QPair<QString, int>& feed);
void sort();
void clear();
static bool lessThan(const QPair<QString, int>& lhs, const QPair<QString, int>& rhs);
private:
// QString represents title if the feed, int represents count of newly downloaded messages.
QList<QPair<QString, int>> m_updatedFeeds;
};
// This class offers means to "update" feeds and "special" categories.
// NOTE: This class is used within separate thread.
class FeedDownloader : public QObject {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedDownloader(QObject* parent = 0);
virtual ~FeedDownloader();
bool isUpdateRunning() const;
public slots:
// Performs update of all feeds from the "feeds" parameter.
// New messages are downloaded for each feed and they
// are stored persistently in the database.
// Appropriate signals are emitted.
void updateFeeds(const QList<Feed*>& feeds);
// Stops running update.
void stopRunningUpdate();
private slots:
void oneFeedUpdateFinished(const QList<Message>& messages, bool error_during_obtaining);
signals:
// Emitted if feed updates started.
void updateStarted();
// Emitted if all items from update queue are
// processed.
void updateFinished(FeedDownloadResults updated_feeds);
// Emitted if any item is processed.
// "Current" number indicates count of processed feeds
// and "total" number indicates total number of feeds
// which were in the initial queue.
void updateProgress(const Feed* feed, int current, int total);
private:
void updateAvailableFeeds();
void finalizeUpdate();
QList<Feed*> m_feeds;
QMutex* m_mutex;
QThreadPool* m_threadPool;
FeedDownloadResults m_results;
int m_feedsUpdated;
int m_feedsUpdating;
int m_feedsOriginalCount;
};
#endif // FEEDDOWNLOADER_H

File diff suppressed because it is too large Load Diff

View File

@ -1,182 +1,182 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDSMODEL_H
#define FEEDSMODEL_H
#include <QAbstractItemModel>
#include "core/message.h"
#include "services/abstract/rootitem.h"
class Category;
class Feed;
class ServiceRoot;
class ServiceEntryPoint;
class StandardServiceRoot;
class FeedsModel : public QAbstractItemModel {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedsModel(QObject *parent = 0);
virtual ~FeedsModel();
// Model implementation.
inline QVariant data(const QModelIndex &index, int role) const {
// Return data according to item.
return itemForIndex(index)->data(index.column(), role);
}
// Drag & drop.
QMimeData *mimeData(const QModelIndexList &indexes) const;
QStringList mimeTypes() const;
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
Qt::DropActions supportedDropActions() const;
Qt::ItemFlags flags(const QModelIndex &index) const;
// Other subclassed methods.
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex index(int row, int column, const QModelIndex &parent) const;
QModelIndex parent(const QModelIndex &child) const;
int columnCount(const QModelIndex &parent) const;
int rowCount(const QModelIndex &parent) const;
// Returns counts of ALL/UNREAD (non-deleted) messages for the model.
int countOfAllMessages() const;
int countOfUnreadMessages() const;
// Returns all activated service roots.
// NOTE: Service root nodes are lying directly UNDER
// the model root item.
QList<ServiceRoot*> serviceRoots() const;
// Determines if there is any account activated from given entry point.
bool containsServiceRootFromEntryPoint(const ServiceEntryPoint *point) const;
// Direct and the only global accessor to standard service root.
StandardServiceRoot *standardServiceRoot() const;
// Returns the list of feeds which should be updated
// according to auto-update schedule.
// Variable "auto_update_now" is true, when global timeout
// for scheduled auto-update was met and global auto-update strategy is enabled
// so feeds with "default" auto-update strategy should be updated.
//
// This method might change some properties of some feeds.
QList<Feed*> feedsForScheduledUpdate(bool auto_update_now);
// Returns (undeleted) messages for given feeds.
// This is usually used for displaying whole feeds
// in "newspaper" mode.
QList<Message> messagesForItem(RootItem *item) const;
// Returns ALL RECURSIVE CHILD feeds contained within single index.
QList<Feed*> feedsForIndex(const QModelIndex &index) const;
// Returns feed/category which lies at the specified index or
// root item if index is invalid.
RootItem *itemForIndex(const QModelIndex &index) const;
// Returns source QModelIndex on which lies given item.
// NOTE: This goes through all available indexes and
// checks their bound items manually, there is no
// other way to to this.
QModelIndex indexForItem(const RootItem *item) const;
// Determines if any feed has any new messages.
bool hasAnyFeedNewMessages() const;
// Access to root item.
RootItem *rootItem() const;
public slots:
// Loads feed/categories from the database.
void loadActivatedServiceAccounts();
// Stops all accounts before exit.
void stopServiceAccounts();
// Reloads counts of all feeds/categories/whatever in the model.
void reloadCountsOfWholeModel();
// Checks if new parent node is different from one used by original node.
// If it is, then it reassigns original_node to new parent.
void reassignNodeToNewParent(RootItem *original_node, RootItem *new_parent);
// Adds given service root account.
bool addServiceAccount(ServiceRoot *root, bool freshly_activated);
// Removes item with given index.
// NOTE: Also deletes item from memory.
void removeItem(const QModelIndex &index);
void removeItem(RootItem *deleting_item);
// Recycle bins operations.
bool restoreAllBins();
bool emptyAllBins();
// Feeds operations.
bool markItemRead(RootItem *item, RootItem::ReadStatus read);
bool markItemCleared(RootItem *item, bool clean_read_only);
// Signals that properties (probably counts)
// of ALL items have changed.
void reloadWholeLayout();
// Signals that SOME data of this model need
// to be reloaded by ALL attached views.
// NOTE: This reloads all parent valid indexes too.
void reloadChangedLayout(QModelIndexList list);
// Invalidates data under index for the item.
void reloadChangedItem(RootItem *item);
// Notifies other components about messages
// counts.
void notifyWithCounts();
private slots:
void onItemDataChanged(const QList<RootItem*> &items);
signals:
// Emitted if counts of messages are changed.
void messageCountsChanged(int unread_messages, bool any_feed_has_unread_messages);
// Emitted if any item requested that any view should expand it.
void itemExpandRequested(QList<RootItem*> items, bool expand);
// Emitted if any item requested that its expand states should be explicitly saved.
// NOTE: Normally expand states are saved when application quits.
void itemExpandStateSaveRequested(RootItem *subtree_root);
// Emitted when there is a need of reloading of displayed messages.
void reloadMessageListRequested(bool mark_selected_messages_read);
// There was some drag/drop operation, notify view about this.
// NOTE: View will probably expand dropped index.
void requireItemValidationAfterDragDrop(const QModelIndex &source_index);
private:
RootItem *m_rootItem;
QList<QString> m_headerData;
QList<QString> m_tooltipData;
QIcon m_countsIcon;
};
#endif // FEEDSMODEL_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDSMODEL_H
#define FEEDSMODEL_H
#include <QAbstractItemModel>
#include "core/message.h"
#include "services/abstract/rootitem.h"
class Category;
class Feed;
class ServiceRoot;
class ServiceEntryPoint;
class StandardServiceRoot;
class FeedsModel : public QAbstractItemModel {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedsModel(QObject* parent = 0);
virtual ~FeedsModel();
// Model implementation.
inline QVariant data(const QModelIndex& index, int role) const {
// Return data according to item.
return itemForIndex(index)->data(index.column(), role);
}
// Drag & drop.
QMimeData* mimeData(const QModelIndexList& indexes) const;
QStringList mimeTypes() const;
bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
Qt::DropActions supportedDropActions() const;
Qt::ItemFlags flags(const QModelIndex& index) const;
// Other subclassed methods.
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex index(int row, int column, const QModelIndex& parent) const;
QModelIndex parent(const QModelIndex& child) const;
int columnCount(const QModelIndex& parent) const;
int rowCount(const QModelIndex& parent) const;
// Returns counts of ALL/UNREAD (non-deleted) messages for the model.
int countOfAllMessages() const;
int countOfUnreadMessages() const;
// Returns all activated service roots.
// NOTE: Service root nodes are lying directly UNDER
// the model root item.
QList<ServiceRoot*> serviceRoots() const;
// Determines if there is any account activated from given entry point.
bool containsServiceRootFromEntryPoint(const ServiceEntryPoint* point) const;
// Direct and the only global accessor to standard service root.
StandardServiceRoot* standardServiceRoot() const;
// Returns the list of feeds which should be updated
// according to auto-update schedule.
// Variable "auto_update_now" is true, when global timeout
// for scheduled auto-update was met and global auto-update strategy is enabled
// so feeds with "default" auto-update strategy should be updated.
//
// This method might change some properties of some feeds.
QList<Feed*> feedsForScheduledUpdate(bool auto_update_now);
// Returns (undeleted) messages for given feeds.
// This is usually used for displaying whole feeds
// in "newspaper" mode.
QList<Message> messagesForItem(RootItem* item) const;
// Returns ALL RECURSIVE CHILD feeds contained within single index.
QList<Feed*> feedsForIndex(const QModelIndex& index) const;
// Returns feed/category which lies at the specified index or
// root item if index is invalid.
RootItem* itemForIndex(const QModelIndex& index) const;
// Returns source QModelIndex on which lies given item.
// NOTE: This goes through all available indexes and
// checks their bound items manually, there is no
// other way to to this.
QModelIndex indexForItem(const RootItem* item) const;
// Determines if any feed has any new messages.
bool hasAnyFeedNewMessages() const;
// Access to root item.
RootItem* rootItem() const;
public slots:
// Loads feed/categories from the database.
void loadActivatedServiceAccounts();
// Stops all accounts before exit.
void stopServiceAccounts();
// Reloads counts of all feeds/categories/whatever in the model.
void reloadCountsOfWholeModel();
// Checks if new parent node is different from one used by original node.
// If it is, then it reassigns original_node to new parent.
void reassignNodeToNewParent(RootItem* original_node, RootItem* new_parent);
// Adds given service root account.
bool addServiceAccount(ServiceRoot* root, bool freshly_activated);
// Removes item with given index.
// NOTE: Also deletes item from memory.
void removeItem(const QModelIndex& index);
void removeItem(RootItem* deleting_item);
// Recycle bins operations.
bool restoreAllBins();
bool emptyAllBins();
// Feeds operations.
bool markItemRead(RootItem* item, RootItem::ReadStatus read);
bool markItemCleared(RootItem* item, bool clean_read_only);
// Signals that properties (probably counts)
// of ALL items have changed.
void reloadWholeLayout();
// Signals that SOME data of this model need
// to be reloaded by ALL attached views.
// NOTE: This reloads all parent valid indexes too.
void reloadChangedLayout(QModelIndexList list);
// Invalidates data under index for the item.
void reloadChangedItem(RootItem* item);
// Notifies other components about messages
// counts.
void notifyWithCounts();
private slots:
void onItemDataChanged(const QList<RootItem*>& items);
signals:
// Emitted if counts of messages are changed.
void messageCountsChanged(int unread_messages, bool any_feed_has_unread_messages);
// Emitted if any item requested that any view should expand it.
void itemExpandRequested(QList<RootItem*> items, bool expand);
// Emitted if any item requested that its expand states should be explicitly saved.
// NOTE: Normally expand states are saved when application quits.
void itemExpandStateSaveRequested(RootItem* subtree_root);
// Emitted when there is a need of reloading of displayed messages.
void reloadMessageListRequested(bool mark_selected_messages_read);
// There was some drag/drop operation, notify view about this.
// NOTE: View will probably expand dropped index.
void requireItemValidationAfterDragDrop(const QModelIndex& source_index);
private:
RootItem* m_rootItem;
QList<QString> m_headerData;
QList<QString> m_tooltipData;
QIcon m_countsIcon;
};
#endif // FEEDSMODEL_H

View File

@ -1,264 +1,278 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/feedsproxymodel.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "core/feedsmodel.h"
#include "services/abstract/rootitem.h"
#include <QTimer>
FeedsProxyModel::FeedsProxyModel(FeedsModel *source_model, QObject *parent)
: QSortFilterProxyModel(parent), m_sourceModel(source_model), m_selectedItem(nullptr),
m_showUnreadOnly(false), m_hiddenIndices(QList<QPair<int,QModelIndex> >()) {
setObjectName(QSL("FeedsProxyModel"));
setSortRole(Qt::EditRole);
setSortCaseSensitivity(Qt::CaseInsensitive);
setFilterCaseSensitivity(Qt::CaseInsensitive);
setFilterKeyColumn(-1);
setFilterRole(Qt::EditRole);
setDynamicSortFilter(true);
setSourceModel(m_sourceModel);
}
FeedsProxyModel::~FeedsProxyModel() {
qDebug("Destroying FeedsProxyModel instance");
}
QModelIndexList FeedsProxyModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const {
QModelIndexList result;
const uint match_type = flags & 0x0F;
const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
const bool recurse = flags & Qt::MatchRecursive;
const bool wrap = flags & Qt::MatchWrap;
const bool all_hits = (hits == -1);
QString entered_text;
const QModelIndex p = parent(start);
int from = start.row();
int to = rowCount(p);
for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
for (int r = from; (r < to) && (all_hits || result.count() < hits); ++r) {
QModelIndex idx = index(r, start.column(), p);
if (!idx.isValid()) {
continue;
}
QModelIndex mapped_idx = mapToSource(idx);
QVariant item_value = m_sourceModel->itemForIndex(mapped_idx)->title();
// QVariant based matching.
if (match_type == Qt::MatchExactly) {
if (value == item_value) {
result.append(idx);
}
}
// QString based matching.
else {
if (entered_text.isEmpty()) {
entered_text = value.toString();
}
QString item_text = item_value.toString();
switch (match_type) {
case Qt::MatchRegExp:
if (QRegExp(entered_text, cs).exactMatch(item_text)) {
result.append(idx);
}
break;
case Qt::MatchWildcard:
if (QRegExp(entered_text, cs, QRegExp::Wildcard).exactMatch(item_text)) {
result.append(idx);
}
break;
case Qt::MatchStartsWith:
if (item_text.startsWith(entered_text, cs)) {
result.append(idx);
}
break;
case Qt::MatchEndsWith:
if (item_text.endsWith(entered_text, cs)) {
result.append(idx);
}
break;
case Qt::MatchFixedString:
if (item_text.compare(entered_text, cs) == 0) {
result.append(idx);
}
break;
case Qt::MatchContains:
default:
if (item_text.contains(entered_text, cs)) {
result.append(idx);
}
break;
}
}
if (recurse && hasChildren(idx)) {
result += match(index(0, idx.column(), idx), role, (entered_text.isEmpty() ? value : entered_text), (all_hits ? -1 : hits - result.count()), flags);
}
}
from = 0;
to = start.row();
}
return result;
}
bool FeedsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const {
if (left.isValid() && right.isValid()) {
// Make necessary castings.
const RootItem *left_item = m_sourceModel->itemForIndex(left);
const RootItem *right_item = m_sourceModel->itemForIndex(right);
// NOTE: Here we want to accomplish that ALL
// categories are queued one after another and all
// feeds are queued one after another too.
// Moreover, sort everything alphabetically or
// by item counts, depending on the sort column.
if (left_item->kind() == right_item->kind()) {
// Both items are feeds or both items are categories.
if (left.column() == FDS_MODEL_COUNTS_INDEX) {
// User wants to sort according to counts.
return left_item->countOfUnreadMessages() < right_item->countOfUnreadMessages();
}
else {
// In other cases, sort by title.
return QString::localeAwareCompare(left_item->title(), right_item->title()) < 0;
}
}
else if (left_item->kind() == RootItemKind::Bin) {
// Left item is recycle bin. Make sure it is "biggest" item if we have selected ascending order.
return sortOrder() == Qt::DescendingOrder;
}
else if (right_item->kind() == RootItemKind::Bin) {
// Right item is recycle bin. Make sure it is "smallest" item if we have selected descending order.
return sortOrder() == Qt::AscendingOrder;
}
else if (left_item->kind() == RootItemKind::Feed) {
// Left item is feed, right item is category.
return false;
}
else {
// Left item is category, right item is feed.
// NOTE: Category is in fact "more" than feed but we consider it to be "less" because it should be "placed"
// above the "smalles" feed when ascending sort is used.
// NOTE: We need to keep recycle bin in first position.
return true;
}
}
else {
return false;
}
}
bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const {
bool should_show = filterAcceptsRowInternal(source_row, source_parent);
if (should_show && m_hiddenIndices.contains(QPair<int,QModelIndex>(source_row, source_parent))) {
const_cast<FeedsProxyModel*>(this)->m_hiddenIndices.removeAll(QPair<int,QModelIndex>(source_row, source_parent));
// Load status.
emit expandAfterFilterIn(m_sourceModel->index(source_row, 0, source_parent));
}
if (!should_show) {
const_cast<FeedsProxyModel*>(this)->m_hiddenIndices.append(QPair<int,QModelIndex>(source_row, source_parent));
}
return should_show;
}
bool FeedsProxyModel::filterAcceptsRowInternal(int source_row, const QModelIndex &source_parent) const {
if (!m_showUnreadOnly) {
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
const QModelIndex idx = m_sourceModel->index(source_row, 0, source_parent);
if (!idx.isValid()) {
return false;
}
const RootItem *item = m_sourceModel->itemForIndex(idx);
if (item->kind() == RootItemKind::Bin || item->kind() == RootItemKind::ServiceRoot) {
// Recycle bin is always displayed.
return true;
}
else if (item->isParentOf(m_selectedItem)/* || item->isChildOf(m_selectedItem)*/ || m_selectedItem == item) {
// Currently selected item and all its parents and children must be displayed.
return true;
}
else {
// NOTE: If item has < 0 of unread message it may mean, that the count
// of unread messages is not (yet) known, display that item too.
return item->countOfUnreadMessages() != 0;
}
}
const RootItem *FeedsProxyModel::selectedItem() const {
return m_selectedItem;
}
void FeedsProxyModel::setSelectedItem(const RootItem *selected_item) {
m_selectedItem = selected_item;
}
bool FeedsProxyModel::showUnreadOnly() const {
return m_showUnreadOnly;
}
void FeedsProxyModel::invalidateReadFeedsFilter(bool set_new_value, bool show_unread_only) {
if (set_new_value) {
setShowUnreadOnly(show_unread_only);
}
QTimer::singleShot(0, this, &FeedsProxyModel::invalidateFilter);
}
void FeedsProxyModel::setShowUnreadOnly(bool show_unread_only) {
m_showUnreadOnly = show_unread_only;
qApp->settings()->setValue(GROUP(Feeds), Feeds::ShowOnlyUnreadFeeds, show_unread_only);
}
QModelIndexList FeedsProxyModel::mapListToSource(const QModelIndexList &indexes) const {
QModelIndexList source_indexes;
foreach (const QModelIndex &index, indexes) {
source_indexes << mapToSource(index);
}
return source_indexes;
}
void FeedsProxyModel::invalidateFilter() {
QSortFilterProxyModel::invalidateFilter();
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/feedsproxymodel.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "core/feedsmodel.h"
#include "services/abstract/rootitem.h"
#include <QTimer>
FeedsProxyModel::FeedsProxyModel(FeedsModel* source_model, QObject* parent)
: QSortFilterProxyModel(parent), m_sourceModel(source_model), m_selectedItem(nullptr),
m_showUnreadOnly(false), m_hiddenIndices(QList<QPair<int, QModelIndex>>()) {
setObjectName(QSL("FeedsProxyModel"));
setSortRole(Qt::EditRole);
setSortCaseSensitivity(Qt::CaseInsensitive);
setFilterCaseSensitivity(Qt::CaseInsensitive);
setFilterKeyColumn(-1);
setFilterRole(Qt::EditRole);
setDynamicSortFilter(true);
setSourceModel(m_sourceModel);
}
FeedsProxyModel::~FeedsProxyModel() {
qDebug("Destroying FeedsProxyModel instance");
}
QModelIndexList FeedsProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const {
QModelIndexList result;
const uint match_type = flags & 0x0F;
const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
const bool recurse = flags & Qt::MatchRecursive;
const bool wrap = flags & Qt::MatchWrap;
const bool all_hits = (hits == -1);
QString entered_text;
const QModelIndex p = parent(start);
int from = start.row();
int to = rowCount(p);
for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
for (int r = from; (r < to) && (all_hits || result.count() < hits); ++r) {
QModelIndex idx = index(r, start.column(), p);
if (!idx.isValid()) {
continue;
}
QModelIndex mapped_idx = mapToSource(idx);
QVariant item_value = m_sourceModel->itemForIndex(mapped_idx)->title();
// QVariant based matching.
if (match_type == Qt::MatchExactly) {
if (value == item_value) {
result.append(idx);
}
}
// QString based matching.
else {
if (entered_text.isEmpty()) {
entered_text = value.toString();
}
QString item_text = item_value.toString();
switch (match_type) {
case Qt::MatchRegExp:
if (QRegExp(entered_text, cs).exactMatch(item_text)) {
result.append(idx);
}
break;
case Qt::MatchWildcard:
if (QRegExp(entered_text, cs, QRegExp::Wildcard).exactMatch(item_text)) {
result.append(idx);
}
break;
case Qt::MatchStartsWith:
if (item_text.startsWith(entered_text, cs)) {
result.append(idx);
}
break;
case Qt::MatchEndsWith:
if (item_text.endsWith(entered_text, cs)) {
result.append(idx);
}
break;
case Qt::MatchFixedString:
if (item_text.compare(entered_text, cs) == 0) {
result.append(idx);
}
break;
case Qt::MatchContains:
default:
if (item_text.contains(entered_text, cs)) {
result.append(idx);
}
break;
}
}
if (recurse && hasChildren(idx)) {
result += match(index(0, idx.column(), idx), role, (entered_text.isEmpty() ? value : entered_text), (all_hits ? -1 : hits - result.count()), flags);
}
}
from = 0;
to = start.row();
}
return result;
}
bool FeedsProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const {
if (left.isValid() && right.isValid()) {
// Make necessary castings.
const RootItem* left_item = m_sourceModel->itemForIndex(left);
const RootItem* right_item = m_sourceModel->itemForIndex(right);
// NOTE: Here we want to accomplish that ALL
// categories are queued one after another and all
// feeds are queued one after another too.
// Moreover, sort everything alphabetically or
// by item counts, depending on the sort column.
if (left_item->kind() == right_item->kind()) {
// Both items are feeds or both items are categories.
if (left.column() == FDS_MODEL_COUNTS_INDEX) {
// User wants to sort according to counts.
return left_item->countOfUnreadMessages() < right_item->countOfUnreadMessages();
}
else {
// In other cases, sort by title.
return QString::localeAwareCompare(left_item->title(), right_item->title()) < 0;
}
}
else if (left_item->kind() == RootItemKind::Bin) {
// Left item is recycle bin. Make sure it is "biggest" item if we have selected ascending order.
return sortOrder() == Qt::DescendingOrder;
}
else if (right_item->kind() == RootItemKind::Bin) {
// Right item is recycle bin. Make sure it is "smallest" item if we have selected descending order.
return sortOrder() == Qt::AscendingOrder;
}
else if (left_item->kind() == RootItemKind::Feed) {
// Left item is feed, right item is category.
return false;
}
else {
// Left item is category, right item is feed.
// NOTE: Category is in fact "more" than feed but we consider it to be "less" because it should be "placed"
// above the "smalles" feed when ascending sort is used.
// NOTE: We need to keep recycle bin in first position.
return true;
}
}
else {
return false;
}
}
bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const {
bool should_show = filterAcceptsRowInternal(source_row, source_parent);
if (should_show && m_hiddenIndices.contains(QPair<int, QModelIndex>(source_row, source_parent))) {
const_cast<FeedsProxyModel*>(this)->m_hiddenIndices.removeAll(QPair<int, QModelIndex>(source_row, source_parent));
// Load status.
emit expandAfterFilterIn(m_sourceModel->index(source_row, 0, source_parent));
}
if (!should_show) {
const_cast<FeedsProxyModel*>(this)->m_hiddenIndices.append(QPair<int, QModelIndex>(source_row, source_parent));
}
return should_show;
}
bool FeedsProxyModel::filterAcceptsRowInternal(int source_row, const QModelIndex& source_parent) const {
if (!m_showUnreadOnly) {
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
const QModelIndex idx = m_sourceModel->index(source_row, 0, source_parent);
if (!idx.isValid()) {
return false;
}
const RootItem* item = m_sourceModel->itemForIndex(idx);
if (item->kind() == RootItemKind::Bin || item->kind() == RootItemKind::ServiceRoot) {
// Recycle bin is always displayed.
return true;
}
else if (item->isParentOf(m_selectedItem)/* || item->isChildOf(m_selectedItem)*/ || m_selectedItem == item) {
// Currently selected item and all its parents and children must be displayed.
return true;
}
else {
// NOTE: If item has < 0 of unread message it may mean, that the count
// of unread messages is not (yet) known, display that item too.
return item->countOfUnreadMessages() != 0;
}
}
const RootItem* FeedsProxyModel::selectedItem() const {
return m_selectedItem;
}
void FeedsProxyModel::setSelectedItem(const RootItem* selected_item) {
m_selectedItem = selected_item;
}
bool FeedsProxyModel::showUnreadOnly() const {
return m_showUnreadOnly;
}
void FeedsProxyModel::invalidateReadFeedsFilter(bool set_new_value, bool show_unread_only) {
if (set_new_value) {
setShowUnreadOnly(show_unread_only);
}
QTimer::singleShot(0, this, &FeedsProxyModel::invalidateFilter);
}
void FeedsProxyModel::setShowUnreadOnly(bool show_unread_only) {
m_showUnreadOnly = show_unread_only;
qApp->settings()->setValue(GROUP(Feeds), Feeds::ShowOnlyUnreadFeeds, show_unread_only);
}
QModelIndexList FeedsProxyModel::mapListToSource(const QModelIndexList& indexes) const {
QModelIndexList source_indexes;
foreach (const QModelIndex& index, indexes) {
source_indexes << mapToSource(index);
}
return source_indexes;
}
void FeedsProxyModel::invalidateFilter() {
QSortFilterProxyModel::invalidateFilter();
}

View File

@ -1,70 +1,70 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDSPROXYMODEL_H
#define FEEDSPROXYMODEL_H
#include <QSortFilterProxyModel>
class FeedsModel;
class RootItem;
class FeedsProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedsProxyModel(FeedsModel *source_model, QObject *parent = 0);
virtual ~FeedsProxyModel();
// Returns index list of items which "match" given value.
// Used for finding items according to entered title text.
QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const;
// Maps list of indexes.
QModelIndexList mapListToSource(const QModelIndexList &indexes) const;
bool showUnreadOnly() const;
void setShowUnreadOnly(bool show_unread_only);
const RootItem *selectedItem() const;
void setSelectedItem(const RootItem *selected_item);
public slots:
void invalidateReadFeedsFilter(bool set_new_value = false, bool show_unread_only = false);
private slots:
void invalidateFilter();
signals:
void expandAfterFilterIn(QModelIndex idx) const;
private:
// Compares two rows of data.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
bool filterAcceptsRowInternal(int source_row, const QModelIndex &source_parent) const;
// Source model pointer.
FeedsModel *m_sourceModel;
const RootItem *m_selectedItem;
bool m_showUnreadOnly;
QList<QPair<int,QModelIndex> > m_hiddenIndices;
};
#endif // FEEDSPROXYMODEL_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDSPROXYMODEL_H
#define FEEDSPROXYMODEL_H
#include <QSortFilterProxyModel>
class FeedsModel;
class RootItem;
class FeedsProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedsProxyModel(FeedsModel* source_model, QObject* parent = 0);
virtual ~FeedsProxyModel();
// Returns index list of items which "match" given value.
// Used for finding items according to entered title text.
QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const;
// Maps list of indexes.
QModelIndexList mapListToSource(const QModelIndexList& indexes) const;
bool showUnreadOnly() const;
void setShowUnreadOnly(bool show_unread_only);
const RootItem* selectedItem() const;
void setSelectedItem(const RootItem* selected_item);
public slots:
void invalidateReadFeedsFilter(bool set_new_value = false, bool show_unread_only = false);
private slots:
void invalidateFilter();
signals:
void expandAfterFilterIn(QModelIndex idx) const;
private:
// Compares two rows of data.
bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
bool filterAcceptsRowInternal(int source_row, const QModelIndex& source_parent) const;
// Source model pointer.
FeedsModel* m_sourceModel;
const RootItem* m_selectedItem;
bool m_showUnreadOnly;
QList<QPair<int, QModelIndex>> m_hiddenIndices;
};
#endif // FEEDSPROXYMODEL_H

View File

@ -1,112 +1,112 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/message.h"
#include "miscellaneous/textfactory.h"
#include <QVariant>
Enclosure::Enclosure(const QString &url, const QString &mime) : m_url(url), m_mimeType(mime) {
}
QList<Enclosure> Enclosures::decodeEnclosuresFromString(const QString &enclosures_data) {
QList<Enclosure> enclosures;
foreach (const QString &single_enclosure, enclosures_data.split(ENCLOSURES_OUTER_SEPARATOR, QString::SkipEmptyParts)) {
Enclosure enclosure;
if (single_enclosure.contains(ECNLOSURES_INNER_SEPARATOR)) {
QStringList mime_url = single_enclosure.split(ECNLOSURES_INNER_SEPARATOR);
enclosure.m_mimeType = QByteArray::fromBase64(mime_url.at(0).toLocal8Bit());
enclosure.m_url = QByteArray::fromBase64(mime_url.at(1).toLocal8Bit());
}
else {
enclosure.m_url = QByteArray::fromBase64(single_enclosure.toLocal8Bit());
}
enclosures.append(enclosure);
}
return enclosures;
}
QString Enclosures::encodeEnclosuresToString(const QList<Enclosure> &enclosures) {
QStringList enclosures_str;
foreach (const Enclosure &enclosure, enclosures) {
if (enclosure.m_mimeType.isEmpty()) {
enclosures_str.append(enclosure.m_url.toLocal8Bit().toBase64());
}
else {
enclosures_str.append(QString(enclosure.m_mimeType.toLocal8Bit().toBase64()) +
ECNLOSURES_INNER_SEPARATOR +
enclosure.m_url.toLocal8Bit().toBase64());
}
}
return enclosures_str.join(QString(ENCLOSURES_OUTER_SEPARATOR));
}
Message::Message() {
m_title = m_url = m_author = m_contents = m_feedId = m_customId = m_customHash = QSL("");
m_enclosures = QList<Enclosure>();
m_accountId = m_id = 0;
m_isRead = m_isImportant = false;
}
Message Message::fromSqlRecord(const QSqlRecord &record, bool *result) {
if (record.count() != MSG_DB_CUSTOM_HASH_INDEX + 1) {
if (result != nullptr) {
*result = false;
return Message();
}
}
Message message;
message.m_id = record.value(MSG_DB_ID_INDEX).toInt();
message.m_isRead = record.value(MSG_DB_READ_INDEX).toBool();
message.m_isImportant = record.value(MSG_DB_IMPORTANT_INDEX).toBool();
message.m_feedId = record.value(MSG_DB_FEED_CUSTOM_ID_INDEX).toString();
message.m_title = record.value(MSG_DB_TITLE_INDEX).toString();
message.m_url = record.value(MSG_DB_URL_INDEX).toString();
message.m_author = record.value(MSG_DB_AUTHOR_INDEX).toString();
message.m_created = TextFactory::parseDateTime(record.value(MSG_DB_DCREATED_INDEX).value<qint64>());
message.m_contents = record.value(MSG_DB_CONTENTS_INDEX).toString();
message.m_enclosures = Enclosures::decodeEnclosuresFromString(record.value(MSG_DB_ENCLOSURES_INDEX).toString());
message.m_accountId = record.value(MSG_DB_ACCOUNT_ID_INDEX).toInt();
message.m_customId = record.value(MSG_DB_CUSTOM_ID_INDEX).toString();
message.m_customHash = record.value(MSG_DB_CUSTOM_HASH_INDEX).toString();
if (result != nullptr) {
*result = true;
}
return message;
}
uint qHash(Message key, uint seed) {
Q_UNUSED(seed)
return (key.m_accountId * 10000) + key.m_id;
}
uint qHash(const Message &key) {
return (key.m_accountId * 10000) + key.m_id;
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/message.h"
#include "miscellaneous/textfactory.h"
#include <QVariant>
Enclosure::Enclosure(const QString& url, const QString& mime) : m_url(url), m_mimeType(mime) {
}
QList<Enclosure> Enclosures::decodeEnclosuresFromString(const QString& enclosures_data) {
QList<Enclosure> enclosures;
foreach (const QString& single_enclosure, enclosures_data.split(ENCLOSURES_OUTER_SEPARATOR, QString::SkipEmptyParts)) {
Enclosure enclosure;
if (single_enclosure.contains(ECNLOSURES_INNER_SEPARATOR)) {
QStringList mime_url = single_enclosure.split(ECNLOSURES_INNER_SEPARATOR);
enclosure.m_mimeType = QByteArray::fromBase64(mime_url.at(0).toLocal8Bit());
enclosure.m_url = QByteArray::fromBase64(mime_url.at(1).toLocal8Bit());
}
else {
enclosure.m_url = QByteArray::fromBase64(single_enclosure.toLocal8Bit());
}
enclosures.append(enclosure);
}
return enclosures;
}
QString Enclosures::encodeEnclosuresToString(const QList<Enclosure>& enclosures) {
QStringList enclosures_str;
foreach (const Enclosure& enclosure, enclosures) {
if (enclosure.m_mimeType.isEmpty()) {
enclosures_str.append(enclosure.m_url.toLocal8Bit().toBase64());
}
else {
enclosures_str.append(QString(enclosure.m_mimeType.toLocal8Bit().toBase64()) +
ECNLOSURES_INNER_SEPARATOR +
enclosure.m_url.toLocal8Bit().toBase64());
}
}
return enclosures_str.join(QString(ENCLOSURES_OUTER_SEPARATOR));
}
Message::Message() {
m_title = m_url = m_author = m_contents = m_feedId = m_customId = m_customHash = QSL("");
m_enclosures = QList<Enclosure>();
m_accountId = m_id = 0;
m_isRead = m_isImportant = false;
}
Message Message::fromSqlRecord(const QSqlRecord& record, bool* result) {
if (record.count() != MSG_DB_CUSTOM_HASH_INDEX + 1) {
if (result != nullptr) {
*result = false;
return Message();
}
}
Message message;
message.m_id = record.value(MSG_DB_ID_INDEX).toInt();
message.m_isRead = record.value(MSG_DB_READ_INDEX).toBool();
message.m_isImportant = record.value(MSG_DB_IMPORTANT_INDEX).toBool();
message.m_feedId = record.value(MSG_DB_FEED_CUSTOM_ID_INDEX).toString();
message.m_title = record.value(MSG_DB_TITLE_INDEX).toString();
message.m_url = record.value(MSG_DB_URL_INDEX).toString();
message.m_author = record.value(MSG_DB_AUTHOR_INDEX).toString();
message.m_created = TextFactory::parseDateTime(record.value(MSG_DB_DCREATED_INDEX).value<qint64>());
message.m_contents = record.value(MSG_DB_CONTENTS_INDEX).toString();
message.m_enclosures = Enclosures::decodeEnclosuresFromString(record.value(MSG_DB_ENCLOSURES_INDEX).toString());
message.m_accountId = record.value(MSG_DB_ACCOUNT_ID_INDEX).toInt();
message.m_customId = record.value(MSG_DB_CUSTOM_ID_INDEX).toString();
message.m_customHash = record.value(MSG_DB_CUSTOM_HASH_INDEX).toString();
if (result != nullptr) {
*result = true;
}
return message;
}
uint qHash(Message key, uint seed) {
Q_UNUSED(seed)
return (key.m_accountId * 10000) + key.m_id;
}
uint qHash(const Message& key) {
return (key.m_accountId * 10000) + key.m_id;
}

View File

@ -1,85 +1,85 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGE_H
#define MESSAGE_H
#include "definitions/definitions.h"
#include <QDateTime>
#include <QStringList>
#include <QSqlRecord>
// Represents single enclosure.
struct Enclosure {
public:
explicit Enclosure(const QString &url = QString(), const QString &mime = QString());
QString m_url;
QString m_mimeType;
};
// Represents single enclosure.
class Enclosures {
public:
static QList<Enclosure> decodeEnclosuresFromString(const QString &enclosures_data);
static QString encodeEnclosuresToString(const QList<Enclosure> &enclosures);
};
// Represents single message.
class Message {
public:
explicit Message();
// Creates Message from given record, which contains
// row from query SELECT * FROM Messages WHERE ....;
static Message fromSqlRecord(const QSqlRecord &record, bool *result = nullptr);
QString m_title;
QString m_url;
QString m_author;
QString m_contents;
QDateTime m_created;
QString m_feedId;
int m_accountId;
int m_id;
QString m_customId;
QString m_customHash;
bool m_isRead;
bool m_isImportant;
QList<Enclosure> m_enclosures;
// Is true if "created" date was obtained directly
// from the feed, otherwise is false
bool m_createdFromFeed;
friend inline bool operator==(const Message &lhs, const Message &rhs) {
return lhs.m_accountId == rhs.m_accountId && lhs.m_id == rhs.m_id;
}
friend inline bool operator!=(const Message &lhs, const Message &rhs) {
return !(lhs == rhs);
}
};
uint qHash(Message key, uint seed);
uint qHash(const Message &key);
#endif // MESSAGE_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGE_H
#define MESSAGE_H
#include "definitions/definitions.h"
#include <QDateTime>
#include <QStringList>
#include <QSqlRecord>
// Represents single enclosure.
struct Enclosure {
public:
explicit Enclosure(const QString& url = QString(), const QString& mime = QString());
QString m_url;
QString m_mimeType;
};
// Represents single enclosure.
class Enclosures {
public:
static QList<Enclosure> decodeEnclosuresFromString(const QString& enclosures_data);
static QString encodeEnclosuresToString(const QList<Enclosure>& enclosures);
};
// Represents single message.
class Message {
public:
explicit Message();
// Creates Message from given record, which contains
// row from query SELECT * FROM Messages WHERE ....;
static Message fromSqlRecord(const QSqlRecord& record, bool* result = nullptr);
QString m_title;
QString m_url;
QString m_author;
QString m_contents;
QDateTime m_created;
QString m_feedId;
int m_accountId;
int m_id;
QString m_customId;
QString m_customHash;
bool m_isRead;
bool m_isImportant;
QList<Enclosure> m_enclosures;
// Is true if "created" date was obtained directly
// from the feed, otherwise is false
bool m_createdFromFeed;
friend inline bool operator==(const Message& lhs, const Message& rhs) {
return lhs.m_accountId == rhs.m_accountId && lhs.m_id == rhs.m_id;
}
friend inline bool operator!=(const Message& lhs, const Message& rhs) {
return !(lhs == rhs);
}
};
uint qHash(Message key, uint seed);
uint qHash(const Message& key);
#endif // MESSAGE_H

View File

@ -30,524 +30,525 @@
#include <QSqlField>
MessagesModel::MessagesModel(QObject *parent)
: QSqlQueryModel(parent), MessagesModelSqlLayer(),
m_cache(new MessagesModelCache(this)), m_messageHighlighter(NoHighlighting), m_customDateFormat(QString()) {
setupFonts();
setupIcons();
setupHeaderData();
updateDateFormat();
loadMessages(nullptr);
MessagesModel::MessagesModel(QObject* parent)
: QSqlQueryModel(parent), MessagesModelSqlLayer(),
m_cache(new MessagesModelCache(this)), m_messageHighlighter(NoHighlighting), m_customDateFormat(QString()) {
setupFonts();
setupIcons();
setupHeaderData();
updateDateFormat();
loadMessages(nullptr);
}
MessagesModel::~MessagesModel() {
qDebug("Destroying MessagesModel instance.");
qDebug("Destroying MessagesModel instance.");
}
void MessagesModel::setupIcons() {
m_favoriteIcon = qApp->icons()->fromTheme(QSL("mail-mark-important"));
m_readIcon = qApp->icons()->fromTheme(QSL("mail-mark-read"));
m_unreadIcon = qApp->icons()->fromTheme(QSL("mail-mark-unread"));
m_favoriteIcon = qApp->icons()->fromTheme(QSL("mail-mark-important"));
m_readIcon = qApp->icons()->fromTheme(QSL("mail-mark-read"));
m_unreadIcon = qApp->icons()->fromTheme(QSL("mail-mark-unread"));
}
void MessagesModel::repopulate() {
m_cache->clear();
setQuery(selectStatement(), m_db);
m_cache->clear();
setQuery(selectStatement(), m_db);
while (canFetchMore()) {
fetchMore();
}
while (canFetchMore()) {
fetchMore();
}
}
bool MessagesModel::setData(const QModelIndex &index, const QVariant &value, int role) {
Q_UNUSED(role)
m_cache->setData(index, value, record(index.row()));
return true;
bool MessagesModel::setData(const QModelIndex& index, const QVariant& value, int role) {
Q_UNUSED(role)
m_cache->setData(index, value, record(index.row()));
return true;
}
void MessagesModel::setupFonts() {
m_normalFont = Application::font("MessagesView");
m_boldFont = m_normalFont;
m_boldFont.setBold(true);
m_normalStrikedFont = m_normalFont;
m_boldStrikedFont = m_boldFont;
m_normalStrikedFont.setStrikeOut(true);
m_boldStrikedFont.setStrikeOut(true);
m_normalFont = Application::font("MessagesView");
m_boldFont = m_normalFont;
m_boldFont.setBold(true);
m_normalStrikedFont = m_normalFont;
m_boldStrikedFont = m_boldFont;
m_normalStrikedFont.setStrikeOut(true);
m_boldStrikedFont.setStrikeOut(true);
}
void MessagesModel::loadMessages(RootItem *item) {
m_selectedItem = item;
void MessagesModel::loadMessages(RootItem* item) {
m_selectedItem = item;
if (item == nullptr) {
setFilter(QSL(DEFAULT_SQL_MESSAGES_FILTER));
}
else {
if (!item->getParentServiceRoot()->loadMessagesForItem(item, this)) {
setFilter(QSL("true != true"));
qWarning("Loading of messages from item '%s' failed.", qPrintable(item->title()));
qApp->showGuiMessage(tr("Loading of messages from item '%1' failed.").arg(item->title()),
tr("Loading of messages failed, maybe messages could not be downloaded."),
QSystemTrayIcon::Critical,
qApp->mainFormWidget(),
true);
}
}
if (item == nullptr) {
setFilter(QSL(DEFAULT_SQL_MESSAGES_FILTER));
}
repopulate();
else {
if (!item->getParentServiceRoot()->loadMessagesForItem(item, this)) {
setFilter(QSL("true != true"));
qWarning("Loading of messages from item '%s' failed.", qPrintable(item->title()));
qApp->showGuiMessage(tr("Loading of messages from item '%1' failed.").arg(item->title()),
tr("Loading of messages failed, maybe messages could not be downloaded."),
QSystemTrayIcon::Critical,
qApp->mainFormWidget(),
true);
}
}
repopulate();
}
bool MessagesModel::setMessageImportantById(int id, RootItem::Importance important) {
for (int i = 0; i < rowCount(); i++) {
int found_id = data(i, MSG_DB_ID_INDEX, Qt::EditRole).toInt();
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);
if (found_id == id) {
bool set = setData(index(i, MSG_DB_IMPORTANT_INDEX), important);
if (set) {
emit dataChanged(index(i, 0), index(i, MSG_DB_CUSTOM_HASH_INDEX));
}
if (set) {
emit dataChanged(index(i, 0), index(i, MSG_DB_CUSTOM_HASH_INDEX));
}
return set;
}
}
return set;
}
}
return false;
return false;
}
void MessagesModel::highlightMessages(MessagesModel::MessageHighlighter highlight) {
m_messageHighlighter = highlight;
emit layoutAboutToBeChanged();
emit layoutChanged();
m_messageHighlighter = highlight;
emit layoutAboutToBeChanged();
emit layoutChanged();
}
int MessagesModel::messageId(int row_index) const {
return data(row_index, MSG_DB_ID_INDEX, Qt::EditRole).toInt();
return data(row_index, MSG_DB_ID_INDEX, Qt::EditRole).toInt();
}
RootItem::Importance MessagesModel::messageImportance(int row_index) const {
return (RootItem::Importance) data(row_index, MSG_DB_IMPORTANT_INDEX, Qt::EditRole).toInt();
return (RootItem::Importance) data(row_index, MSG_DB_IMPORTANT_INDEX, Qt::EditRole).toInt();
}
RootItem *MessagesModel::loadedItem() const {
return m_selectedItem;
RootItem* MessagesModel::loadedItem() const {
return m_selectedItem;
}
void MessagesModel::updateDateFormat() {
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool()) {
m_customDateFormat = qApp->settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString();
}
else {
m_customDateFormat = QString();
}
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool()) {
m_customDateFormat = qApp->settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString();
}
else {
m_customDateFormat = QString();
}
}
void MessagesModel::reloadWholeLayout() {
emit layoutAboutToBeChanged();
emit layoutChanged();
emit layoutAboutToBeChanged();
emit layoutChanged();
}
Message MessagesModel::messageAt(int row_index) const {
return Message::fromSqlRecord(m_cache->containsData(row_index) ? m_cache->record(row_index) : record(row_index));
Message MessagesModel::messageAt(int row_index) const {
return Message::fromSqlRecord(m_cache->containsData(row_index) ? m_cache->record(row_index) : record(row_index));
}
void MessagesModel::setupHeaderData() {
m_headerData << /*: Tooltip for ID of message.*/ tr("Id") <<
/*: Tooltip for "read" column in msg list.*/ tr("Read") <<
/*: Tooltip for "deleted" column in msg list.*/ tr("Deleted") <<
/*: Tooltip for "important" column in msg list.*/ tr("Important") <<
/*: Tooltip for name of feed for message.*/ tr("Feed") <<
/*: Tooltip for title of message.*/ tr("Title") <<
/*: Tooltip for url of message.*/ tr("Url") <<
/*: Tooltip for author of message.*/ tr("Author") <<
/*: Tooltip for creation date of message.*/ tr("Created on") <<
/*: Tooltip for contents of message.*/ tr("Contents") <<
/*: Tooltip for "pdeleted" column in msg list.*/ tr("Permanently deleted") <<
/*: Tooltip for attachments of message.*/ tr("Attachments") <<
/*: Tooltip for account ID of message.*/ tr("Account ID") <<
/*: Tooltip for custom ID of message.*/ tr("Custom ID") <<
/*: Tooltip for custom hash string of message.*/ tr("Custom hash") <<
/*: Tooltip for custom ID of feed of message.*/ tr("Feed ID");;
m_tooltipData << tr("Id of the message.") << tr("Is message read?") <<
tr("Is message deleted?") << tr("Is message important?") <<
tr("Id of feed which this message belongs to.") <<
tr("Title of the message.") << tr("Url of the message.") <<
tr("Author of the message.") << tr("Creation date of the message.") <<
tr("Contents of the message.") << tr("Is message permanently deleted from recycle bin?") <<
tr("List of attachments.") << tr("Account ID of the message.") << tr("Custom ID of the message") <<
tr("Custom hash of the message.") << tr("Custom ID of feed of the message.");
m_headerData << /*: Tooltip for ID of message.*/ tr("Id") <<
/*: Tooltip for "read" column in msg list.*/ tr("Read") <<
/*: Tooltip for "deleted" column in msg list.*/ tr("Deleted") <<
/*: Tooltip for "important" column in msg list.*/ tr("Important") <<
/*: Tooltip for name of feed for message.*/ tr("Feed") <<
/*: Tooltip for title of message.*/ tr("Title") <<
/*: Tooltip for url of message.*/ tr("Url") <<
/*: Tooltip for author of message.*/ tr("Author") <<
/*: Tooltip for creation date of message.*/ tr("Created on") <<
/*: Tooltip for contents of message.*/ tr("Contents") <<
/*: Tooltip for "pdeleted" column in msg list.*/ tr("Permanently deleted") <<
/*: Tooltip for attachments of message.*/ tr("Attachments") <<
/*: Tooltip for account ID of message.*/ tr("Account ID") <<
/*: Tooltip for custom ID of message.*/ tr("Custom ID") <<
/*: Tooltip for custom hash string of message.*/ tr("Custom hash") <<
/*: Tooltip for custom ID of feed of message.*/ tr("Feed ID");;
m_tooltipData << tr("Id of the message.") << tr("Is message read?") <<
tr("Is message deleted?") << tr("Is message important?") <<
tr("Id of feed which this message belongs to.") <<
tr("Title of the message.") << tr("Url of the message.") <<
tr("Author of the message.") << tr("Creation date of the message.") <<
tr("Contents of the message.") << tr("Is message permanently deleted from recycle bin?") <<
tr("List of attachments.") << tr("Account ID of the message.") << tr("Custom ID of the message") <<
tr("Custom hash of the message.") << tr("Custom ID of feed of the message.");
}
Qt::ItemFlags MessagesModel::flags(const QModelIndex &index) const {
Q_UNUSED(index)
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemNeverHasChildren;
Qt::ItemFlags MessagesModel::flags(const QModelIndex& index) const {
Q_UNUSED(index)
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemNeverHasChildren;
}
QVariant MessagesModel::data(int row, int column, int role) const {
return data(index(row, column), role);
return data(index(row, column), role);
}
QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
// This message is not in cache, return real data from live query.
switch (role) {
// Human readable data for viewing.
case Qt::DisplayRole: {
int index_column = idx.column();
QVariant MessagesModel::data(const QModelIndex& idx, int role) const {
// This message is not in cache, return real data from live query.
switch (role) {
// Human readable data for viewing.
case Qt::DisplayRole: {
int index_column = idx.column();
if (index_column == MSG_DB_DCREATED_INDEX) {
QDateTime dt = TextFactory::parseDateTime(QSqlQueryModel::data(idx, role).value<qint64>()).toLocalTime();
if (index_column == MSG_DB_DCREATED_INDEX) {
QDateTime dt = TextFactory::parseDateTime(QSqlQueryModel::data(idx, role).value<qint64>()).toLocalTime();
if (m_customDateFormat.isEmpty()) {
return dt.toString(Qt::DefaultLocaleShortDate);
}
else {
return dt.toString(m_customDateFormat);
}
}
else if (index_column == MSG_DB_AUTHOR_INDEX) {
const QString author_name = QSqlQueryModel::data(idx, role).toString();
if (m_customDateFormat.isEmpty()) {
return dt.toString(Qt::DefaultLocaleShortDate);
}
return author_name.isEmpty() ? QSL("-") : author_name;
}
else if (index_column != MSG_DB_IMPORTANT_INDEX && index_column != MSG_DB_READ_INDEX) {
return QSqlQueryModel::data(idx, role);
}
else {
return QVariant();
}
}
else {
return dt.toString(m_customDateFormat);
}
}
case Qt::EditRole:
return m_cache->containsData(idx.row()) ? m_cache->data(idx) : QSqlQueryModel::data(idx, role);
else if (index_column == MSG_DB_AUTHOR_INDEX) {
const QString author_name = QSqlQueryModel::data(idx, role).toString();
return author_name.isEmpty() ? QSL("-") : author_name;
}
case Qt::FontRole: {
QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX);
QVariant data_read = data(idx_read, Qt::EditRole);
else if (index_column != MSG_DB_IMPORTANT_INDEX && index_column != MSG_DB_READ_INDEX) {
return QSqlQueryModel::data(idx, role);
}
const bool is_bin = qobject_cast<RecycleBin*>(loadedItem()) != nullptr;
bool is_deleted;
else {
return QVariant();
}
}
if (is_bin) {
QModelIndex idx_del = index(idx.row(), MSG_DB_PDELETED_INDEX);
is_deleted = data(idx_del, Qt::EditRole).toBool();
}
else {
QModelIndex idx_del = index(idx.row(), MSG_DB_DELETED_INDEX);
is_deleted = data(idx_del, Qt::EditRole).toBool();
}
case Qt::EditRole:
return m_cache->containsData(idx.row()) ? m_cache->data(idx) : QSqlQueryModel::data(idx, role);
const bool striked = is_deleted;
case Qt::FontRole: {
QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX);
QVariant data_read = data(idx_read, Qt::EditRole);
const bool is_bin = qobject_cast<RecycleBin*>(loadedItem()) != nullptr;
bool is_deleted;
if (data_read.toBool()) {
return striked ? m_normalStrikedFont : m_normalFont;
}
else {
return striked ? m_boldStrikedFont : m_boldFont;
}
}
if (is_bin) {
QModelIndex idx_del = index(idx.row(), MSG_DB_PDELETED_INDEX);
is_deleted = data(idx_del, Qt::EditRole).toBool();
}
case Qt::ForegroundRole:
switch (m_messageHighlighter) {
case HighlightImportant: {
QModelIndex idx_important = index(idx.row(), MSG_DB_IMPORTANT_INDEX);
QVariant dta = m_cache->containsData(idx_important.row()) ? m_cache->data(idx_important) : QSqlQueryModel::data(idx_important);
else {
QModelIndex idx_del = index(idx.row(), MSG_DB_DELETED_INDEX);
is_deleted = data(idx_del, Qt::EditRole).toBool();
}
return dta.toInt() == 1 ? QColor(Qt::blue) : QVariant();
}
const bool striked = is_deleted;
case HighlightUnread: {
QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX);
QVariant dta = m_cache->containsData(idx_read.row()) ? m_cache->data(idx_read) : QSqlQueryModel::data(idx_read);
if (data_read.toBool()) {
return striked ? m_normalStrikedFont : m_normalFont;
}
return dta.toInt() == 0 ? QColor(Qt::blue) : QVariant();
}
else {
return striked ? m_boldStrikedFont : m_boldFont;
}
}
case NoHighlighting:
default:
return QVariant();
}
case Qt::ForegroundRole:
switch (m_messageHighlighter) {
case HighlightImportant: {
QModelIndex idx_important = index(idx.row(), MSG_DB_IMPORTANT_INDEX);
QVariant dta = m_cache->containsData(idx_important.row()) ? m_cache->data(idx_important) : QSqlQueryModel::data(idx_important);
return dta.toInt() == 1 ? QColor(Qt::blue) : QVariant();
}
case Qt::DecorationRole: {
const int index_column = idx.column();
case HighlightUnread: {
QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX);
QVariant dta = m_cache->containsData(idx_read.row()) ? m_cache->data(idx_read) : QSqlQueryModel::data(idx_read);
return dta.toInt() == 0 ? QColor(Qt::blue) : QVariant();
}
if (index_column == MSG_DB_READ_INDEX) {
QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX);
QVariant dta = m_cache->containsData(idx_read.row()) ? m_cache->data(idx_read) : QSqlQueryModel::data(idx_read);
case NoHighlighting:
default:
return QVariant();
}
return dta.toInt() == 1 ? m_readIcon : m_unreadIcon;
}
else if (index_column == MSG_DB_IMPORTANT_INDEX) {
QModelIndex idx_important = index(idx.row(), MSG_DB_IMPORTANT_INDEX);
QVariant dta = m_cache->containsData(idx_important.row()) ? m_cache->data(idx_important) : QSqlQueryModel::data(idx_important);
case Qt::DecorationRole: {
const int index_column = idx.column();
return dta.toInt() == 1 ? m_favoriteIcon : QVariant();
}
else {
return QVariant();
}
}
if (index_column == MSG_DB_READ_INDEX) {
QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX);
QVariant dta = m_cache->containsData(idx_read.row()) ? m_cache->data(idx_read) : QSqlQueryModel::data(idx_read);
return dta.toInt() == 1 ? m_readIcon : m_unreadIcon;
}
default:
return QVariant();
}
else if (index_column == MSG_DB_IMPORTANT_INDEX) {
QModelIndex idx_important = index(idx.row(), MSG_DB_IMPORTANT_INDEX);
QVariant dta = m_cache->containsData(idx_important.row()) ? m_cache->data(idx_important) : QSqlQueryModel::data(idx_important);
return dta.toInt() == 1 ? m_favoriteIcon : QVariant();
}
else {
return QVariant();
}
}
default:
return QVariant();
}
}
bool MessagesModel::setMessageRead(int row_index, RootItem::ReadStatus read) {
if (data(row_index, MSG_DB_READ_INDEX, Qt::EditRole).toInt() == read) {
// Read status is the same is the one currently set.
// In that case, no extra work is needed.
return true;
}
if (data(row_index, MSG_DB_READ_INDEX, Qt::EditRole).toInt() == read) {
// Read status is the same is the one currently set.
// In that case, no extra work is needed.
return true;
}
Message message = messageAt(row_index);
Message message = messageAt(row_index);
if (!m_selectedItem->getParentServiceRoot()->onBeforeSetMessagesRead(m_selectedItem, QList<Message>() << message, read)) {
// Cannot change read status of the item. Abort.
return false;
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeSetMessagesRead(m_selectedItem, QList<Message>() << message, read)) {
// Cannot change read status of the item. Abort.
return false;
}
// Rewrite "visible" data in the model.
bool working_change = setData(index(row_index, MSG_DB_READ_INDEX), read);
// Rewrite "visible" data in the model.
bool working_change = setData(index(row_index, MSG_DB_READ_INDEX), read);
if (!working_change) {
// If rewriting in the model failed, then cancel all actions.
qDebug("Setting of new data to the model failed for message read change.");
return false;
}
if (!working_change) {
// If rewriting in the model failed, then cancel all actions.
qDebug("Setting of new data to the model failed for message read change.");
return false;
}
if (DatabaseQueries::markMessagesReadUnread(m_db, QStringList() << QString::number(message.m_id), read)) {
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList<Message>() << message, read);
}
else {
return false;
}
if (DatabaseQueries::markMessagesReadUnread(m_db, QStringList() << QString::number(message.m_id), read)) {
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList<Message>() << message, read);
}
else {
return false;
}
}
bool MessagesModel::setMessageReadById(int id, RootItem::ReadStatus read) {
for (int i = 0; i < rowCount(); i++) {
int found_id = data(i, MSG_DB_ID_INDEX, Qt::EditRole).toInt();
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_READ_INDEX), read);
if (found_id == id) {
bool set = setData(index(i, MSG_DB_READ_INDEX), read);
if (set) {
emit dataChanged(index(i, 0), index(i, MSG_DB_CUSTOM_HASH_INDEX));
}
if (set) {
emit dataChanged(index(i, 0), index(i, MSG_DB_CUSTOM_HASH_INDEX));
}
return set;
}
}
return set;
}
}
return false;
return false;
}
bool MessagesModel::switchMessageImportance(int row_index) {
const QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX);
const RootItem::Importance current_importance = (RootItem::Importance) data(target_index, Qt::EditRole).toInt();
const RootItem::Importance next_importance = current_importance == RootItem::Important ?
RootItem::NotImportant : RootItem::Important;
const Message message = messageAt(row_index);
const QPair<Message,RootItem::Importance> pair(message, next_importance);
const QModelIndex target_index = index(row_index, MSG_DB_IMPORTANT_INDEX);
const RootItem::Importance current_importance = (RootItem::Importance) data(target_index, Qt::EditRole).toInt();
const RootItem::Importance next_importance = current_importance == RootItem::Important ?
RootItem::NotImportant : RootItem::Important;
const Message message = messageAt(row_index);
const QPair<Message, RootItem::Importance> pair(message, next_importance);
if (!m_selectedItem->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_selectedItem,
QList<QPair<Message,RootItem::Importance> >() << pair)) {
return false;
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_selectedItem,
QList<QPair<Message, RootItem::Importance>>() << pair)) {
return false;
}
// Rewrite "visible" data in the model.
const bool working_change = setData(target_index, next_importance);
// Rewrite "visible" data in the model.
const bool working_change = setData(target_index, next_importance);
if (!working_change) {
// If rewriting in the model failed, then cancel all actions.
qDebug("Setting of new data to the model failed for message importance change.");
return false;
}
if (!working_change) {
// If rewriting in the model failed, then cancel all actions.
qDebug("Setting of new data to the model failed for message importance change.");
return false;
}
// Commit changes.
if (DatabaseQueries::markMessageImportant(m_db, message.m_id, next_importance)) {
emit dataChanged(index(row_index, 0), index(row_index, MSG_DB_FEED_CUSTOM_ID_INDEX), QVector<int>() << Qt::FontRole);
// Commit changes.
if (DatabaseQueries::markMessageImportant(m_db, message.m_id, next_importance)) {
emit dataChanged(index(row_index, 0), index(row_index, MSG_DB_FEED_CUSTOM_ID_INDEX), QVector<int>() << Qt::FontRole);
return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem,
QList<QPair<Message, RootItem::Importance>>() << pair);
}
return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem,
QList<QPair<Message,RootItem::Importance> >() << pair);
}
else {
return false;
}
else {
return false;
}
}
bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages) {
QStringList message_ids;
QList<QPair<Message,RootItem::Importance> > message_states;
bool MessagesModel::switchBatchMessageImportance(const QModelIndexList& messages) {
QStringList message_ids;
QList<QPair<Message, RootItem::Importance>> message_states;
// Obtain IDs of all desired messages.
foreach (const QModelIndex &message, messages) {
const Message msg = messageAt(message.row());
RootItem::Importance message_importance = messageImportance((message.row()));
// Obtain IDs of all desired messages.
foreach (const QModelIndex& message, messages) {
const Message msg = messageAt(message.row());
RootItem::Importance message_importance = messageImportance((message.row()));
message_states.append(QPair<Message, RootItem::Importance>(msg, message_importance == RootItem::Important ?
RootItem::NotImportant :
RootItem::Important));
message_ids.append(QString::number(msg.m_id));
QModelIndex idx_msg_imp = index(message.row(), MSG_DB_IMPORTANT_INDEX);
setData(idx_msg_imp, message_importance == RootItem::Important ?
(int) RootItem::NotImportant :
(int) RootItem::Important);
}
message_states.append(QPair<Message,RootItem::Importance>(msg, message_importance == RootItem::Important ?
RootItem::NotImportant :
RootItem::Important));
message_ids.append(QString::number(msg.m_id));
reloadWholeLayout();
QModelIndex idx_msg_imp = index(message.row(), MSG_DB_IMPORTANT_INDEX);
setData(idx_msg_imp, message_importance == RootItem::Important ?
(int) RootItem::NotImportant :
(int) RootItem::Important);
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_selectedItem, message_states)) {
return false;
}
reloadWholeLayout();
if (DatabaseQueries::switchMessagesImportance(m_db, message_ids)) {
return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem, message_states);
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_selectedItem, message_states)) {
return false;
}
if (DatabaseQueries::switchMessagesImportance(m_db, message_ids)) {
return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem, message_states);
}
else {
return false;
}
else {
return false;
}
}
bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages) {
QStringList message_ids;
QList<Message> msgs;
bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList& messages) {
QStringList message_ids;
QList<Message> msgs;
// Obtain IDs of all desired messages.
foreach (const QModelIndex &message, messages) {
const Message msg = messageAt(message.row());
// Obtain IDs of all desired messages.
foreach (const QModelIndex& message, messages) {
const Message msg = messageAt(message.row());
msgs.append(msg);
message_ids.append(QString::number(msg.m_id));
msgs.append(msg);
message_ids.append(QString::number(msg.m_id));
if (qobject_cast<RecycleBin*>(m_selectedItem) != nullptr) {
setData(index(message.row(), MSG_DB_PDELETED_INDEX), 1);
}
if (qobject_cast<RecycleBin*>(m_selectedItem) != nullptr) {
setData(index(message.row(), MSG_DB_PDELETED_INDEX), 1);
}
else {
setData(index(message.row(), MSG_DB_DELETED_INDEX), 1);
}
}
else {
setData(index(message.row(), MSG_DB_DELETED_INDEX), 1);
}
}
reloadWholeLayout();
reloadWholeLayout();
if (!m_selectedItem->getParentServiceRoot()->onBeforeMessagesDelete(m_selectedItem, msgs)) {
return false;
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeMessagesDelete(m_selectedItem, msgs)) {
return false;
}
bool deleted;
bool deleted;
if (m_selectedItem->kind() != RootItemKind::Bin) {
deleted = DatabaseQueries::deleteOrRestoreMessagesToFromBin(m_db, message_ids, true);
}
else {
deleted = DatabaseQueries::permanentlyDeleteMessages(m_db, message_ids);
}
if (m_selectedItem->kind() != RootItemKind::Bin) {
deleted = DatabaseQueries::deleteOrRestoreMessagesToFromBin(m_db, message_ids, true);
}
if (deleted) {
return m_selectedItem->getParentServiceRoot()->onAfterMessagesDelete(m_selectedItem, msgs);
}
else {
return false;
}
else {
deleted = DatabaseQueries::permanentlyDeleteMessages(m_db, message_ids);
}
if (deleted) {
return m_selectedItem->getParentServiceRoot()->onAfterMessagesDelete(m_selectedItem, msgs);
}
else {
return false;
}
}
bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, RootItem::ReadStatus read) {
QStringList message_ids;
QList<Message> msgs;
bool MessagesModel::setBatchMessagesRead(const QModelIndexList& messages, RootItem::ReadStatus read) {
QStringList message_ids;
QList<Message> msgs;
// Obtain IDs of all desired messages.
foreach (const QModelIndex &message, messages) {
Message msg = messageAt(message.row());
// Obtain IDs of all desired messages.
foreach (const QModelIndex& message, messages) {
Message msg = messageAt(message.row());
msgs.append(msg);
message_ids.append(QString::number(msg.m_id));
setData(index(message.row(), MSG_DB_READ_INDEX), (int) read);
}
msgs.append(msg);
message_ids.append(QString::number(msg.m_id));
reloadWholeLayout();
setData(index(message.row(), MSG_DB_READ_INDEX), (int) read);
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeSetMessagesRead(m_selectedItem, msgs, read)) {
return false;
}
reloadWholeLayout();
if (DatabaseQueries::markMessagesReadUnread(m_db, message_ids, read)) {
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, msgs, read);
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeSetMessagesRead(m_selectedItem, msgs, read)) {
return false;
}
if (DatabaseQueries::markMessagesReadUnread(m_db, message_ids, read)) {
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, msgs, read);
}
else {
return false;
}
else {
return false;
}
}
bool MessagesModel::setBatchMessagesRestored(const QModelIndexList &messages) {
QStringList message_ids;
QList<Message> msgs;
bool MessagesModel::setBatchMessagesRestored(const QModelIndexList& messages) {
QStringList message_ids;
QList<Message> msgs;
// Obtain IDs of all desired messages.
foreach (const QModelIndex &message, messages) {
const Message msg = messageAt(message.row());
// Obtain IDs of all desired messages.
foreach (const QModelIndex& message, messages) {
const Message msg = messageAt(message.row());
msgs.append(msg);
message_ids.append(QString::number(msg.m_id));
setData(index(message.row(), MSG_DB_PDELETED_INDEX), 0);
setData(index(message.row(), MSG_DB_DELETED_INDEX), 0);
}
msgs.append(msg);
message_ids.append(QString::number(msg.m_id));
reloadWholeLayout();
setData(index(message.row(), MSG_DB_PDELETED_INDEX), 0);
setData(index(message.row(), MSG_DB_DELETED_INDEX), 0);
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeMessagesRestoredFromBin(m_selectedItem, msgs)) {
return false;
}
reloadWholeLayout();
if (DatabaseQueries::deleteOrRestoreMessagesToFromBin(m_db, message_ids, false)) {
return m_selectedItem->getParentServiceRoot()->onAfterMessagesRestoredFromBin(m_selectedItem, msgs);
}
if (!m_selectedItem->getParentServiceRoot()->onBeforeMessagesRestoredFromBin(m_selectedItem, msgs)) {
return false;
}
if (DatabaseQueries::deleteOrRestoreMessagesToFromBin(m_db, message_ids, false)) {
return m_selectedItem->getParentServiceRoot()->onAfterMessagesRestoredFromBin(m_selectedItem, msgs);
}
else {
return false;
}
else {
return false;
}
}
QVariant MessagesModel::headerData(int section, Qt::Orientation orientation, int role) const {
Q_UNUSED(orientation)
Q_UNUSED(orientation)
switch (role) {
case Qt::DisplayRole:
// Display textual headers for all columns except "read" and
// "important" columns.
if (section != MSG_DB_READ_INDEX && section != MSG_DB_IMPORTANT_INDEX) {
return m_headerData.at(section);
}
else {
return QVariant();
}
switch (role) {
case Qt::DisplayRole:
case Qt::ToolTipRole:
return m_tooltipData.at(section);
// Display textual headers for all columns except "read" and
// "important" columns.
if (section != MSG_DB_READ_INDEX && section != MSG_DB_IMPORTANT_INDEX) {
return m_headerData.at(section);
}
case Qt::EditRole:
return m_headerData.at(section);
else {
return QVariant();
}
// Display icons for "read" and "important" columns.
case Qt::DecorationRole: {
switch (section) {
case MSG_DB_READ_INDEX:
return m_readIcon;
case Qt::ToolTipRole:
return m_tooltipData.at(section);
case MSG_DB_IMPORTANT_INDEX:
return m_favoriteIcon;
case Qt::EditRole:
return m_headerData.at(section);
default:
return QVariant();
}
}
// Display icons for "read" and "important" columns.
case Qt::DecorationRole: {
switch (section) {
case MSG_DB_READ_INDEX:
return m_readIcon;
default:
return QVariant();
}
case MSG_DB_IMPORTANT_INDEX:
return m_favoriteIcon;
default:
return QVariant();
}
}
default:
return QVariant();
}
}

View File

@ -32,84 +32,84 @@
class MessagesModelCache;
class MessagesModel : public QSqlQueryModel, public MessagesModelSqlLayer {
Q_OBJECT
Q_OBJECT
public:
// Enum which describes basic filtering schemes
// for messages.
enum MessageHighlighter {
NoHighlighting = 100,
HighlightUnread = 101,
HighlightImportant = 102
};
public:
// Enum which describes basic filtering schemes
// for messages.
enum MessageHighlighter {
NoHighlighting = 100,
HighlightUnread = 101,
HighlightImportant = 102
};
// Constructors and destructors.
explicit MessagesModel(QObject *parent = 0);
virtual ~MessagesModel();
// Constructors and destructors.
explicit MessagesModel(QObject* parent = 0);
virtual ~MessagesModel();
// Fetches ALL available data to the model.
// NOTE: This activates the SQL query and populates the model with new data.
void repopulate();
// Fetches ALL available data to the model.
// NOTE: This activates the SQL query and populates the model with new data.
void repopulate();
// Model implementation.
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QVariant data(int row, int column, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
// Model implementation.
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
QVariant data(int row, int column, int role = Qt::DisplayRole) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
Qt::ItemFlags flags(const QModelIndex& index) const;
// Returns message at given index.
Message messageAt(int row_index) const;
int messageId(int row_index) const;
RootItem::Importance messageImportance(int row_index) const;
// Returns message at given index.
Message messageAt(int row_index) const;
int messageId(int row_index) const;
RootItem::Importance messageImportance(int row_index) const;
RootItem *loadedItem() const;
void updateDateFormat();
void reloadWholeLayout();
RootItem* loadedItem() const;
void updateDateFormat();
void reloadWholeLayout();
// SINGLE message manipulators.
bool switchMessageImportance(int row_index);
bool setMessageRead(int row_index, RootItem::ReadStatus read);
// SINGLE message manipulators.
bool switchMessageImportance(int row_index);
bool setMessageRead(int row_index, RootItem::ReadStatus read);
// BATCH messages manipulators.
bool switchBatchMessageImportance(const QModelIndexList &messages);
bool setBatchMessagesDeleted(const QModelIndexList &messages);
bool setBatchMessagesRead(const QModelIndexList &messages, RootItem::ReadStatus read);
bool setBatchMessagesRestored(const QModelIndexList &messages);
// BATCH messages manipulators.
bool switchBatchMessageImportance(const QModelIndexList& messages);
bool setBatchMessagesDeleted(const QModelIndexList& messages);
bool setBatchMessagesRead(const QModelIndexList& messages, RootItem::ReadStatus read);
bool setBatchMessagesRestored(const QModelIndexList& messages);
// Highlights messages.
void highlightMessages(MessageHighlighter highlight);
// Highlights messages.
void highlightMessages(MessageHighlighter highlight);
// Loads messages of given feeds.
void loadMessages(RootItem *item);
// Loads messages of given feeds.
void loadMessages(RootItem* item);
public slots:
// NOTE: These methods DO NOT actually change data in the DB, just in the model.
// These are particularly used by msg browser.
bool setMessageImportantById(int id, RootItem::Importance important);
bool setMessageReadById(int id, RootItem::ReadStatus read);
public slots:
// NOTE: These methods DO NOT actually change data in the DB, just in the model.
// These are particularly used by msg browser.
bool setMessageImportantById(int id, RootItem::Importance important);
bool setMessageReadById(int id, RootItem::ReadStatus read);
private:
void setupHeaderData();
void setupFonts();
void setupIcons();
private:
void setupHeaderData();
void setupFonts();
void setupIcons();
MessagesModelCache *m_cache;
MessageHighlighter m_messageHighlighter;
MessagesModelCache* m_cache;
MessageHighlighter m_messageHighlighter;
QString m_customDateFormat;
RootItem *m_selectedItem;
QList<QString> m_headerData;
QList<QString> m_tooltipData;
QString m_customDateFormat;
RootItem* m_selectedItem;
QList<QString> m_headerData;
QList<QString> m_tooltipData;
QFont m_normalFont;
QFont m_boldFont;
QFont m_normalStrikedFont;
QFont m_boldStrikedFont;
QFont m_normalFont;
QFont m_boldFont;
QFont m_normalStrikedFont;
QFont m_boldStrikedFont;
QIcon m_favoriteIcon;
QIcon m_readIcon;
QIcon m_unreadIcon;
QIcon m_favoriteIcon;
QIcon m_readIcon;
QIcon m_unreadIcon;
};
Q_DECLARE_METATYPE(MessagesModel::MessageHighlighter)

View File

@ -1,39 +1,39 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/messagesmodelcache.h"
#include "miscellaneous/textfactory.h"
MessagesModelCache::MessagesModelCache(QObject *parent) : QObject(parent), m_msgCache(QHash<int,QSqlRecord>()) {
}
MessagesModelCache::~MessagesModelCache() {
}
void MessagesModelCache::setData(const QModelIndex &index, const QVariant &value, const QSqlRecord &record) {
if (!m_msgCache.contains(index.row())) {
m_msgCache[index.row()] = record;
}
m_msgCache[index.row()].setValue(index.column(), value);
}
QVariant MessagesModelCache::data(const QModelIndex &idx) {
return m_msgCache[idx.row()].value(idx.column());
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/messagesmodelcache.h"
#include "miscellaneous/textfactory.h"
MessagesModelCache::MessagesModelCache(QObject* parent) : QObject(parent), m_msgCache(QHash<int, QSqlRecord>()) {
}
MessagesModelCache::~MessagesModelCache() {
}
void MessagesModelCache::setData(const QModelIndex& index, const QVariant& value, const QSqlRecord& record) {
if (!m_msgCache.contains(index.row())) {
m_msgCache[index.row()] = record;
}
m_msgCache[index.row()].setValue(index.column(), value);
}
QVariant MessagesModelCache::data(const QModelIndex& idx) {
return m_msgCache[idx.row()].value(idx.column());
}

View File

@ -1,55 +1,55 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGESMODELCACHE_H
#define MESSAGESMODELCACHE_H
#include <QObject>
#include "core/message.h"
#include <QVariant>
#include <QModelIndex>
class MessagesModelCache : public QObject {
Q_OBJECT
public:
explicit MessagesModelCache(QObject *parent = nullptr);
virtual ~MessagesModelCache();
inline bool containsData(int row_idx) const {
return m_msgCache.contains(row_idx);
}
inline QSqlRecord record(int row_idx) const {
return m_msgCache.value(row_idx);
}
inline void clear() {
m_msgCache.clear();
}
void setData(const QModelIndex &index, const QVariant &value, const QSqlRecord &record);
QVariant data(const QModelIndex &idx);
private:
QHash<int,QSqlRecord> m_msgCache;
};
#endif // MESSAGESMODELCACHE_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGESMODELCACHE_H
#define MESSAGESMODELCACHE_H
#include <QObject>
#include "core/message.h"
#include <QVariant>
#include <QModelIndex>
class MessagesModelCache : public QObject {
Q_OBJECT
public:
explicit MessagesModelCache(QObject* parent = nullptr);
virtual ~MessagesModelCache();
inline bool containsData(int row_idx) const {
return m_msgCache.contains(row_idx);
}
inline QSqlRecord record(int row_idx) const {
return m_msgCache.value(row_idx);
}
inline void clear() {
m_msgCache.clear();
}
void setData(const QModelIndex& index, const QVariant& value, const QSqlRecord& record);
QVariant data(const QModelIndex& idx);
private:
QHash<int, QSqlRecord> m_msgCache;
};
#endif // MESSAGESMODELCACHE_H

View File

@ -1,105 +1,105 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/messagesmodelsqllayer.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
MessagesModelSqlLayer::MessagesModelSqlLayer()
: m_filter(QSL(DEFAULT_SQL_MESSAGES_FILTER)), m_fieldNames(QMap<int,QString>()),
m_sortColumns(QList<int>()), m_sortOrders(QList<Qt::SortOrder>()){
m_db = qApp->database()->connection(QSL("MessagesModel"), DatabaseFactory::FromSettings);
m_fieldNames[MSG_DB_ID_INDEX] = "Messages.id";
m_fieldNames[MSG_DB_READ_INDEX] = "Messages.is_read";
m_fieldNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted";
m_fieldNames[MSG_DB_IMPORTANT_INDEX] = "Messages.is_important";
m_fieldNames[MSG_DB_FEED_TITLE_INDEX] = "Feeds.title";
m_fieldNames[MSG_DB_TITLE_INDEX] = "Messages.title";
m_fieldNames[MSG_DB_URL_INDEX] = "Messages.url";
m_fieldNames[MSG_DB_AUTHOR_INDEX] = "Messages.author";
m_fieldNames[MSG_DB_DCREATED_INDEX] = "Messages.date_created";
m_fieldNames[MSG_DB_CONTENTS_INDEX] = "Messages.contents";
m_fieldNames[MSG_DB_PDELETED_INDEX] = "Messages.is_pdeleted";
m_fieldNames[MSG_DB_ENCLOSURES_INDEX] = "Messages.enclosures";
m_fieldNames[MSG_DB_ACCOUNT_ID_INDEX] = "Messages.account_id";
m_fieldNames[MSG_DB_CUSTOM_ID_INDEX] = "Messages.custom_id";
m_fieldNames[MSG_DB_CUSTOM_HASH_INDEX] = "Messages.custom_hash";
m_fieldNames[MSG_DB_FEED_CUSTOM_ID_INDEX] = "Messages.feed";
}
void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order) {
int existing = m_sortColumns.indexOf(column);
bool is_ctrl_pressed = (QApplication::queryKeyboardModifiers() & Qt::ControlModifier) == Qt::ControlModifier;
if (existing >= 0) {
m_sortColumns.removeAt(existing);
m_sortOrders.removeAt(existing);
}
if (m_sortColumns.size() > MAX_MULTICOLUMN_SORT_STATES) {
// We support only limited number of sort states
// due to DB performance.
m_sortColumns.removeAt(0);
m_sortOrders.removeAt(0);
}
if (is_ctrl_pressed) {
// User is activating the multicolumn sort mode.
m_sortColumns.append(column);
m_sortOrders.append(order);
}
else {
m_sortColumns.prepend(column);
m_sortOrders.prepend(order);
}
qDebug("Added sort state, select statement is now:\n'%s'", qPrintable(selectStatement()));
}
void MessagesModelSqlLayer::setFilter(const QString &filter) {
m_filter = filter;
}
QString MessagesModelSqlLayer::formatFields() const {
return m_fieldNames.values().join(QSL(", "));
}
QString MessagesModelSqlLayer::selectStatement() const {
return QL1S("SELECT ") + formatFields() +
QSL(" FROM Messages LEFT JOIN Feeds ON Messages.feed = Feeds.custom_id AND Messages.account_id = Feeds.account_id WHERE ") +
m_filter + orderByClause() + QL1C(';');
}
QString MessagesModelSqlLayer::orderByClause() const {
if (m_sortColumns.isEmpty()) {
return QString();
}
else {
QStringList sorts;
for (int i = 0; i < m_sortColumns.size(); i++) {
QString field_name(m_fieldNames[m_sortColumns[i]]);
sorts.append(field_name + (m_sortOrders[i] == Qt::AscendingOrder ? QSL(" ASC") : QSL(" DESC")));
}
return QL1S(" ORDER BY ") + sorts.join(QSL(", "));
}
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "core/messagesmodelsqllayer.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
MessagesModelSqlLayer::MessagesModelSqlLayer()
: m_filter(QSL(DEFAULT_SQL_MESSAGES_FILTER)), m_fieldNames(QMap<int, QString>()),
m_sortColumns(QList<int>()), m_sortOrders(QList<Qt::SortOrder>()) {
m_db = qApp->database()->connection(QSL("MessagesModel"), DatabaseFactory::FromSettings);
m_fieldNames[MSG_DB_ID_INDEX] = "Messages.id";
m_fieldNames[MSG_DB_READ_INDEX] = "Messages.is_read";
m_fieldNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted";
m_fieldNames[MSG_DB_IMPORTANT_INDEX] = "Messages.is_important";
m_fieldNames[MSG_DB_FEED_TITLE_INDEX] = "Feeds.title";
m_fieldNames[MSG_DB_TITLE_INDEX] = "Messages.title";
m_fieldNames[MSG_DB_URL_INDEX] = "Messages.url";
m_fieldNames[MSG_DB_AUTHOR_INDEX] = "Messages.author";
m_fieldNames[MSG_DB_DCREATED_INDEX] = "Messages.date_created";
m_fieldNames[MSG_DB_CONTENTS_INDEX] = "Messages.contents";
m_fieldNames[MSG_DB_PDELETED_INDEX] = "Messages.is_pdeleted";
m_fieldNames[MSG_DB_ENCLOSURES_INDEX] = "Messages.enclosures";
m_fieldNames[MSG_DB_ACCOUNT_ID_INDEX] = "Messages.account_id";
m_fieldNames[MSG_DB_CUSTOM_ID_INDEX] = "Messages.custom_id";
m_fieldNames[MSG_DB_CUSTOM_HASH_INDEX] = "Messages.custom_hash";
m_fieldNames[MSG_DB_FEED_CUSTOM_ID_INDEX] = "Messages.feed";
}
void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order) {
int existing = m_sortColumns.indexOf(column);
bool is_ctrl_pressed = (QApplication::queryKeyboardModifiers() & Qt::ControlModifier) == Qt::ControlModifier;
if (existing >= 0) {
m_sortColumns.removeAt(existing);
m_sortOrders.removeAt(existing);
}
if (m_sortColumns.size() > MAX_MULTICOLUMN_SORT_STATES) {
// We support only limited number of sort states
// due to DB performance.
m_sortColumns.removeAt(0);
m_sortOrders.removeAt(0);
}
if (is_ctrl_pressed) {
// User is activating the multicolumn sort mode.
m_sortColumns.append(column);
m_sortOrders.append(order);
}
else {
m_sortColumns.prepend(column);
m_sortOrders.prepend(order);
}
qDebug("Added sort state, select statement is now:\n'%s'", qPrintable(selectStatement()));
}
void MessagesModelSqlLayer::setFilter(const QString& filter) {
m_filter = filter;
}
QString MessagesModelSqlLayer::formatFields() const {
return m_fieldNames.values().join(QSL(", "));
}
QString MessagesModelSqlLayer::selectStatement() const {
return QL1S("SELECT ") + formatFields() +
QSL(" FROM Messages LEFT JOIN Feeds ON Messages.feed = Feeds.custom_id AND Messages.account_id = Feeds.account_id WHERE ") +
m_filter + orderByClause() + QL1C(';');
}
QString MessagesModelSqlLayer::orderByClause() const {
if (m_sortColumns.isEmpty()) {
return QString();
}
else {
QStringList sorts;
for (int i = 0; i < m_sortColumns.size(); i++) {
QString field_name(m_fieldNames[m_sortColumns[i]]);
sorts.append(field_name + (m_sortOrders[i] == Qt::AscendingOrder ? QSL(" ASC") : QSL(" DESC")));
}
return QL1S(" ORDER BY ") + sorts.join(QSL(", "));
}
}

View File

@ -1,56 +1,56 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGESMODELSQLLAYER_H
#define MESSAGESMODELSQLLAYER_H
#include <QSqlDatabase>
#include <QMap>
#include <QList>
class MessagesModelSqlLayer {
public:
explicit MessagesModelSqlLayer();
// Adds this new state to queue of sort states.
void addSortState(int column, Qt::SortOrder order);
// Sets SQL WHERE clause, without "WHERE" keyword.
void setFilter(const QString &filter);
protected:
QString orderByClause() const;
QString selectStatement() const;
QString formatFields() const;
QSqlDatabase m_db;
private:
QString m_filter;
// NOTE: These two lists contain data for multicolumn sorting.
// They are always same length. Most important sort column/order
// are located at the start of lists;
QMap<int,QString> m_fieldNames;
QList<int> m_sortColumns;
QList<Qt::SortOrder> m_sortOrders;
};
#endif // MESSAGESMODELSQLLAYER_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGESMODELSQLLAYER_H
#define MESSAGESMODELSQLLAYER_H
#include <QSqlDatabase>
#include <QMap>
#include <QList>
class MessagesModelSqlLayer {
public:
explicit MessagesModelSqlLayer();
// Adds this new state to queue of sort states.
void addSortState(int column, Qt::SortOrder order);
// Sets SQL WHERE clause, without "WHERE" keyword.
void setFilter(const QString& filter);
protected:
QString orderByClause() const;
QString selectStatement() const;
QString formatFields() const;
QSqlDatabase m_db;
private:
QString m_filter;
// NOTE: These two lists contain data for multicolumn sorting.
// They are always same length. Most important sort column/order
// are located at the start of lists;
QMap<int, QString> m_fieldNames;
QList<int> m_sortColumns;
QList<Qt::SortOrder> m_sortOrders;
};
#endif // MESSAGESMODELSQLLAYER_H

View File

@ -20,174 +20,181 @@
#include "core/messagesmodel.h"
MessagesProxyModel::MessagesProxyModel(MessagesModel *source_model, QObject *parent)
: QSortFilterProxyModel(parent), m_sourceModel(source_model) {
setObjectName(QSL("MessagesProxyModel"));
setSortRole(Qt::EditRole);
setSortCaseSensitivity(Qt::CaseInsensitive);
setFilterCaseSensitivity(Qt::CaseInsensitive);
setFilterKeyColumn(-1);
setFilterRole(Qt::EditRole);
setDynamicSortFilter(false);
setSourceModel(m_sourceModel);
MessagesProxyModel::MessagesProxyModel(MessagesModel* source_model, QObject* parent)
: QSortFilterProxyModel(parent), m_sourceModel(source_model) {
setObjectName(QSL("MessagesProxyModel"));
setSortRole(Qt::EditRole);
setSortCaseSensitivity(Qt::CaseInsensitive);
setFilterCaseSensitivity(Qt::CaseInsensitive);
setFilterKeyColumn(-1);
setFilterRole(Qt::EditRole);
setDynamicSortFilter(false);
setSourceModel(m_sourceModel);
}
MessagesProxyModel::~MessagesProxyModel() {
qDebug("Destroying MessagesProxyModel instance.");
qDebug("Destroying MessagesProxyModel instance.");
}
QModelIndex MessagesProxyModel::getNextPreviousUnreadItemIndex(int default_row) {
const bool started_from_zero = default_row == 0;
QModelIndex next_index = getNextUnreadItemIndex(default_row, rowCount() - 1);
const bool started_from_zero = default_row == 0;
QModelIndex next_index = getNextUnreadItemIndex(default_row, rowCount() - 1);
// There is no next message, check previous.
if (!next_index.isValid() && !started_from_zero) {
next_index = getNextUnreadItemIndex(0, default_row - 1);
}
// There is no next message, check previous.
if (!next_index.isValid() && !started_from_zero) {
next_index = getNextUnreadItemIndex(0, default_row - 1);
}
return next_index;
return next_index;
}
QModelIndex MessagesProxyModel::getNextUnreadItemIndex(int default_row, int max_row) const {
while (default_row <= max_row) {
// Get info if the message is read or not.
const QModelIndex proxy_index = index(default_row, MSG_DB_READ_INDEX);
const bool is_read = m_sourceModel->data(mapToSource(proxy_index).row(),
MSG_DB_READ_INDEX, Qt::EditRole).toInt() == 1;
while (default_row <= max_row) {
// Get info if the message is read or not.
const QModelIndex proxy_index = index(default_row, MSG_DB_READ_INDEX);
const bool is_read = m_sourceModel->data(mapToSource(proxy_index).row(),
MSG_DB_READ_INDEX, Qt::EditRole).toInt() == 1;
if (!is_read) {
// We found unread message, mark it.
return proxy_index;
}
else {
default_row++;
}
}
if (!is_read) {
// We found unread message, mark it.
return proxy_index;
}
return QModelIndex();
else {
default_row++;
}
}
return QModelIndex();
}
bool MessagesProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const {
Q_UNUSED(left)
Q_UNUSED(right)
// NOTE: Comparisons are done by SQL servers itself, not client-side.
return false;
bool MessagesProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const {
Q_UNUSED(left)
Q_UNUSED(right)
// NOTE: Comparisons are done by SQL servers itself, not client-side.
return false;
}
QModelIndexList MessagesProxyModel::mapListFromSource(const QModelIndexList &indexes, bool deep) const {
QModelIndexList mapped_indexes;
QModelIndexList MessagesProxyModel::mapListFromSource(const QModelIndexList& indexes, bool deep) const {
QModelIndexList mapped_indexes;
foreach (const QModelIndex &index, indexes) {
if (deep) {
// Construct new source index.
mapped_indexes << mapFromSource(m_sourceModel->index(index.row(), index.column()));
}
else {
mapped_indexes << mapFromSource(index);
}
}
foreach (const QModelIndex& index, indexes) {
if (deep) {
// Construct new source index.
mapped_indexes << mapFromSource(m_sourceModel->index(index.row(), index.column()));
}
return mapped_indexes;
else {
mapped_indexes << mapFromSource(index);
}
}
return mapped_indexes;
}
QModelIndexList MessagesProxyModel::match(const QModelIndex &start, int role,
const QVariant &entered_value, int hits, Qt::MatchFlags flags) const {
QModelIndexList result;
const uint match_type = flags & 0x0F;
const Qt::CaseSensitivity case_sensitivity = Qt::CaseInsensitive;
const bool wrap = flags & Qt::MatchWrap;
const bool all_hits = (hits == -1);
QString entered_text;
int from = start.row();
int to = rowCount();
QModelIndexList MessagesProxyModel::match(const QModelIndex& start, int role,
const QVariant& entered_value, int hits, Qt::MatchFlags flags) const {
QModelIndexList result;
const uint match_type = flags & 0x0F;
const Qt::CaseSensitivity case_sensitivity = Qt::CaseInsensitive;
const bool wrap = flags & Qt::MatchWrap;
const bool all_hits = (hits == -1);
QString entered_text;
int from = start.row();
int to = rowCount();
for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); i++) {
for (int r = from; (r < to) && (all_hits || result.count() < hits); r++) {
QModelIndex idx = index(r, start.column());
for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); i++) {
for (int r = from; (r < to) && (all_hits || result.count() < hits); r++) {
QModelIndex idx = index(r, start.column());
if (!idx.isValid()) {
continue;
}
if (!idx.isValid()) {
continue;
}
QVariant item_value = m_sourceModel->data(mapToSource(idx).row(), MSG_DB_TITLE_INDEX, role);
QVariant item_value = m_sourceModel->data(mapToSource(idx).row(), MSG_DB_TITLE_INDEX, role);
// QVariant based matching.
if (match_type == Qt::MatchExactly) {
if (entered_value == item_value) {
result.append(idx);
}
}
// QString based matching.
else {
if (entered_text.isEmpty()) {
entered_text = entered_value.toString();
}
// QVariant based matching.
if (match_type == Qt::MatchExactly) {
if (entered_value == item_value) {
result.append(idx);
}
}
QString item_text = item_value.toString();
// QString based matching.
else {
if (entered_text.isEmpty()) {
entered_text = entered_value.toString();
}
switch (match_type) {
case Qt::MatchRegExp:
if (QRegExp(entered_text, case_sensitivity).exactMatch(item_text)) {
result.append(idx);
}
break;
QString item_text = item_value.toString();
case Qt::MatchWildcard:
if (QRegExp(entered_text, case_sensitivity, QRegExp::Wildcard).exactMatch(item_text)) {
result.append(idx);
}
break;
switch (match_type) {
case Qt::MatchRegExp:
if (QRegExp(entered_text, case_sensitivity).exactMatch(item_text)) {
result.append(idx);
}
case Qt::MatchStartsWith:
if (item_text.startsWith(entered_text, case_sensitivity)) {
result.append(idx);
}
break;
break;
case Qt::MatchEndsWith:
if (item_text.endsWith(entered_text, case_sensitivity)) {
result.append(idx);
}
break;
case Qt::MatchWildcard:
if (QRegExp(entered_text, case_sensitivity, QRegExp::Wildcard).exactMatch(item_text)) {
result.append(idx);
}
case Qt::MatchFixedString:
if (item_text.compare(entered_text, case_sensitivity) == 0) {
result.append(idx);
}
break;
break;
case Qt::MatchContains:
default:
if (item_text.contains(entered_text, case_sensitivity)) {
result.append(idx);
}
break;
}
}
}
case Qt::MatchStartsWith:
if (item_text.startsWith(entered_text, case_sensitivity)) {
result.append(idx);
}
// Prepare for the next iteration.
from = 0;
to = start.row();
}
break;
return result;
case Qt::MatchEndsWith:
if (item_text.endsWith(entered_text, case_sensitivity)) {
result.append(idx);
}
break;
case Qt::MatchFixedString:
if (item_text.compare(entered_text, case_sensitivity) == 0) {
result.append(idx);
}
break;
case Qt::MatchContains:
default:
if (item_text.contains(entered_text, case_sensitivity)) {
result.append(idx);
}
break;
}
}
}
// Prepare for the next iteration.
from = 0;
to = start.row();
}
return result;
}
void MessagesProxyModel::sort(int column, Qt::SortOrder order) {
// NOTE: Ignore here, sort is done elsewhere (server-side).
Q_UNUSED(column)
Q_UNUSED(order)
// NOTE: Ignore here, sort is done elsewhere (server-side).
Q_UNUSED(column)
Q_UNUSED(order)
}
QModelIndexList MessagesProxyModel::mapListToSource(const QModelIndexList &indexes) const {
QModelIndexList source_indexes;
QModelIndexList MessagesProxyModel::mapListToSource(const QModelIndexList& indexes) const {
QModelIndexList source_indexes;
foreach (const QModelIndex &index, indexes) {
source_indexes << mapToSource(index);
}
foreach (const QModelIndex& index, indexes) {
source_indexes << mapToSource(index);
}
return source_indexes;
return source_indexes;
}

View File

@ -24,33 +24,33 @@
class MessagesModel;
class MessagesProxyModel : public QSortFilterProxyModel {
Q_OBJECT
Q_OBJECT
public:
// Constructors and destructors.
explicit MessagesProxyModel(MessagesModel *source_model, QObject *parent = 0);
virtual ~MessagesProxyModel();
public:
// Constructors and destructors.
explicit MessagesProxyModel(MessagesModel* source_model, QObject* parent = 0);
virtual ~MessagesProxyModel();
QModelIndex getNextPreviousUnreadItemIndex(int default_row);
QModelIndex getNextPreviousUnreadItemIndex(int default_row);
// Maps list of indexes.
QModelIndexList mapListToSource(const QModelIndexList &indexes) const;
QModelIndexList mapListFromSource(const QModelIndexList &indexes, bool deep = false) const;
// Maps list of indexes.
QModelIndexList mapListToSource(const QModelIndexList& indexes) const;
QModelIndexList mapListFromSource(const QModelIndexList& indexes, bool deep = false) const;
// Fix for matching indexes with respect to specifics of the message model.
QModelIndexList match(const QModelIndex &start, int role, const QVariant &entered_value, int hits, Qt::MatchFlags flags) const;
// Fix for matching indexes with respect to specifics of the message model.
QModelIndexList match(const QModelIndex& start, int role, const QVariant& entered_value, int hits, Qt::MatchFlags flags) const;
// Performs sort of items.
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
// Performs sort of items.
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
private:
QModelIndex getNextUnreadItemIndex(int default_row, int max_row) const;
private:
QModelIndex getNextUnreadItemIndex(int default_row, int max_row) const;
// Compares two rows of data.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
// Compares two rows of data.
bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
// Source model pointer.
MessagesModel *m_sourceModel;
// Source model pointer.
MessagesModel* m_sourceModel;
};
#endif // MESSAGESPROXYMODEL_H

View File

@ -1,258 +1,258 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 DEFINITIONS_H
#define DEFINITIONS_H
#include <QtGlobal>
#define SERVICE_CODE_STD_RSS "std-rss"
#define SERVICE_CODE_TT_RSS "tt-rss"
#define SERVICE_CODE_OWNCLOUD "owncloud"
#define ARGUMENTS_LIST_SEPARATOR "\n"
#define ADBLOCK_UPDATE_DAYS_INTERVAL 5
#define ADBLOCK_ICON_ACTIVE "adblock"
#define ADBLOCK_ICON_DISABLED "adblock-disabled"
#define IS_IN_ARRAY(offset, array) ((offset >= 0) && (offset < array.count()))
#define ADBLOCK_CUSTOMLIST_NAME "customlist.txt"
#define ADBLOCK_LISTS_SUBDIRECTORY "adblock"
#define ADBLOCK_EASYLIST_URL "https://easylist-downloads.adblockplus.org/easylist.txt"
#define DEFAULT_SQL_MESSAGES_FILTER "0 > 1"
#define MAX_MULTICOLUMN_SORT_STATES 3
#define ENCLOSURES_OUTER_SEPARATOR '#'
#define ECNLOSURES_INNER_SEPARATOR '&'
#define URI_SCHEME_FEED_SHORT "feed:"
#define URI_SCHEME_FEED "feed://"
#define URI_SCHEME_HTTP "http://"
#define RELEASES_LIST "https://api.github.com/repos/martinrotter/rssguard/releases"
#define DEFAULT_LOCALE "en"
#define DEFAULT_FEED_ENCODING "UTF-8"
#define DEFAULT_FEED_TYPE "RSS"
#define URL_REGEXP "^(http|https|feed|ftp):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&amp;:/~\\+#]*[\\w\\-\\@?^=%&amp;/~\\+#])?$"
#define USER_AGENT_HTTP_HEADER "User-Agent"
#define TEXT_TITLE_LIMIT 30
#define RESELECT_MESSAGE_THRESSHOLD 500
#define ICON_SIZE_SETTINGS 16
#define NO_PARENT_CATEGORY -1
#define ID_RECYCLE_BIN -2
#define TRAY_ICON_BUBBLE_TIMEOUT 20000
#define CLOSE_LOCK_TIMEOUT 500
#define DOWNLOAD_TIMEOUT 5000
#define MESSAGES_VIEW_DEFAULT_COL 170
#define MESSAGES_VIEW_MINIMUM_COL 36
#define FEEDS_VIEW_COLUMN_COUNT 2
#define FEED_DOWNLOADER_MAX_THREADS 6
#define DEFAULT_DAYS_TO_DELETE_MSG 14
#define ELLIPSIS_LENGTH 3
#define MIN_CATEGORY_NAME_LENGTH 1
#define DEFAULT_AUTO_UPDATE_INTERVAL 15
#define AUTO_UPDATE_INTERVAL 60000
#define STARTUP_UPDATE_DELAY 30000
#define TIMEZONE_OFFSET_LIMIT 6
#define CHANGE_EVENT_DELAY 250
#define FLAG_ICON_SUBFOLDER "flags"
#define SEACRH_MESSAGES_ACTION_NAME "search"
#define HIGHLIGHTER_ACTION_NAME "highlighter"
#define SPACER_ACTION_NAME "spacer"
#define SEPARATOR_ACTION_NAME "separator"
#define FILTER_WIDTH 150
#define FILTER_RIGHT_MARGIN 5
#define FEEDS_VIEW_INDENTATION 10
#define ACCEPT_HEADER_FOR_FEED_DOWNLOADER "application/atom+xml,application/xml;q=0.9,text/xml;q=0.8,*/*;q=0.7"
#define MIME_TYPE_ITEM_POINTER "rssguard/itempointer"
#define DOWNLOADER_ICON_SIZE 48
#define NOTIFICATION_ICON_SIZE 32
#define GOOGLE_SEARCH_URL "https://www.google.com/search?q=%1&ie=utf-8&oe=utf-8"
#define GOOGLE_SUGGEST_URL "http://suggestqueries.google.com/complete/search?output=toolbar&hl=en&q=%1"
#define ENCRYPTION_FILE_NAME "key.private"
#define RELOAD_MODEL_BORDER_NUM 10
#define MAX_ZOOM_FACTOR 5.0f
#define MIN_ZOOM_FACTOR 0.25f
#define DEFAULT_ZOOM_FACTOR 1.0f
#define ZOOM_FACTOR_STEP 0.1f
#define INTERNAL_URL_MESSAGE "http://rssguard.message"
#define INTERNAL_URL_BLANK "http://rssguard.blank"
#define INTERNAL_URL_MESSAGE_HOST "rssguard.message"
#define INTERNAL_URL_BLANK_HOST "rssguard.blank"
#define FEED_INITIAL_OPML_PATTERN "feeds-%1.opml"
#define FEED_REGEX_MATCHER "<link[^>]+type=\\\"application/(atom|rss)\\+xml\\\"[^>]*>"
#define FEED_HREF_REGEX_MATCHER "href\\=\\\"[^\\\"]+\\\""
#define PLACEHOLDER_UNREAD_COUNTS "%unread"
#define PLACEHOLDER_ALL_COUNTS "%all"
#define BACKUP_NAME_SETTINGS "config"
#define BACKUP_SUFFIX_SETTINGS ".ini.backup"
#define BACKUP_NAME_DATABASE "database"
#define BACKUP_SUFFIX_DATABASE ".db.backup"
#define APP_DB_MYSQL_DRIVER "QMYSQL"
#define APP_DB_MYSQL_INIT "db_init_mysql.sql"
#define APP_DB_MYSQL_TEST "MySQLTest"
#define APP_DB_MYSQL_PORT 3306
#define APP_DB_SQLITE_DRIVER "QSQLITE"
#define APP_DB_SQLITE_INIT "db_init_sqlite.sql"
#define APP_DB_SQLITE_PATH "database/local"
#define APP_DB_SQLITE_FILE "database.db"
// Keep this in sync with schema versions declared in SQL initialization code.
#define APP_DB_SCHEMA_VERSION "8"
#define APP_DB_UPDATE_FILE_PATTERN "db_update_%1_%2_%3.sql"
#define APP_DB_COMMENT_SPLIT "-- !\n"
#define APP_DB_NAME_PLACEHOLDER "##"
#define APP_CFG_PATH "config"
#define APP_CFG_FILE "config.ini"
#define APP_QUIT_INSTANCE "-q"
#define APP_IS_RUNNING "app_is_running"
#define APP_SKIN_USER_FOLDER "skins"
#define APP_SKIN_DEFAULT "vergilius"
#define APP_SKIN_METADATA_FILE "metadata.xml"
#define APP_STYLE_DEFAULT "Fusion"
#define APP_THEME_DEFAULT "Faenza"
#define APP_NO_THEME ""
#define APP_THEME_SUFFIX ".png"
#ifndef QSL
// Thin macro wrapper for literal strings.
// They are much more memory efficient and faster.
// Use it for all literals except for two cases:
// a) Methods which take QLatin1String (use QLatin1String for literal argument too),
// b) Construction of empty literals "", use QString() instead of QStringLiteral("").
#define QSL(x) QStringLiteral(x)
#endif
#ifndef QL1S
// Macro for latin strings. Latin strings are
// faster than QStrings created from literals.
#define QL1S(x) QLatin1String(x)
#endif
#ifndef QL1C
// Macro for latin chars.
#define QL1C(x) QLatin1Char(x)
#endif
// Indexes of columns as they are DEFINED IN THE TABLE for MESSAGES.
#define MSG_DB_ID_INDEX 0
#define MSG_DB_READ_INDEX 1
#define MSG_DB_DELETED_INDEX 2
#define MSG_DB_IMPORTANT_INDEX 3
#define MSG_DB_FEED_TITLE_INDEX 4
#define MSG_DB_TITLE_INDEX 5
#define MSG_DB_URL_INDEX 6
#define MSG_DB_AUTHOR_INDEX 7
#define MSG_DB_DCREATED_INDEX 8
#define MSG_DB_CONTENTS_INDEX 9
#define MSG_DB_PDELETED_INDEX 10
#define MSG_DB_ENCLOSURES_INDEX 11
#define MSG_DB_ACCOUNT_ID_INDEX 12
#define MSG_DB_CUSTOM_ID_INDEX 13
#define MSG_DB_CUSTOM_HASH_INDEX 14
#define MSG_DB_FEED_CUSTOM_ID_INDEX 15
// Indexes of columns as they are DEFINED IN THE TABLE for CATEGORIES.
#define CAT_DB_ID_INDEX 0
#define CAT_DB_PARENT_ID_INDEX 1
#define CAT_DB_TITLE_INDEX 2
#define CAT_DB_DESCRIPTION_INDEX 3
#define CAT_DB_DCREATED_INDEX 4
#define CAT_DB_ICON_INDEX 5
#define CAT_DB_ACCOUNT_ID_INDEX 6
#define CAT_DB_CUSTOM_ID_INDEX 7
// Indexes of columns as they are DEFINED IN THE TABLE for FEEDS.
#define FDS_DB_ID_INDEX 0
#define FDS_DB_TITLE_INDEX 1
#define FDS_DB_DESCRIPTION_INDEX 2
#define FDS_DB_DCREATED_INDEX 3
#define FDS_DB_ICON_INDEX 4
#define FDS_DB_CATEGORY_INDEX 5
#define FDS_DB_ENCODING_INDEX 6
#define FDS_DB_URL_INDEX 7
#define FDS_DB_PROTECTED_INDEX 8
#define FDS_DB_USERNAME_INDEX 9
#define FDS_DB_PASSWORD_INDEX 10
#define FDS_DB_UPDATE_TYPE_INDEX 11
#define FDS_DB_UPDATE_INTERVAL_INDEX 12
#define FDS_DB_TYPE_INDEX 13
#define FDS_DB_ACCOUNT_ID_INDEX 14
#define FDS_DB_CUSTOM_ID_INDEX 15
// Indexes of columns for feed models.
#define FDS_MODEL_TITLE_INDEX 0
#define FDS_MODEL_COUNTS_INDEX 1
#if defined(Q_OS_LINUX)
#define OS_ID "Linux"
#elif defined(Q_OS_OSX)
#define OS_ID "Mac OS X"
#elif defined(Q_OS_WIN)
#define OS_ID "Windows"
#else
#define OS_ID ""
#endif
#if defined(Q_OS_LINUX)
#define APP_DESKTOP_SOURCE_ENTRY_FILE "rssguard.desktop.autostart"
#define APP_DESKTOP_ENTRY_FILE "rssguard.desktop"
#define APP_DESKTOP_ENTRY_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/autostart")
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/translations")
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/skins")
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/information")
#define APP_THEME_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/icons")
#define APP_SQL_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/sql")
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/../share/pixmaps/rssguard.png")
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/icons/rssguard_plain.png")
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/initial_feeds")
#elif defined(Q_OS_OSX)
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/../Resources/translations")
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/../Resources/skins")
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../Resources/information")
#define APP_THEME_PATH QApplication::applicationDirPath() + QString("/../Resources/icons")
#define APP_SQL_PATH QApplication::applicationDirPath() + QString("/../Resources/sql")
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/../Resources/icons/rssguard.png")
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../Resources/information")
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/../Resources/icons/rssguard_plain.png")
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/../Resources/initial_feeds")
#elif defined(Q_OS_WIN)
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/translations")
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins")
#define APP_INFO_PATH QApplication::applicationDirPath()
#define APP_THEME_PATH QApplication::applicationDirPath() + QString("/icons")
#define APP_SQL_PATH QApplication::applicationDirPath() + QString("/sql")
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/rssguard.png")
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/rssguard_plain.png")
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/initial_feeds")
#endif
#endif // DEFINITIONS_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 DEFINITIONS_H
#define DEFINITIONS_H
#include <QtGlobal>
#define SERVICE_CODE_STD_RSS "std-rss"
#define SERVICE_CODE_TT_RSS "tt-rss"
#define SERVICE_CODE_OWNCLOUD "owncloud"
#define ARGUMENTS_LIST_SEPARATOR "\n"
#define ADBLOCK_UPDATE_DAYS_INTERVAL 5
#define ADBLOCK_ICON_ACTIVE "adblock"
#define ADBLOCK_ICON_DISABLED "adblock-disabled"
#define IS_IN_ARRAY(offset, array) ((offset >= 0) && (offset < array.count()))
#define ADBLOCK_CUSTOMLIST_NAME "customlist.txt"
#define ADBLOCK_LISTS_SUBDIRECTORY "adblock"
#define ADBLOCK_EASYLIST_URL "https://easylist-downloads.adblockplus.org/easylist.txt"
#define DEFAULT_SQL_MESSAGES_FILTER "0 > 1"
#define MAX_MULTICOLUMN_SORT_STATES 3
#define ENCLOSURES_OUTER_SEPARATOR '#'
#define ECNLOSURES_INNER_SEPARATOR '&'
#define URI_SCHEME_FEED_SHORT "feed:"
#define URI_SCHEME_FEED "feed://"
#define URI_SCHEME_HTTP "http://"
#define RELEASES_LIST "https://api.github.com/repos/martinrotter/rssguard/releases"
#define DEFAULT_LOCALE "en"
#define DEFAULT_FEED_ENCODING "UTF-8"
#define DEFAULT_FEED_TYPE "RSS"
#define URL_REGEXP "^(http|https|feed|ftp):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&amp;:/~\\+#]*[\\w\\-\\@?^=%&amp;/~\\+#])?$"
#define USER_AGENT_HTTP_HEADER "User-Agent"
#define TEXT_TITLE_LIMIT 30
#define RESELECT_MESSAGE_THRESSHOLD 500
#define ICON_SIZE_SETTINGS 16
#define NO_PARENT_CATEGORY -1
#define ID_RECYCLE_BIN -2
#define TRAY_ICON_BUBBLE_TIMEOUT 20000
#define CLOSE_LOCK_TIMEOUT 500
#define DOWNLOAD_TIMEOUT 5000
#define MESSAGES_VIEW_DEFAULT_COL 170
#define MESSAGES_VIEW_MINIMUM_COL 36
#define FEEDS_VIEW_COLUMN_COUNT 2
#define FEED_DOWNLOADER_MAX_THREADS 6
#define DEFAULT_DAYS_TO_DELETE_MSG 14
#define ELLIPSIS_LENGTH 3
#define MIN_CATEGORY_NAME_LENGTH 1
#define DEFAULT_AUTO_UPDATE_INTERVAL 15
#define AUTO_UPDATE_INTERVAL 60000
#define STARTUP_UPDATE_DELAY 30000
#define TIMEZONE_OFFSET_LIMIT 6
#define CHANGE_EVENT_DELAY 250
#define FLAG_ICON_SUBFOLDER "flags"
#define SEACRH_MESSAGES_ACTION_NAME "search"
#define HIGHLIGHTER_ACTION_NAME "highlighter"
#define SPACER_ACTION_NAME "spacer"
#define SEPARATOR_ACTION_NAME "separator"
#define FILTER_WIDTH 150
#define FILTER_RIGHT_MARGIN 5
#define FEEDS_VIEW_INDENTATION 10
#define ACCEPT_HEADER_FOR_FEED_DOWNLOADER "application/atom+xml,application/xml;q=0.9,text/xml;q=0.8,*/*;q=0.7"
#define MIME_TYPE_ITEM_POINTER "rssguard/itempointer"
#define DOWNLOADER_ICON_SIZE 48
#define NOTIFICATION_ICON_SIZE 32
#define GOOGLE_SEARCH_URL "https://www.google.com/search?q=%1&ie=utf-8&oe=utf-8"
#define GOOGLE_SUGGEST_URL "http://suggestqueries.google.com/complete/search?output=toolbar&hl=en&q=%1"
#define ENCRYPTION_FILE_NAME "key.private"
#define RELOAD_MODEL_BORDER_NUM 10
#define MAX_ZOOM_FACTOR 5.0f
#define MIN_ZOOM_FACTOR 0.25f
#define DEFAULT_ZOOM_FACTOR 1.0f
#define ZOOM_FACTOR_STEP 0.1f
#define INTERNAL_URL_MESSAGE "http://rssguard.message"
#define INTERNAL_URL_BLANK "http://rssguard.blank"
#define INTERNAL_URL_MESSAGE_HOST "rssguard.message"
#define INTERNAL_URL_BLANK_HOST "rssguard.blank"
#define FEED_INITIAL_OPML_PATTERN "feeds-%1.opml"
#define FEED_REGEX_MATCHER "<link[^>]+type=\\\"application/(atom|rss)\\+xml\\\"[^>]*>"
#define FEED_HREF_REGEX_MATCHER "href\\=\\\"[^\\\"]+\\\""
#define PLACEHOLDER_UNREAD_COUNTS "%unread"
#define PLACEHOLDER_ALL_COUNTS "%all"
#define BACKUP_NAME_SETTINGS "config"
#define BACKUP_SUFFIX_SETTINGS ".ini.backup"
#define BACKUP_NAME_DATABASE "database"
#define BACKUP_SUFFIX_DATABASE ".db.backup"
#define APP_DB_MYSQL_DRIVER "QMYSQL"
#define APP_DB_MYSQL_INIT "db_init_mysql.sql"
#define APP_DB_MYSQL_TEST "MySQLTest"
#define APP_DB_MYSQL_PORT 3306
#define APP_DB_SQLITE_DRIVER "QSQLITE"
#define APP_DB_SQLITE_INIT "db_init_sqlite.sql"
#define APP_DB_SQLITE_PATH "database/local"
#define APP_DB_SQLITE_FILE "database.db"
// Keep this in sync with schema versions declared in SQL initialization code.
#define APP_DB_SCHEMA_VERSION "8"
#define APP_DB_UPDATE_FILE_PATTERN "db_update_%1_%2_%3.sql"
#define APP_DB_COMMENT_SPLIT "-- !\n"
#define APP_DB_NAME_PLACEHOLDER "##"
#define APP_CFG_PATH "config"
#define APP_CFG_FILE "config.ini"
#define APP_QUIT_INSTANCE "-q"
#define APP_IS_RUNNING "app_is_running"
#define APP_SKIN_USER_FOLDER "skins"
#define APP_SKIN_DEFAULT "vergilius"
#define APP_SKIN_METADATA_FILE "metadata.xml"
#define APP_STYLE_DEFAULT "Fusion"
#define APP_THEME_DEFAULT "Faenza"
#define APP_NO_THEME ""
#define APP_THEME_SUFFIX ".png"
#ifndef QSL
// Thin macro wrapper for literal strings.
// They are much more memory efficient and faster.
// Use it for all literals except for two cases:
// a) Methods which take QLatin1String (use QLatin1String for literal argument too),
// b) Construction of empty literals "", use QString() instead of QStringLiteral("").
#define QSL(x) QStringLiteral(x)
#endif
#ifndef QL1S
// Macro for latin strings. Latin strings are
// faster than QStrings created from literals.
#define QL1S(x) QLatin1String(x)
#endif
#ifndef QL1C
// Macro for latin chars.
#define QL1C(x) QLatin1Char(x)
#endif
// Indexes of columns as they are DEFINED IN THE TABLE for MESSAGES.
#define MSG_DB_ID_INDEX 0
#define MSG_DB_READ_INDEX 1
#define MSG_DB_DELETED_INDEX 2
#define MSG_DB_IMPORTANT_INDEX 3
#define MSG_DB_FEED_TITLE_INDEX 4
#define MSG_DB_TITLE_INDEX 5
#define MSG_DB_URL_INDEX 6
#define MSG_DB_AUTHOR_INDEX 7
#define MSG_DB_DCREATED_INDEX 8
#define MSG_DB_CONTENTS_INDEX 9
#define MSG_DB_PDELETED_INDEX 10
#define MSG_DB_ENCLOSURES_INDEX 11
#define MSG_DB_ACCOUNT_ID_INDEX 12
#define MSG_DB_CUSTOM_ID_INDEX 13
#define MSG_DB_CUSTOM_HASH_INDEX 14
#define MSG_DB_FEED_CUSTOM_ID_INDEX 15
// Indexes of columns as they are DEFINED IN THE TABLE for CATEGORIES.
#define CAT_DB_ID_INDEX 0
#define CAT_DB_PARENT_ID_INDEX 1
#define CAT_DB_TITLE_INDEX 2
#define CAT_DB_DESCRIPTION_INDEX 3
#define CAT_DB_DCREATED_INDEX 4
#define CAT_DB_ICON_INDEX 5
#define CAT_DB_ACCOUNT_ID_INDEX 6
#define CAT_DB_CUSTOM_ID_INDEX 7
// Indexes of columns as they are DEFINED IN THE TABLE for FEEDS.
#define FDS_DB_ID_INDEX 0
#define FDS_DB_TITLE_INDEX 1
#define FDS_DB_DESCRIPTION_INDEX 2
#define FDS_DB_DCREATED_INDEX 3
#define FDS_DB_ICON_INDEX 4
#define FDS_DB_CATEGORY_INDEX 5
#define FDS_DB_ENCODING_INDEX 6
#define FDS_DB_URL_INDEX 7
#define FDS_DB_PROTECTED_INDEX 8
#define FDS_DB_USERNAME_INDEX 9
#define FDS_DB_PASSWORD_INDEX 10
#define FDS_DB_UPDATE_TYPE_INDEX 11
#define FDS_DB_UPDATE_INTERVAL_INDEX 12
#define FDS_DB_TYPE_INDEX 13
#define FDS_DB_ACCOUNT_ID_INDEX 14
#define FDS_DB_CUSTOM_ID_INDEX 15
// Indexes of columns for feed models.
#define FDS_MODEL_TITLE_INDEX 0
#define FDS_MODEL_COUNTS_INDEX 1
#if defined(Q_OS_LINUX)
#define OS_ID "Linux"
#elif defined(Q_OS_OSX)
#define OS_ID "Mac OS X"
#elif defined(Q_OS_WIN)
#define OS_ID "Windows"
#else
#define OS_ID ""
#endif
#if defined(Q_OS_LINUX)
#define APP_DESKTOP_SOURCE_ENTRY_FILE "rssguard.desktop.autostart"
#define APP_DESKTOP_ENTRY_FILE "rssguard.desktop"
#define APP_DESKTOP_ENTRY_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/autostart")
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/translations")
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/skins")
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/information")
#define APP_THEME_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/icons")
#define APP_SQL_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/sql")
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/../share/pixmaps/rssguard.png")
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/icons/rssguard_plain.png")
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/initial_feeds")
#elif defined(Q_OS_OSX)
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/../Resources/translations")
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/../Resources/skins")
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../Resources/information")
#define APP_THEME_PATH QApplication::applicationDirPath() + QString("/../Resources/icons")
#define APP_SQL_PATH QApplication::applicationDirPath() + QString("/../Resources/sql")
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/../Resources/icons/rssguard.png")
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../Resources/information")
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/../Resources/icons/rssguard_plain.png")
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/../Resources/initial_feeds")
#elif defined(Q_OS_WIN)
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/translations")
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins")
#define APP_INFO_PATH QApplication::applicationDirPath()
#define APP_THEME_PATH QApplication::applicationDirPath() + QString("/icons")
#define APP_SQL_PATH QApplication::applicationDirPath() + QString("/sql")
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/rssguard.png")
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/rssguard_plain.png")
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/initial_feeds")
#endif
#endif // DEFINITIONS_H

View File

@ -27,21 +27,21 @@
DynamicShortcuts::DynamicShortcuts() {
}
void DynamicShortcuts::save(const QList<QAction*> &actions) {
Settings *settings = qApp->settings();
void DynamicShortcuts::save(const QList<QAction*>& actions) {
Settings* settings = qApp->settings();
foreach (const QAction *action, actions) {
settings->setValue(GROUP(Keyboard), action->objectName(), action->shortcut().toString(QKeySequence::PortableText));
}
foreach (const QAction* action, actions) {
settings->setValue(GROUP(Keyboard), action->objectName(), action->shortcut().toString(QKeySequence::PortableText));
}
}
void DynamicShortcuts::load(const QList<QAction *> &actions) {
Settings *settings = qApp->settings();
void DynamicShortcuts::load(const QList<QAction*>& actions) {
Settings* settings = qApp->settings();
foreach (QAction *action, actions) {
QString shortcut_for_action = settings->value(GROUP(Keyboard),
action->objectName(),
action->shortcut().toString(QKeySequence::PortableText)).toString();
action->setShortcut(QKeySequence::fromString(shortcut_for_action, QKeySequence::PortableText));
}
foreach (QAction* action, actions) {
QString shortcut_for_action = settings->value(GROUP(Keyboard),
action->objectName(),
action->shortcut().toString(QKeySequence::PortableText)).toString();
action->setShortcut(QKeySequence::fromString(shortcut_for_action, QKeySequence::PortableText));
}
}

View File

@ -24,18 +24,18 @@
class QAction;
class DynamicShortcuts {
public:
// Checks the application settings and then initializes shortcut of
// each action from actions from the settings.
static void load(const QList<QAction*> &actions);
public:
// Checks the application settings and then initializes shortcut of
// each action from actions from the settings.
static void load(const QList<QAction*>& actions);
// Stores shortcut of each action from actions into the application
// settings.
static void save(const QList<QAction*> &actions);
// Stores shortcut of each action from actions into the application
// settings.
static void save(const QList<QAction*>& actions);
private:
// Constructor.
explicit DynamicShortcuts();
private:
// Constructor.
explicit DynamicShortcuts();
};
#endif // DYNAMICSHORTCUTS_H

View File

@ -26,93 +26,85 @@
#include <QLabel>
DynamicShortcutsWidget::DynamicShortcutsWidget(QWidget *parent) : QWidget(parent) {
// Create layout for this control and set is as active.
m_layout = new QGridLayout(this);
m_layout->setMargin(0);
setLayout(m_layout);
DynamicShortcutsWidget::DynamicShortcutsWidget(QWidget* parent) : QWidget(parent) {
// Create layout for this control and set is as active.
m_layout = new QGridLayout(this);
m_layout->setMargin(0);
setLayout(m_layout);
}
DynamicShortcutsWidget::~DynamicShortcutsWidget() {
delete m_layout;
delete m_layout;
}
bool DynamicShortcutsWidget::areShortcutsUnique() const {
QList<QKeySequence> all_shortcuts;
QList<QKeySequence> all_shortcuts;
// Obtain all shortcuts.
foreach (const ActionBinding &binding, m_actionBindings) {
const QKeySequence new_shortcut = binding.second->shortcut();
// Obtain all shortcuts.
foreach (const ActionBinding& binding, m_actionBindings) {
const QKeySequence new_shortcut = binding.second->shortcut();
if (!new_shortcut.isEmpty() && all_shortcuts.contains(new_shortcut)) {
// Problem, two identical non-empty shortcuts found.
return false;
}
else {
all_shortcuts.append(binding.second->shortcut());
}
}
if (!new_shortcut.isEmpty() && all_shortcuts.contains(new_shortcut)) {
// Problem, two identical non-empty shortcuts found.
return false;
}
return true;
else {
all_shortcuts.append(binding.second->shortcut());
}
}
return true;
}
void DynamicShortcutsWidget::updateShortcuts() {
foreach (const ActionBinding &binding, m_actionBindings) {
binding.first->setShortcut(binding.second->shortcut());
}
foreach (const ActionBinding& binding, m_actionBindings) {
binding.first->setShortcut(binding.second->shortcut());
}
}
void DynamicShortcutsWidget::populate(QList<QAction*> actions) {
m_actionBindings.clear();
qSort(actions.begin(), actions.end(), DynamicShortcutsWidget::lessThan);
m_actionBindings.clear();
qSort(actions.begin(), actions.end(), DynamicShortcutsWidget::lessThan);
int row_id = 0;
int row_id = 0;
// FIXME: Maybe separate actions into "categories". Each category will start with label.
// I will assign each QAaction a property called "category" with some enum value.
// Like:
// File, FeedsCategories, Messages, Tools, WebBrowser, Help
// This will be setup in FormMain::allActions().
// Then here I will process actions into categories.
// FIXME: Maybe separate actions into "categories". Each category will start with label.
// I will assign each QAaction a property called "category" with some enum value.
// Like:
// File, FeedsCategories, Messages, Tools, WebBrowser, Help
// This will be setup in FormMain::allActions().
// Then here I will process actions into categories.
foreach (QAction* action, actions) {
// Create shortcut catcher for this action and set default shortcut.
ShortcutCatcher* catcher = new ShortcutCatcher(this);
catcher->setDefaultShortcut(action->shortcut());
// Store information for re-initialization of shortcuts
// of actions when widget gets "confirmed".
QPair<QAction*, ShortcutCatcher*> new_binding;
new_binding.first = action;
new_binding.second = catcher;
m_actionBindings << new_binding;
// Add new catcher to our control.
QLabel* action_label = new QLabel(this);
action_label->setText(action->text().remove(QSL("&")));
action_label->setToolTip(action->toolTip());
action_label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
QLabel* action_icon = new QLabel(this);
action_icon->setPixmap(action->icon().pixmap(ICON_SIZE_SETTINGS, ICON_SIZE_SETTINGS));
action_icon->setToolTip(action->toolTip());
m_layout->addWidget(action_icon, row_id, 0);
m_layout->addWidget(action_label, row_id, 1);
m_layout->addWidget(catcher, row_id, 2);
row_id++;
connect(catcher, &ShortcutCatcher::shortcutChanged, this, &DynamicShortcutsWidget::setupChanged);
}
foreach (QAction *action, actions) {
// Create shortcut catcher for this action and set default shortcut.
ShortcutCatcher *catcher = new ShortcutCatcher(this);
catcher->setDefaultShortcut(action->shortcut());
// Store information for re-initialization of shortcuts
// of actions when widget gets "confirmed".
QPair<QAction*,ShortcutCatcher*> new_binding;
new_binding.first = action;
new_binding.second = catcher;
m_actionBindings << new_binding;
// Add new catcher to our control.
QLabel *action_label = new QLabel(this);
action_label->setText(action->text().remove(QSL("&")));
action_label->setToolTip(action->toolTip());
action_label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
QLabel *action_icon = new QLabel(this);
action_icon->setPixmap(action->icon().pixmap(ICON_SIZE_SETTINGS, ICON_SIZE_SETTINGS));
action_icon->setToolTip(action->toolTip());
m_layout->addWidget(action_icon, row_id, 0);
m_layout->addWidget(action_label, row_id, 1);
m_layout->addWidget(catcher, row_id, 2);
row_id++;
connect(catcher, &ShortcutCatcher::shortcutChanged, this, &DynamicShortcutsWidget::setupChanged);
}
// Make sure that "spacer" is added.
m_layout->setRowStretch(row_id, 1);
m_layout->setColumnStretch(1, 1);
// Make sure that "spacer" is added.
m_layout->setRowStretch(row_id, 1);
m_layout->setColumnStretch(1, 1);
}
bool DynamicShortcutsWidget::lessThan(QAction *lhs, QAction *rhs) {
return QString::localeAwareCompare(lhs->text().replace(QL1S("&"), QString()), rhs->text().replace(QL1S("&"), QString())) < 0;
bool DynamicShortcutsWidget::lessThan(QAction* lhs, QAction* rhs) {
return QString::localeAwareCompare(lhs->text().replace(QL1S("&"), QString()), rhs->text().replace(QL1S("&"), QString())) < 0;
}

View File

@ -27,38 +27,38 @@ class ShortcutCatcher;
typedef QPair<QAction*, ShortcutCatcher*> ActionBinding;
class DynamicShortcutsWidget : public QWidget {
Q_OBJECT
public:
// Constructors and destructors.
explicit DynamicShortcutsWidget(QWidget *parent = 0);
virtual ~DynamicShortcutsWidget();
Q_OBJECT
// Updates shortcuts of all actions according to changes.
// NOTE: No access to settings is done here.
// Shortcuts are fetched from settings when applications starts
// and stored back to settings when application quits.
void updateShortcuts();
public:
// Constructors and destructors.
explicit DynamicShortcutsWidget(QWidget* parent = 0);
virtual ~DynamicShortcutsWidget();
// Returns true if all shortcuts are unique,
// otherwise false.
bool areShortcutsUnique() const;
// Updates shortcuts of all actions according to changes.
// NOTE: No access to settings is done here.
// Shortcuts are fetched from settings when applications starts
// and stored back to settings when application quits.
void updateShortcuts();
// Populates this widget with shortcut widgets for given actions.
// NOTE: This gets initial shortcut for each action from its properties, NOT from
// the application settings, so shortcuts from settings need to be
// assigned to actions before calling this method.
void populate(QList<QAction*> actions);
// Returns true if all shortcuts are unique,
// otherwise false.
bool areShortcutsUnique() const;
signals:
void setupChanged();
// Populates this widget with shortcut widgets for given actions.
// NOTE: This gets initial shortcut for each action from its properties, NOT from
// the application settings, so shortcuts from settings need to be
// assigned to actions before calling this method.
void populate(QList<QAction*> actions);
private:
static bool lessThan(QAction *lhs, QAction *rhs);
signals:
void setupChanged();
private:
QGridLayout *m_layout;
QList<ActionBinding> m_actionBindings;
private:
static bool lessThan(QAction* lhs, QAction* rhs);
private:
QGridLayout* m_layout;
QList<ActionBinding> m_actionBindings;
};
#endif // DYNAMICSHORTCUTSOVERVIEW_H

View File

@ -50,93 +50,94 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QKeyEvent>
ShortcutButton::ShortcutButton(ShortcutCatcher *catcher, QWidget *parent)
: QPushButton(parent), m_catcher(catcher) {
setMinimumWidth(100);
ShortcutButton::ShortcutButton(ShortcutCatcher* catcher, QWidget* parent)
: QPushButton(parent), m_catcher(catcher) {
setMinimumWidth(100);
}
ShortcutButton::~ShortcutButton() {
}
void ShortcutButton::keyPressEvent(QKeyEvent *event) {
int pressed_key = event->key();
void ShortcutButton::keyPressEvent(QKeyEvent* event) {
int pressed_key = event->key();
if (pressed_key == -1) {
m_catcher->doneRecording();
}
if (pressed_key == -1) {
m_catcher->doneRecording();
}
const Qt::KeyboardModifiers new_modifiers = event->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
const Qt::KeyboardModifiers new_modifiers = event->modifiers() & (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
if (!m_catcher->m_isRecording && (pressed_key == Qt::Key_Return || pressed_key == Qt::Key_Space)) {
return;
}
if (!m_catcher->m_isRecording && (pressed_key == Qt::Key_Return || pressed_key == Qt::Key_Space)) {
return;
}
if (!m_catcher->m_isRecording) {
QPushButton::keyPressEvent(event);
return;
}
if (!m_catcher->m_isRecording) {
QPushButton::keyPressEvent(event);
return;
}
event->accept();
m_catcher->m_modifierKeys = new_modifiers;
event->accept();
m_catcher->m_modifierKeys = new_modifiers;
switch(pressed_key) {
case Qt::Key_AltGr:
return;
switch (pressed_key) {
case Qt::Key_AltGr:
return;
case Qt::Key_Shift:
case Qt::Key_Control:
case Qt::Key_Alt:
case Qt::Key_Meta:
case Qt::Key_Menu:
m_catcher->controlModifierlessTimout();
m_catcher->updateDisplayShortcut();
break;
case Qt::Key_Shift:
case Qt::Key_Control:
case Qt::Key_Alt:
case Qt::Key_Meta:
case Qt::Key_Menu:
m_catcher->controlModifierlessTimout();
m_catcher->updateDisplayShortcut();
break;
default:
// We now have a valid key press.
if (pressed_key) {
if ((pressed_key == Qt::Key_Backtab) && (m_catcher->m_modifierKeys & Qt::SHIFT)) {
pressed_key = Qt::Key_Tab | m_catcher->m_modifierKeys;
}
else {
pressed_key |= m_catcher->m_modifierKeys;
}
default:
if (m_catcher->m_numKey == 0) {
m_catcher->m_currentSequence = QKeySequence(pressed_key);
}
// We now have a valid key press.
if (pressed_key) {
if ((pressed_key == Qt::Key_Backtab) && (m_catcher->m_modifierKeys & Qt::SHIFT)) {
pressed_key = Qt::Key_Tab | m_catcher->m_modifierKeys;
}
m_catcher->m_numKey++;
else {
pressed_key |= m_catcher->m_modifierKeys;
}
if (m_catcher->m_numKey >= 4) {
m_catcher->doneRecording();
return;
}
if (m_catcher->m_numKey == 0) {
m_catcher->m_currentSequence = QKeySequence(pressed_key);
}
m_catcher->controlModifierlessTimout();
m_catcher->updateDisplayShortcut();
}
}
m_catcher->m_numKey++;
if (m_catcher->m_numKey >= 4) {
m_catcher->doneRecording();
return;
}
m_catcher->controlModifierlessTimout();
m_catcher->updateDisplayShortcut();
}
}
}
void ShortcutButton::keyReleaseEvent(QKeyEvent *event) {
if (event->key() == -1){
return;
}
void ShortcutButton::keyReleaseEvent(QKeyEvent* event) {
if (event->key() == -1) {
return;
}
if (!m_catcher->m_isRecording) {
QPushButton::keyReleaseEvent(event);
return;
}
if (!m_catcher->m_isRecording) {
QPushButton::keyReleaseEvent(event);
return;
}
event->accept();
event->accept();
const Qt::KeyboardModifiers new_modifiers = event->modifiers() &
(Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
const Qt::KeyboardModifiers new_modifiers = event->modifiers() &
(Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);
if (((uint) new_modifiers & m_catcher->m_modifierKeys) < m_catcher->m_modifierKeys) {
m_catcher->m_modifierKeys = new_modifiers;
m_catcher->controlModifierlessTimout();
m_catcher->updateDisplayShortcut();
}
if (((uint) new_modifiers & m_catcher->m_modifierKeys) < m_catcher->m_modifierKeys) {
m_catcher->m_modifierKeys = new_modifiers;
m_catcher->controlModifierlessTimout();
m_catcher->updateDisplayShortcut();
}
}

View File

@ -52,19 +52,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class ShortcutCatcher;
class ShortcutButton : public QPushButton {
Q_OBJECT
Q_OBJECT
public:
// Constructors and destructors.
explicit ShortcutButton(ShortcutCatcher *catcher, QWidget *parent = 0);
virtual ~ShortcutButton();
public:
// Constructors and destructors.
explicit ShortcutButton(ShortcutCatcher* catcher, QWidget* parent = 0);
virtual ~ShortcutButton();
protected:
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
protected:
void keyPressEvent(QKeyEvent* event);
void keyReleaseEvent(QKeyEvent* event);
private:
ShortcutCatcher *m_catcher;
private:
ShortcutCatcher* m_catcher;
};
#endif // SHORTCUTBUTTON_H

View File

@ -52,123 +52,118 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QHBoxLayout>
ShortcutCatcher::ShortcutCatcher(QWidget *parent)
: QWidget(parent) {
// Setup layout of the control
m_layout = new QHBoxLayout(this);
m_layout->setMargin(0);
m_layout->setSpacing(1);
// Create reset button.
m_btnReset = new PlainToolButton(this);
m_btnReset->setIcon(qApp->icons()->fromTheme(QSL("document-revert")));
m_btnReset->setFocusPolicy(Qt::NoFocus);
m_btnReset->setToolTip(tr("Reset to original shortcut."));
// Create clear button.
m_btnClear = new PlainToolButton(this);
m_btnClear->setIcon(qApp->icons()->fromTheme(QSL("list-remove")));
m_btnClear->setFocusPolicy(Qt::NoFocus);
m_btnClear->setToolTip(tr("Clear current shortcut."));
// Clear main shortcut catching button.
m_btnChange = new ShortcutButton(this);
m_btnChange->setFocusPolicy(Qt::StrongFocus);
m_btnChange->setToolTip(tr("Click and hit new shortcut."));
// Add both buttons to the layout.
m_layout->addWidget(m_btnChange);
m_layout->addWidget(m_btnReset);
m_layout->addWidget(m_btnClear);
// Establish needed connections.
connect(m_btnReset, &QToolButton::clicked, this, &ShortcutCatcher::resetShortcut);
connect(m_btnClear, &QToolButton::clicked, this, &ShortcutCatcher::clearShortcut);
connect(m_btnChange, &QToolButton::clicked, this, &ShortcutCatcher::startRecording);
// Prepare initial state of the control.
updateDisplayShortcut();
ShortcutCatcher::ShortcutCatcher(QWidget* parent)
: QWidget(parent) {
// Setup layout of the control
m_layout = new QHBoxLayout(this);
m_layout->setMargin(0);
m_layout->setSpacing(1);
// Create reset button.
m_btnReset = new PlainToolButton(this);
m_btnReset->setIcon(qApp->icons()->fromTheme(QSL("document-revert")));
m_btnReset->setFocusPolicy(Qt::NoFocus);
m_btnReset->setToolTip(tr("Reset to original shortcut."));
// Create clear button.
m_btnClear = new PlainToolButton(this);
m_btnClear->setIcon(qApp->icons()->fromTheme(QSL("list-remove")));
m_btnClear->setFocusPolicy(Qt::NoFocus);
m_btnClear->setToolTip(tr("Clear current shortcut."));
// Clear main shortcut catching button.
m_btnChange = new ShortcutButton(this);
m_btnChange->setFocusPolicy(Qt::StrongFocus);
m_btnChange->setToolTip(tr("Click and hit new shortcut."));
// Add both buttons to the layout.
m_layout->addWidget(m_btnChange);
m_layout->addWidget(m_btnReset);
m_layout->addWidget(m_btnClear);
// Establish needed connections.
connect(m_btnReset, &QToolButton::clicked, this, &ShortcutCatcher::resetShortcut);
connect(m_btnClear, &QToolButton::clicked, this, &ShortcutCatcher::clearShortcut);
connect(m_btnChange, &QToolButton::clicked, this, &ShortcutCatcher::startRecording);
// Prepare initial state of the control.
updateDisplayShortcut();
}
ShortcutCatcher::~ShortcutCatcher() {
delete m_btnReset;
delete m_btnChange;
delete m_btnClear;
delete m_layout;
delete m_btnReset;
delete m_btnChange;
delete m_btnClear;
delete m_layout;
}
void ShortcutCatcher::startRecording() {
m_numKey = 0;
m_modifierKeys = 0;
m_currentSequence = QKeySequence();
m_isRecording = true;
m_btnChange->setDown(true);
m_btnChange->grabKeyboard();
updateDisplayShortcut();
m_numKey = 0;
m_modifierKeys = 0;
m_currentSequence = QKeySequence();
m_isRecording = true;
m_btnChange->setDown(true);
m_btnChange->grabKeyboard();
updateDisplayShortcut();
}
void ShortcutCatcher::doneRecording() {
m_isRecording = false;
m_btnChange->releaseKeyboard();
m_btnChange->setDown(false);
updateDisplayShortcut();
emit shortcutChanged(m_currentSequence);
m_isRecording = false;
m_btnChange->releaseKeyboard();
m_btnChange->setDown(false);
updateDisplayShortcut();
emit shortcutChanged(m_currentSequence);
}
void ShortcutCatcher::controlModifierlessTimout() {
if (m_numKey && !m_modifierKeys) {
doneRecording();
}
if (m_numKey && !m_modifierKeys) {
doneRecording();
}
}
void ShortcutCatcher::updateDisplayShortcut() {
QString str = m_currentSequence.toString(QKeySequence::NativeText);
str.replace(QL1S("&"), QL1S("&&"));
QString str = m_currentSequence.toString(QKeySequence::NativeText);
str.replace(QL1S("&"), QL1S("&&"));
if (m_isRecording) {
if (m_modifierKeys) {
if (!str.isEmpty()) {
str.append(QSL(","));
}
if (m_modifierKeys & Qt::META) {
str += QL1S("Meta + ");
}
if (m_modifierKeys & Qt::CTRL) {
str += QL1S("Ctrl + ");
}
if (m_modifierKeys & Qt::ALT) {
str += QL1S("Alt + ");
}
if (m_modifierKeys & Qt::SHIFT) {
str += QL1S("Shift + ");
}
}
}
if (m_isRecording) {
if (m_modifierKeys) {
if (!str.isEmpty()) {
str.append(QSL(","));
}
m_btnChange->setText(str);
if (m_modifierKeys & Qt::META) {
str += QL1S("Meta + ");
}
if (m_modifierKeys & Qt::CTRL) {
str += QL1S("Ctrl + ");
}
if (m_modifierKeys & Qt::ALT) {
str += QL1S("Alt + ");
}
if (m_modifierKeys & Qt::SHIFT) {
str += QL1S("Shift + ");
}
}
}
m_btnChange->setText(str);
}
QKeySequence ShortcutCatcher::shortcut() const {
return m_currentSequence;
return m_currentSequence;
}
void ShortcutCatcher::setDefaultShortcut(const QKeySequence &key) {
m_defaultSequence = key;
setShortcut(key);
void ShortcutCatcher::setDefaultShortcut(const QKeySequence& key) {
m_defaultSequence = key;
setShortcut(key);
}
void ShortcutCatcher::setShortcut(const QKeySequence &key) {
m_currentSequence = key;
doneRecording();
void ShortcutCatcher::setShortcut(const QKeySequence& key) {
m_currentSequence = key;
doneRecording();
}
void ShortcutCatcher::resetShortcut() {
setShortcut(m_defaultSequence);
setShortcut(m_defaultSequence);
}
void ShortcutCatcher::clearShortcut() {
setShortcut(QKeySequence());
setShortcut(QKeySequence());
}

View File

@ -54,45 +54,45 @@ class QToolButton;
class ShortcutButton;
class ShortcutCatcher : public QWidget {
Q_OBJECT
Q_OBJECT
friend class ShortcutButton;
friend class ShortcutButton;
public:
// Constructors and destructors.
explicit ShortcutCatcher(QWidget *parent = 0);
virtual ~ShortcutCatcher();
public:
// Constructors and destructors.
explicit ShortcutCatcher(QWidget* parent = 0);
virtual ~ShortcutCatcher();
void controlModifierlessTimout();
void updateDisplayShortcut();
void controlModifierlessTimout();
void updateDisplayShortcut();
QKeySequence shortcut() const;
void setDefaultShortcut(const QKeySequence &key);
void setShortcut(const QKeySequence &key);
QKeySequence shortcut() const;
void setDefaultShortcut(const QKeySequence& key);
void setShortcut(const QKeySequence& key);
public slots:
void resetShortcut();
void clearShortcut();
public slots:
void resetShortcut();
void clearShortcut();
private slots:
void startRecording();
void doneRecording();
private slots:
void startRecording();
void doneRecording();
signals:
void shortcutChanged(const QKeySequence &seguence);
signals:
void shortcutChanged(const QKeySequence& seguence);
private:
QToolButton *m_btnReset;
QToolButton *m_btnClear;
ShortcutButton *m_btnChange;
QHBoxLayout *m_layout;
private:
QToolButton* m_btnReset;
QToolButton* m_btnClear;
ShortcutButton* m_btnChange;
QHBoxLayout* m_layout;
QKeySequence m_currentSequence;
QKeySequence m_defaultSequence;
QKeySequence m_currentSequence;
QKeySequence m_defaultSequence;
bool m_isRecording;
int m_numKey;
uint m_modifierKeys;
bool m_isRecording;
int m_numKey;
uint m_modifierKeys;
};
#endif // KEYSEQUENCECATCHER_H

View File

@ -1,29 +1,29 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "exceptions/applicationexception.h"
ApplicationException::ApplicationException(const QString &message) : m_message(message) {
}
ApplicationException::~ApplicationException() {
}
QString ApplicationException::message() const {
return m_message;
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "exceptions/applicationexception.h"
ApplicationException::ApplicationException(const QString& message) : m_message(message) {
}
ApplicationException::~ApplicationException() {
}
QString ApplicationException::message() const {
return m_message;
}

View File

@ -1,35 +1,35 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 APPLICATIONEXCEPTION_H
#define APPLICATIONEXCEPTION_H
#include <QString>
class ApplicationException {
public:
explicit ApplicationException(const QString &message = QString());
virtual ~ApplicationException();
QString message() const;
private:
QString m_message;
};
#endif // APPLICATIONEXCEPTION_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 APPLICATIONEXCEPTION_H
#define APPLICATIONEXCEPTION_H
#include <QString>
class ApplicationException {
public:
explicit ApplicationException(const QString& message = QString());
virtual ~ApplicationException();
QString message() const;
private:
QString m_message;
};
#endif // APPLICATIONEXCEPTION_H

View File

@ -1,25 +1,25 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "exceptions/ioexception.h"
IOException::IOException(const QString &message) : ApplicationException(message) {
}
IOException::~IOException() {
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 "exceptions/ioexception.h"
IOException::IOException(const QString& message) : ApplicationException(message) {
}
IOException::~IOException() {
}

View File

@ -1,30 +1,30 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 IOEXCEPTION_H
#define IOEXCEPTION_H
#include "exceptions/applicationexception.h"
class IOException : public ApplicationException {
public:
explicit IOException(const QString &message = QString());
virtual ~IOException();
};
#endif // IOEXCEPTION_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 IOEXCEPTION_H
#define IOEXCEPTION_H
#include "exceptions/applicationexception.h"
class IOException : public ApplicationException {
public:
explicit IOException(const QString& message = QString());
virtual ~IOException();
};
#endif // IOEXCEPTION_H

View File

@ -1,41 +1,41 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/baselineedit.h"
#include <QKeyEvent>
BaseLineEdit::BaseLineEdit(QWidget *parent) : QLineEdit(parent) {
}
BaseLineEdit::~BaseLineEdit() {
}
void BaseLineEdit::submit(const QString &text) {
setText(text);
emit submitted(text);
}
void BaseLineEdit::keyPressEvent(QKeyEvent *event) {
if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
emit submitted(text());
event->accept();
}
QLineEdit::keyPressEvent(event);
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/baselineedit.h"
#include <QKeyEvent>
BaseLineEdit::BaseLineEdit(QWidget* parent) : QLineEdit(parent) {
}
BaseLineEdit::~BaseLineEdit() {
}
void BaseLineEdit::submit(const QString& text) {
setText(text);
emit submitted(text);
}
void BaseLineEdit::keyPressEvent(QKeyEvent* event) {
if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
emit submitted(text());
event->accept();
}
QLineEdit::keyPressEvent(event);
}

View File

@ -1,43 +1,43 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 BASELINEEDIT_H
#define BASELINEEDIT_H
#include <QLineEdit>
class BaseLineEdit : public QLineEdit {
Q_OBJECT
public:
// Constructors and destructors.
explicit BaseLineEdit(QWidget *parent = 0);
virtual ~BaseLineEdit();
public slots:
void submit(const QString &text);
protected:
void keyPressEvent(QKeyEvent *event);
signals:
// Emitted if user hits ENTER button.
void submitted(const QString &text);
};
#endif // BASELINEEDIT_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 BASELINEEDIT_H
#define BASELINEEDIT_H
#include <QLineEdit>
class BaseLineEdit : public QLineEdit {
Q_OBJECT
public:
// Constructors and destructors.
explicit BaseLineEdit(QWidget* parent = 0);
virtual ~BaseLineEdit();
public slots:
void submit(const QString& text);
protected:
void keyPressEvent(QKeyEvent* event);
signals:
// Emitted if user hits ENTER button.
void submitted(const QString& text);
};
#endif // BASELINEEDIT_H

View File

@ -1,50 +1,50 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/basetoolbar.h"
#include "definitions/definitions.h"
#include "gui/dialogs/formmain.h"
#include "miscellaneous/settings.h"
#include <QWidgetAction>
BaseToolBar::BaseToolBar(const QString &title, QWidget *parent) : QToolBar(title, parent) {
// Update right margin of filter textbox.
QMargins margins = contentsMargins();
margins.setRight(margins.right() + FILTER_RIGHT_MARGIN);
setContentsMargins(margins);
}
BaseToolBar::~BaseToolBar() {
qDebug("Destroying BaseToolBar instance.");
}
void BaseBar::loadSavedActions() {
loadSpecificActions(getSpecificActions(savedActions()));
}
QAction *BaseBar::findMatchingAction(const QString &action, const QList<QAction*> &actions) const {
foreach (QAction *act, actions) {
if (act->objectName() == action) {
return act;
}
}
return nullptr;
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/basetoolbar.h"
#include "definitions/definitions.h"
#include "gui/dialogs/formmain.h"
#include "miscellaneous/settings.h"
#include <QWidgetAction>
BaseToolBar::BaseToolBar(const QString& title, QWidget* parent) : QToolBar(title, parent) {
// Update right margin of filter textbox.
QMargins margins = contentsMargins();
margins.setRight(margins.right() + FILTER_RIGHT_MARGIN);
setContentsMargins(margins);
}
BaseToolBar::~BaseToolBar() {
qDebug("Destroying BaseToolBar instance.");
}
void BaseBar::loadSavedActions() {
loadSpecificActions(getSpecificActions(savedActions()));
}
QAction* BaseBar::findMatchingAction(const QString& action, const QList<QAction*>& actions) const {
foreach (QAction* act, actions) {
if (act->objectName() == action) {
return act;
}
}
return nullptr;
}

View File

@ -1,60 +1,60 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 TOOLBAR_H
#define TOOLBAR_H
#include <QToolBar>
class BaseBar {
public:
// Returns all actions which can be added to the toolbar.
virtual QList<QAction*> availableActions() const = 0;
// Returns all changeable actions which are currently included
// in the toolbar.
virtual QList<QAction*> changeableActions() const = 0;
// Sets new "actions" to the toolbar and perhaps saves the toolbar
// state into the settings.
virtual void saveChangeableActions(const QStringList &actions) = 0;
// Returns list of default actions.
virtual QStringList defaultActions() const = 0;
virtual QStringList savedActions() const = 0;
// Loads the toolbar state from settings.
virtual void loadSavedActions();
virtual QList<QAction*> getSpecificActions(const QStringList &actions) = 0;
virtual void loadSpecificActions(const QList<QAction*> &actions) = 0;
protected:
QAction *findMatchingAction(const QString &action, const QList<QAction *> &actions) const;
};
class BaseToolBar : public QToolBar, public BaseBar {
Q_OBJECT
public:
// Constructors and destructors.
explicit BaseToolBar(const QString &title, QWidget *parent = 0);
virtual ~BaseToolBar();
};
#endif // TOOLBAR_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 TOOLBAR_H
#define TOOLBAR_H
#include <QToolBar>
class BaseBar {
public:
// Returns all actions which can be added to the toolbar.
virtual QList<QAction*> availableActions() const = 0;
// Returns all changeable actions which are currently included
// in the toolbar.
virtual QList<QAction*> changeableActions() const = 0;
// Sets new "actions" to the toolbar and perhaps saves the toolbar
// state into the settings.
virtual void saveChangeableActions(const QStringList& actions) = 0;
// Returns list of default actions.
virtual QStringList defaultActions() const = 0;
virtual QStringList savedActions() const = 0;
// Loads the toolbar state from settings.
virtual void loadSavedActions();
virtual QList<QAction*> getSpecificActions(const QStringList& actions) = 0;
virtual void loadSpecificActions(const QList<QAction*>& actions) = 0;
protected:
QAction* findMatchingAction(const QString& action, const QList<QAction*>& actions) const;
};
class BaseToolBar : public QToolBar, public BaseBar {
Q_OBJECT
public:
// Constructors and destructors.
explicit BaseToolBar(const QString& title, QWidget* parent = 0);
virtual ~BaseToolBar();
};
#endif // TOOLBAR_H

View File

@ -25,61 +25,63 @@
ClickableLabel::ClickableLabel(QWidget* parent)
: QLabel(parent) {
: QLabel(parent) {
}
QString ClickableLabel::themeIcon() const {
return m_themeIcon;
return m_themeIcon;
}
void ClickableLabel::setThemeIcon(const QString &name) {
m_themeIcon = name;
updateIcon();
void ClickableLabel::setThemeIcon(const QString& name) {
m_themeIcon = name;
updateIcon();
}
QIcon ClickableLabel::fallbackIcon() const {
return m_fallbackIcon;
return m_fallbackIcon;
}
void ClickableLabel::setFallbackIcon(const QIcon &fallbackIcon) {
m_fallbackIcon = fallbackIcon;
updateIcon();
void ClickableLabel::setFallbackIcon(const QIcon& fallbackIcon) {
m_fallbackIcon = fallbackIcon;
updateIcon();
}
void ClickableLabel::updateIcon() {
if (!m_themeIcon.isEmpty()) {
if (!m_themeIcon.isEmpty()) {
const QIcon icon = qApp->icons()->fromTheme(m_themeIcon);
const QIcon icon = qApp->icons()->fromTheme(m_themeIcon);
if (!icon.isNull()) {
setPixmap(icon.pixmap(size()));
return;
}
}
if (!icon.isNull()) {
setPixmap(icon.pixmap(size()));
return;
}
}
if (!m_fallbackIcon.isNull()) {
setPixmap(m_fallbackIcon.pixmap(size()));
}
if (!m_fallbackIcon.isNull()) {
setPixmap(m_fallbackIcon.pixmap(size()));
}
}
void ClickableLabel::resizeEvent(QResizeEvent *ev) {
QLabel::resizeEvent(ev);
updateIcon();
void ClickableLabel::resizeEvent(QResizeEvent* ev) {
QLabel::resizeEvent(ev);
updateIcon();
}
void ClickableLabel::mouseReleaseEvent(QMouseEvent* ev) {
if (ev->button() == Qt::LeftButton && rect().contains(ev->pos())) {
if (ev->modifiers() == Qt::ControlModifier) {
emit middleClicked(ev->globalPos());
}
else {
emit clicked(ev->globalPos());
}
}
else if (ev->button() == Qt::MiddleButton && rect().contains(ev->pos())) {
emit middleClicked(ev->globalPos());
}
else {
QLabel::mouseReleaseEvent(ev);
}
if (ev->button() == Qt::LeftButton && rect().contains(ev->pos())) {
if (ev->modifiers() == Qt::ControlModifier) {
emit middleClicked(ev->globalPos());
}
else {
emit clicked(ev->globalPos());
}
}
else if (ev->button() == Qt::MiddleButton && rect().contains(ev->pos())) {
emit middleClicked(ev->globalPos());
}
else {
QLabel::mouseReleaseEvent(ev);
}
}

View File

@ -25,35 +25,35 @@
class QMouseEvent;
class ClickableLabel : public QLabel{
Q_OBJECT
Q_PROPERTY(QSize fixedsize READ size WRITE setFixedSize)
Q_PROPERTY(int fixedwidth READ width WRITE setFixedWidth)
Q_PROPERTY(int fixedheight READ height WRITE setFixedHeight)
Q_PROPERTY(QString themeIcon READ themeIcon WRITE setThemeIcon)
Q_PROPERTY(QIcon fallbackIcon READ fallbackIcon WRITE setFallbackIcon)
class ClickableLabel : public QLabel {
Q_OBJECT
Q_PROPERTY(QSize fixedsize READ size WRITE setFixedSize)
Q_PROPERTY(int fixedwidth READ width WRITE setFixedWidth)
Q_PROPERTY(int fixedheight READ height WRITE setFixedHeight)
Q_PROPERTY(QString themeIcon READ themeIcon WRITE setThemeIcon)
Q_PROPERTY(QIcon fallbackIcon READ fallbackIcon WRITE setFallbackIcon)
public:
explicit ClickableLabel(QWidget *parent = 0);
public:
explicit ClickableLabel(QWidget* parent = 0);
QString themeIcon() const;
void setThemeIcon(const QString &name);
QString themeIcon() const;
void setThemeIcon(const QString& name);
QIcon fallbackIcon() const;
void setFallbackIcon(const QIcon &fallbackIcon);
QIcon fallbackIcon() const;
void setFallbackIcon(const QIcon& fallbackIcon);
signals:
void clicked(QPoint);
void middleClicked(QPoint);
signals:
void clicked(QPoint);
void middleClicked(QPoint);
private:
void updateIcon();
private:
void updateIcon();
void resizeEvent(QResizeEvent *ev);
void mouseReleaseEvent(QMouseEvent* ev);
void resizeEvent(QResizeEvent* ev);
void mouseReleaseEvent(QMouseEvent* ev);
QString m_themeIcon;
QIcon m_fallbackIcon;
QString m_themeIcon;
QIcon m_fallbackIcon;
};

View File

@ -1,43 +1,42 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/colorlabel.h"
#include <QPaintEvent>
#include <QPainter>
ColorLabel::ColorLabel(QWidget *parent) : QLabel(parent), m_color(QColor()) {
setFixedWidth(20);
}
ColorLabel::~ColorLabel() {
}
QColor ColorLabel::color() const {
return m_color;
}
void ColorLabel::setColor(const QColor &color) {
m_color = color;
repaint();
}
void ColorLabel::paintEvent(QPaintEvent *event) {
QPainter(this).fillRect(event->rect(), m_color);
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/colorlabel.h"
#include <QPaintEvent>
#include <QPainter>
ColorLabel::ColorLabel(QWidget* parent) : QLabel(parent), m_color(QColor()) {
setFixedWidth(20);
}
ColorLabel::~ColorLabel() {
}
QColor ColorLabel::color() const {
return m_color;
}
void ColorLabel::setColor(const QColor& color) {
m_color = color;
repaint();
}
void ColorLabel::paintEvent(QPaintEvent* event) {
QPainter(this).fillRect(event->rect(), m_color);
}

View File

@ -1,41 +1,41 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 COLORLABEL_H
#define COLORLABEL_H
#include <QLabel>
class ColorLabel : public QLabel {
Q_OBJECT
public:
explicit ColorLabel(QWidget *parent = 0);
virtual ~ColorLabel();
QColor color() const;
void setColor(const QColor &color);
protected:
void paintEvent(QPaintEvent *event);
private:
QColor m_color;
};
#endif // COLORLABEL_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 COLORLABEL_H
#define COLORLABEL_H
#include <QLabel>
class ColorLabel : public QLabel {
Q_OBJECT
public:
explicit ColorLabel(QWidget* parent = 0);
virtual ~ColorLabel();
QColor color() const;
void setColor(const QColor& color);
protected:
void paintEvent(QPaintEvent* event);
private:
QColor m_color;
};
#endif // COLORLABEL_H

View File

@ -1,39 +1,37 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/comboboxwithstatus.h"
#include "gui/plaintoolbutton.h"
#include <QHBoxLayout>
ComboBoxWithStatus::ComboBoxWithStatus(QWidget *parent)
: WidgetWithStatus(parent) {
m_wdgInput = new QComboBox(this);
// Set correct size for the tool button.
const int txt_input_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(txt_input_height, txt_input_height);
// Compose the layout.
m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus);
}
ComboBoxWithStatus::~ComboBoxWithStatus() {
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/comboboxwithstatus.h"
#include "gui/plaintoolbutton.h"
#include <QHBoxLayout>
ComboBoxWithStatus::ComboBoxWithStatus(QWidget* parent)
: WidgetWithStatus(parent) {
m_wdgInput = new QComboBox(this);
// Set correct size for the tool button.
const int txt_input_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(txt_input_height, txt_input_height);
// Compose the layout.
m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus);
}
ComboBoxWithStatus::~ComboBoxWithStatus() {
}

View File

@ -1,39 +1,39 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 COMBOBOXWITHSTATUS_H
#define COMBOBOXWITHSTATUS_H
#include "gui/widgetwithstatus.h"
#include <QComboBox>
class ComboBoxWithStatus : public WidgetWithStatus {
Q_OBJECT
public:
// Constructors and destructors.
explicit ComboBoxWithStatus(QWidget *parent = 0);
virtual ~ComboBoxWithStatus();
inline QComboBox *comboBox() const {
return static_cast<QComboBox*>(m_wdgInput);
}
};
#endif // COMBOBOXWITHSTATUS_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 COMBOBOXWITHSTATUS_H
#define COMBOBOXWITHSTATUS_H
#include "gui/widgetwithstatus.h"
#include <QComboBox>
class ComboBoxWithStatus : public WidgetWithStatus {
Q_OBJECT
public:
// Constructors and destructors.
explicit ComboBoxWithStatus(QWidget* parent = 0);
virtual ~ComboBoxWithStatus();
inline QComboBox* comboBox() const {
return static_cast<QComboBox*>(m_wdgInput);
}
};
#endif // COMBOBOXWITHSTATUS_H

View File

@ -1,122 +1,122 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formabout.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/textfactory.h"
#include "miscellaneous/settingsproperties.h"
#include <QFile>
#include <QTextStream>
FormAbout::FormAbout(QWidget *parent) : QDialog(parent), m_ui(new Ui::FormAbout()) {
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about")));
//: About RSS Guard dialog title.
setWindowTitle(tr("About %1").arg(APP_NAME));
m_ui->m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH));
// Load information from embedded text files.
loadLicenseAndInformation();
// Load additional paths information.
loadSettingsAndPaths();
}
FormAbout::~FormAbout() {
qDebug("Destroying FormAbout instance.");
}
void FormAbout::loadSettingsAndPaths() {
if (qApp->settings()->type() == SettingsProperties::Portable) {
m_ui->m_txtPathsSettingsType->setText(tr("FULLY portable"));
}
else {
m_ui->m_txtPathsSettingsType->setText(tr("NOT portable"));
}
m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->getUserDataPath() +
QDir::separator() +
QString(APP_DB_SQLITE_PATH)));
m_ui->m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName()));
m_ui->m_txtPathsSkinsRoot->setText(QDir::toNativeSeparators(qApp->skins()->getUserSkinBaseFolder()));
}
void FormAbout::loadLicenseAndInformation() {
QFile file;
file.setFileName(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtLicenseGnu->setText(QString::fromUtf8(file.readAll()));
}
else {
m_ui->m_txtLicenseGnu->setText(tr("License not found."));
}
file.close();
file.setFileName(APP_INFO_PATH + QL1S("/COPYING_BSD"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtLicenseBsd->setText(QString::fromUtf8(file.readAll()));
}
else {
m_ui->m_txtLicenseBsd->setText(tr("License not found."));
}
file.close();
file.setFileName(APP_INFO_PATH + QL1S("/CHANGELOG"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtChangelog->setText(QString::fromUtf8(file.readAll()));
}
else {
m_ui->m_txtChangelog->setText(tr("Changelog not found."));
}
file.close();
// Set other informative texts.
m_ui->m_lblDesc->setText(tr("<b>%8</b><br>"
"<b>Version:</b> %1 (built on %2/%3)<br>"
"<b>Revision:</b> %4<br>"
"<b>Build date:</b> %5<br>"
"<b>Qt:</b> %6 (compiled against %7)<br>").arg(qApp->applicationVersion(),
APP_SYSTEM_NAME,
APP_SYSTEM_VERSION,
APP_REVISION,
TextFactory::parseDateTime(QString("%1 %2").arg(__DATE__,
__TIME__)).toString(Qt::DefaultLocaleShortDate),
qVersion(),
QT_VERSION_STR,
APP_NAME));
m_ui->m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader."
"<br><br>This software is distributed under the terms of GNU General Public License, version 3."
"<br><br>Contacts:"
"<ul><li><a href=\"mailto://%1\">%1</a> ~e-mail</li>"
"<li><a href=\"%2\">%2</a> ~website</li></ul>"
"You can obtain source code for %5 from its website."
"<br><br><br>Copyright (C) 2011-%3 %4</body>").arg(APP_EMAIL,
APP_URL,
QString::number(QDateTime::currentDateTime().date().year()),
APP_AUTHOR,
APP_NAME));
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formabout.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/textfactory.h"
#include "miscellaneous/settingsproperties.h"
#include <QFile>
#include <QTextStream>
FormAbout::FormAbout(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormAbout()) {
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about")));
//: About RSS Guard dialog title.
setWindowTitle(tr("About %1").arg(APP_NAME));
m_ui->m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH));
// Load information from embedded text files.
loadLicenseAndInformation();
// Load additional paths information.
loadSettingsAndPaths();
}
FormAbout::~FormAbout() {
qDebug("Destroying FormAbout instance.");
}
void FormAbout::loadSettingsAndPaths() {
if (qApp->settings()->type() == SettingsProperties::Portable) {
m_ui->m_txtPathsSettingsType->setText(tr("FULLY portable"));
}
else {
m_ui->m_txtPathsSettingsType->setText(tr("NOT portable"));
}
m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->getUserDataPath() +
QDir::separator() +
QString(APP_DB_SQLITE_PATH)));
m_ui->m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName()));
m_ui->m_txtPathsSkinsRoot->setText(QDir::toNativeSeparators(qApp->skins()->getUserSkinBaseFolder()));
}
void FormAbout::loadLicenseAndInformation() {
QFile file;
file.setFileName(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtLicenseGnu->setText(QString::fromUtf8(file.readAll()));
}
else {
m_ui->m_txtLicenseGnu->setText(tr("License not found."));
}
file.close();
file.setFileName(APP_INFO_PATH + QL1S("/COPYING_BSD"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtLicenseBsd->setText(QString::fromUtf8(file.readAll()));
}
else {
m_ui->m_txtLicenseBsd->setText(tr("License not found."));
}
file.close();
file.setFileName(APP_INFO_PATH + QL1S("/CHANGELOG"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtChangelog->setText(QString::fromUtf8(file.readAll()));
}
else {
m_ui->m_txtChangelog->setText(tr("Changelog not found."));
}
file.close();
// Set other informative texts.
m_ui->m_lblDesc->setText(tr("<b>%8</b><br>"
"<b>Version:</b> %1 (built on %2/%3)<br>"
"<b>Revision:</b> %4<br>"
"<b>Build date:</b> %5<br>"
"<b>Qt:</b> %6 (compiled against %7)<br>").arg(qApp->applicationVersion(),
APP_SYSTEM_NAME,
APP_SYSTEM_VERSION,
APP_REVISION,
TextFactory::parseDateTime(QString("%1 %2").arg(__DATE__,
__TIME__)).toString(Qt::DefaultLocaleShortDate),
qVersion(),
QT_VERSION_STR,
APP_NAME));
m_ui->m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader."
"<br><br>This software is distributed under the terms of GNU General Public License, version 3."
"<br><br>Contacts:"
"<ul><li><a href=\"mailto://%1\">%1</a> ~e-mail</li>"
"<li><a href=\"%2\">%2</a> ~website</li></ul>"
"You can obtain source code for %5 from its website."
"<br><br><br>Copyright (C) 2011-%3 %4</body>").arg(APP_EMAIL,
APP_URL,
QString::number(QDateTime::currentDateTime().date().year()),
APP_AUTHOR,
APP_NAME));
}

View File

@ -1,43 +1,43 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMABOUT_H
#define FORMABOUT_H
#include <QDialog>
#include "ui_formabout.h"
#include "definitions/definitions.h"
class FormAbout : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormAbout(QWidget *parent);
virtual ~FormAbout();
private:
void loadLicenseAndInformation();
void loadSettingsAndPaths();
QScopedPointer<Ui::FormAbout> m_ui;
};
#endif // FORMABOUT_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMABOUT_H
#define FORMABOUT_H
#include <QDialog>
#include "ui_formabout.h"
#include "definitions/definitions.h"
class FormAbout : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormAbout(QWidget* parent);
virtual ~FormAbout();
private:
void loadLicenseAndInformation();
void loadSettingsAndPaths();
QScopedPointer<Ui::FormAbout> m_ui;
};
#endif // FORMABOUT_H

View File

@ -26,61 +26,58 @@
#include <QDialogButtonBox>
FormAddAccount::FormAddAccount(const QList<ServiceEntryPoint*> &entry_points, FeedsModel *model, QWidget *parent)
: QDialog(parent), m_ui(new Ui::FormAddAccount), m_model(model), m_entryPoints(entry_points) {
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("document-new")));
connect(m_ui->m_listEntryPoints, &QListWidget::itemDoubleClicked, this, &FormAddAccount::addSelectedAccount);
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormAddAccount::addSelectedAccount);
connect(m_ui->m_listEntryPoints, &QListWidget::itemSelectionChanged, this, &FormAddAccount::displayActiveEntryPointDetails);
loadEntryPoints();
FormAddAccount::FormAddAccount(const QList<ServiceEntryPoint*>& entry_points, FeedsModel* model, QWidget* parent)
: QDialog(parent), m_ui(new Ui::FormAddAccount), m_model(model), m_entryPoints(entry_points) {
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("document-new")));
connect(m_ui->m_listEntryPoints, &QListWidget::itemDoubleClicked, this, &FormAddAccount::addSelectedAccount);
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormAddAccount::addSelectedAccount);
connect(m_ui->m_listEntryPoints, &QListWidget::itemSelectionChanged, this, &FormAddAccount::displayActiveEntryPointDetails);
loadEntryPoints();
}
FormAddAccount::~FormAddAccount() {
qDebug("Destroying FormAddAccount instance.");
qDebug("Destroying FormAddAccount instance.");
}
void FormAddAccount::addSelectedAccount() {
accept();
accept();
ServiceEntryPoint* point = selectedEntryPoint();
ServiceRoot* new_root = point->createNewRoot();
ServiceEntryPoint *point = selectedEntryPoint();
ServiceRoot *new_root = point->createNewRoot();
if (new_root != nullptr) {
m_model->addServiceAccount(new_root, true);
}
if (new_root != nullptr) {
m_model->addServiceAccount(new_root, true);
}
else {
qCritical("Cannot create new account.");
}
else {
qCritical("Cannot create new account.");
}
}
void FormAddAccount::displayActiveEntryPointDetails() {
const ServiceEntryPoint *point = selectedEntryPoint();
m_ui->m_txtAuthor->setText(point->author());
m_ui->m_txtDescription->setText(point->description());
m_ui->m_txtName->setText(point->name());
m_ui->m_txtVersion->setText(point->version());
const ServiceEntryPoint* point = selectedEntryPoint();
m_ui->m_txtAuthor->setText(point->author());
m_ui->m_txtDescription->setText(point->description());
m_ui->m_txtName->setText(point->name());
m_ui->m_txtVersion->setText(point->version());
}
ServiceEntryPoint *FormAddAccount::selectedEntryPoint() const {
return m_entryPoints.at(m_ui->m_listEntryPoints->currentRow());
ServiceEntryPoint* FormAddAccount::selectedEntryPoint() const {
return m_entryPoints.at(m_ui->m_listEntryPoints->currentRow());
}
void FormAddAccount::loadEntryPoints() {
foreach (const ServiceEntryPoint *entry_point, m_entryPoints) {
QListWidgetItem *item = new QListWidgetItem(entry_point->icon(), entry_point->name(), m_ui->m_listEntryPoints);
foreach (const ServiceEntryPoint* entry_point, m_entryPoints) {
QListWidgetItem* item = new QListWidgetItem(entry_point->icon(), entry_point->name(), m_ui->m_listEntryPoints);
if (entry_point->isSingleInstanceService() && m_model->containsServiceRootFromEntryPoint(entry_point)) {
// Oops, this item cannot be added, it is single instance and is already added.
item->setFlags(Qt::NoItemFlags);
item->setToolTip(tr("This account can be added only once."));
}
}
if (entry_point->isSingleInstanceService() && m_model->containsServiceRootFromEntryPoint(entry_point)) {
// Oops, this item cannot be added, it is single instance and is already added.
item->setFlags(Qt::NoItemFlags);
item->setToolTip(tr("This account can be added only once."));
}
}
m_ui->m_listEntryPoints->setCurrentRow(m_entryPoints.size() - 1);
m_ui->m_listEntryPoints->setCurrentRow(m_entryPoints.size() - 1);
}

View File

@ -27,23 +27,23 @@ class ServiceEntryPoint;
class FeedsModel;
class FormAddAccount : public QDialog {
Q_OBJECT
Q_OBJECT
public:
explicit FormAddAccount(const QList<ServiceEntryPoint*> &entry_points, FeedsModel *model, QWidget *parent = 0);
virtual ~FormAddAccount();
public:
explicit FormAddAccount(const QList<ServiceEntryPoint*>& entry_points, FeedsModel* model, QWidget* parent = 0);
virtual ~FormAddAccount();
private slots:
void addSelectedAccount();
void displayActiveEntryPointDetails();
private slots:
void addSelectedAccount();
void displayActiveEntryPointDetails();
private:
ServiceEntryPoint *selectedEntryPoint() const;
void loadEntryPoints();
private:
ServiceEntryPoint* selectedEntryPoint() const;
void loadEntryPoints();
QScopedPointer<Ui::FormAddAccount> m_ui;
FeedsModel *m_model;
QList<ServiceEntryPoint*> m_entryPoints;
QScopedPointer<Ui::FormAddAccount> m_ui;
FeedsModel* m_model;
QList<ServiceEntryPoint*> m_entryPoints;
};
#endif // FORMADDACCOUNT_H

View File

@ -28,74 +28,73 @@
#include <QDateTime>
FormBackupDatabaseSettings::FormBackupDatabaseSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::FormBackupDatabaseSettings) {
m_ui->setupUi(this);
m_ui->m_txtBackupName->lineEdit()->setPlaceholderText(tr("Common name for backup files"));
FormBackupDatabaseSettings::FormBackupDatabaseSettings(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormBackupDatabaseSettings) {
m_ui->setupUi(this);
m_ui->m_txtBackupName->lineEdit()->setPlaceholderText(tr("Common name for backup files"));
setWindowIcon(qApp->icons()->fromTheme(QSL("document-export")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
connect(m_ui->m_checkBackupDatabase, &QCheckBox::toggled, this, &FormBackupDatabaseSettings::checkOkButton);
connect(m_ui->m_checkBackupSettings, &QCheckBox::toggled, this, &FormBackupDatabaseSettings::checkOkButton);
connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormBackupDatabaseSettings::performBackup);
connect(m_ui->m_txtBackupName->lineEdit(), &BaseLineEdit::textChanged, this, &FormBackupDatabaseSettings::checkBackupNames);
connect(m_ui->m_txtBackupName->lineEdit(), &BaseLineEdit::textChanged, this, &FormBackupDatabaseSettings::checkOkButton);
connect(m_ui->m_btnSelectFolder, &QPushButton::clicked, this, &FormBackupDatabaseSettings::selectFolderInitial);
selectFolder(qApp->getDocumentsFolderPath());
m_ui->m_txtBackupName->lineEdit()->setText(QString(APP_LOW_NAME) + QL1S("_") + QDateTime::currentDateTime().toString(QSL("yyyyMMddHHmm")));
m_ui->m_lblResult->setStatus(WidgetWithStatus::Warning, tr("No operation executed yet."), tr("No operation executed yet."));
setWindowIcon(qApp->icons()->fromTheme(QSL("document-export")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
connect(m_ui->m_checkBackupDatabase, &QCheckBox::toggled, this, &FormBackupDatabaseSettings::checkOkButton);
connect(m_ui->m_checkBackupSettings, &QCheckBox::toggled, this, &FormBackupDatabaseSettings::checkOkButton);
connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormBackupDatabaseSettings::performBackup);
connect(m_ui->m_txtBackupName->lineEdit(), &BaseLineEdit::textChanged, this, &FormBackupDatabaseSettings::checkBackupNames);
connect(m_ui->m_txtBackupName->lineEdit(), &BaseLineEdit::textChanged, this, &FormBackupDatabaseSettings::checkOkButton);
connect(m_ui->m_btnSelectFolder, &QPushButton::clicked, this, &FormBackupDatabaseSettings::selectFolderInitial);
selectFolder(qApp->getDocumentsFolderPath());
m_ui->m_txtBackupName->lineEdit()->setText(QString(APP_LOW_NAME) + QL1S("_") + QDateTime::currentDateTime().toString(QSL("yyyyMMddHHmm")));
m_ui->m_lblResult->setStatus(WidgetWithStatus::Warning, tr("No operation executed yet."), tr("No operation executed yet."));
if (qApp->database()->activeDatabaseDriver() != DatabaseFactory::SQLITE &&
qApp->database()->activeDatabaseDriver() != DatabaseFactory::SQLITE_MEMORY) {
m_ui->m_checkBackupDatabase->setDisabled(true);
}
if (qApp->database()->activeDatabaseDriver() != DatabaseFactory::SQLITE &&
qApp->database()->activeDatabaseDriver() != DatabaseFactory::SQLITE_MEMORY) {
m_ui->m_checkBackupDatabase->setDisabled(true);
}
}
FormBackupDatabaseSettings::~FormBackupDatabaseSettings() {
qDebug("Destroying FormBackupDatabaseSettings instance.");
qDebug("Destroying FormBackupDatabaseSettings instance.");
}
void FormBackupDatabaseSettings::performBackup() {
try {
qApp->backupDatabaseSettings(m_ui->m_checkBackupDatabase->isChecked(), m_ui->m_checkBackupSettings->isChecked(),
m_ui->m_lblSelectFolder->label()->text(), m_ui->m_txtBackupName->lineEdit()->text());
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok,
tr("Backup was created successfully and stored in target directory."),
tr("Backup was created successfully."));
}
catch (const ApplicationException &ex) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(), tr("Backup failed."));
}
try {
qApp->backupDatabaseSettings(m_ui->m_checkBackupDatabase->isChecked(), m_ui->m_checkBackupSettings->isChecked(),
m_ui->m_lblSelectFolder->label()->text(), m_ui->m_txtBackupName->lineEdit()->text());
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok,
tr("Backup was created successfully and stored in target directory."),
tr("Backup was created successfully."));
}
catch (const ApplicationException& ex) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(), tr("Backup failed."));
}
}
void FormBackupDatabaseSettings::selectFolderInitial() {
selectFolder();
selectFolder();
}
void FormBackupDatabaseSettings::selectFolder(QString path) {
if (path.isEmpty()) {
path = QFileDialog::getExistingDirectory(this, tr("Select destination directory"), m_ui->m_lblSelectFolder->label()->text());
}
if (path.isEmpty()) {
path = QFileDialog::getExistingDirectory(this, tr("Select destination directory"), m_ui->m_lblSelectFolder->label()->text());
}
if (!path.isEmpty()) {
m_ui->m_lblSelectFolder->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(path),
tr("Good destination directory is specified."));
}
if (!path.isEmpty()) {
m_ui->m_lblSelectFolder->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(path),
tr("Good destination directory is specified."));
}
}
void FormBackupDatabaseSettings::checkBackupNames(const QString &name) {
if (name.simplified().isEmpty()) {
m_ui->m_txtBackupName->setStatus(WidgetWithStatus::Error, tr("Backup name cannot be empty."));
}
else {
m_ui->m_txtBackupName->setStatus(WidgetWithStatus::Ok, tr("Backup name looks okay."));
}
void FormBackupDatabaseSettings::checkBackupNames(const QString& name) {
if (name.simplified().isEmpty()) {
m_ui->m_txtBackupName->setStatus(WidgetWithStatus::Error, tr("Backup name cannot be empty."));
}
else {
m_ui->m_txtBackupName->setStatus(WidgetWithStatus::Ok, tr("Backup name looks okay."));
}
}
void FormBackupDatabaseSettings::checkOkButton() {
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setDisabled(m_ui->m_txtBackupName->lineEdit()->text().simplified().isEmpty() ||
m_ui->m_lblSelectFolder->label()->text().simplified().isEmpty() ||
(!m_ui->m_checkBackupDatabase->isChecked() &&
!m_ui->m_checkBackupSettings->isChecked()));
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setDisabled(m_ui->m_txtBackupName->lineEdit()->text().simplified().isEmpty() ||
m_ui->m_lblSelectFolder->label()->text().simplified().isEmpty() ||
(!m_ui->m_checkBackupDatabase->isChecked() &&
!m_ui->m_checkBackupSettings->isChecked()));
}

View File

@ -24,23 +24,23 @@
class FormBackupDatabaseSettings : public QDialog {
Q_OBJECT
Q_OBJECT
public:
// Constructors and destructors
explicit FormBackupDatabaseSettings(QWidget *parent = 0);
virtual ~FormBackupDatabaseSettings();
public:
// Constructors and destructors
explicit FormBackupDatabaseSettings(QWidget* parent = 0);
virtual ~FormBackupDatabaseSettings();
private slots:
void performBackup();
void selectFolderInitial();
void selectFolder(QString path = QString());
void checkBackupNames(const QString &name);
void checkOkButton();
private slots:
void performBackup();
void selectFolderInitial();
void selectFolder(QString path = QString());
void checkBackupNames(const QString& name);
void checkOkButton();
private:
QScopedPointer<Ui::FormBackupDatabaseSettings> m_ui;
private:
QScopedPointer<Ui::FormBackupDatabaseSettings> m_ui;
};
#endif // FORMBACKUPDATABASECONFIG_H

View File

@ -1,135 +1,131 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formdatabasecleanup.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/databasefactory.h"
#include <QCloseEvent>
#include <QDialogButtonBox>
#include <QPushButton>
FormDatabaseCleanup::FormDatabaseCleanup(QWidget *parent) : QDialog(parent), m_ui(new Ui::FormDatabaseCleanup), m_cleaner(nullptr) {
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("edit-clear")));
connect(m_ui->m_spinDays, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &FormDatabaseCleanup::updateDaysSuffix);
m_ui->m_spinDays->setValue(DEFAULT_DAYS_TO_DELETE_MSG);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Information, tr("I am ready."), tr("I am ready."));
loadDatabaseInfo();
}
FormDatabaseCleanup::~FormDatabaseCleanup() {
qDebug("Destroying FormDatabaseCleanup instance.");
}
void FormDatabaseCleanup::setCleaner(DatabaseCleaner *cleaner) {
if (m_cleaner != nullptr) {
disconnect(this, 0, m_cleaner, 0);
disconnect(m_cleaner, 0, this, 0);
}
m_cleaner = cleaner;
connect(m_ui->m_btnBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormDatabaseCleanup::startPurging);
connect(this, &FormDatabaseCleanup::purgeRequested, m_cleaner, &DatabaseCleaner::purgeDatabaseData);
connect(m_cleaner, &DatabaseCleaner::purgeStarted, this, &FormDatabaseCleanup::onPurgeStarted);
connect(m_cleaner, &DatabaseCleaner::purgeProgress, this, &FormDatabaseCleanup::onPurgeProgress);
connect(m_cleaner, &DatabaseCleaner::purgeFinished, this,&FormDatabaseCleanup::onPurgeFinished);
}
void FormDatabaseCleanup::closeEvent(QCloseEvent *event) {
if (m_ui->m_progressBar->isEnabled()) {
event->ignore();
}
else {
QDialog::closeEvent(event);
}
}
void FormDatabaseCleanup::keyPressEvent(QKeyEvent *event) {
if (m_ui->m_progressBar->isEnabled()) {
event->ignore();
}
else {
QDialog::keyPressEvent(event);
}
}
void FormDatabaseCleanup::updateDaysSuffix(int number) {
m_ui->m_spinDays->setSuffix(tr(" day(s)", 0, number));
}
void FormDatabaseCleanup::startPurging() {
CleanerOrders orders;
orders.m_removeRecycleBin = m_ui->m_checkRemoveRecycleBin->isChecked();
orders.m_removeOldMessages = m_ui->m_checkRemoveOldMessages->isChecked();
orders.m_barrierForRemovingOldMessagesInDays = m_ui->m_spinDays->value();
orders.m_removeReadMessages = m_ui->m_checkRemoveReadMessages->isChecked();
orders.m_shrinkDatabase = m_ui->m_checkShrink->isEnabled() && m_ui->m_checkShrink->isChecked();
orders.m_removeStarredMessages = m_ui->m_checkRemoveStarredMessages->isChecked();
emit purgeRequested(orders);
}
void FormDatabaseCleanup::onPurgeStarted() {
m_ui->m_progressBar->setValue(0);
m_ui->m_progressBar->setEnabled(true);
m_ui->m_btnBox->setEnabled(false);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Information, tr("Database cleanup is running."), tr("Database cleanup is running."));
}
void FormDatabaseCleanup::onPurgeProgress(int progress, const QString &description) {
m_ui->m_progressBar->setValue(progress);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Information, description, description);
}
void FormDatabaseCleanup::onPurgeFinished(bool finished) {
m_ui->m_progressBar->setEnabled(false);
m_ui->m_progressBar->setValue(0);
m_ui->m_btnBox->setEnabled(true);
if (finished) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Database cleanup is completed."), tr("Database cleanup is completed."));
}
else {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, tr("Database cleanup failed."), tr("Database cleanup failed."));
}
loadDatabaseInfo();
}
void FormDatabaseCleanup::loadDatabaseInfo() {
qint64 file_size = qApp->database()->getDatabaseFileSize();
qint64 data_size = qApp->database()->getDatabaseDataSize();
QString file_size_str = file_size > 0 ? QString::number(file_size / 1000000.0) + QL1S(" MB") : tr("unknown");
QString data_size_str = data_size > 0 ? QString::number(data_size / 1000000.0) + QL1S(" MB") : tr("unknown");
m_ui->m_txtFileSize->setText(tr("file: %1, data: %2").arg(file_size_str, data_size_str));
m_ui->m_txtDatabaseType->setText(qApp->database()->humanDriverName(qApp->database()->activeDatabaseDriver()));
m_ui->m_checkShrink->setEnabled(qApp->database()->activeDatabaseDriver() == DatabaseFactory::SQLITE ||
qApp->database()->activeDatabaseDriver() == DatabaseFactory::SQLITE_MEMORY);
m_ui->m_checkShrink->setChecked(m_ui->m_checkShrink->isEnabled());
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formdatabasecleanup.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/databasefactory.h"
#include <QCloseEvent>
#include <QDialogButtonBox>
#include <QPushButton>
FormDatabaseCleanup::FormDatabaseCleanup(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormDatabaseCleanup), m_cleaner(nullptr) {
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("edit-clear")));
connect(m_ui->m_spinDays, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &FormDatabaseCleanup::updateDaysSuffix);
m_ui->m_spinDays->setValue(DEFAULT_DAYS_TO_DELETE_MSG);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Information, tr("I am ready."), tr("I am ready."));
loadDatabaseInfo();
}
FormDatabaseCleanup::~FormDatabaseCleanup() {
qDebug("Destroying FormDatabaseCleanup instance.");
}
void FormDatabaseCleanup::setCleaner(DatabaseCleaner* cleaner) {
if (m_cleaner != nullptr) {
disconnect(this, 0, m_cleaner, 0);
disconnect(m_cleaner, 0, this, 0);
}
m_cleaner = cleaner;
connect(m_ui->m_btnBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormDatabaseCleanup::startPurging);
connect(this, &FormDatabaseCleanup::purgeRequested, m_cleaner, &DatabaseCleaner::purgeDatabaseData);
connect(m_cleaner, &DatabaseCleaner::purgeStarted, this, &FormDatabaseCleanup::onPurgeStarted);
connect(m_cleaner, &DatabaseCleaner::purgeProgress, this, &FormDatabaseCleanup::onPurgeProgress);
connect(m_cleaner, &DatabaseCleaner::purgeFinished, this, &FormDatabaseCleanup::onPurgeFinished);
}
void FormDatabaseCleanup::closeEvent(QCloseEvent* event) {
if (m_ui->m_progressBar->isEnabled()) {
event->ignore();
}
else {
QDialog::closeEvent(event);
}
}
void FormDatabaseCleanup::keyPressEvent(QKeyEvent* event) {
if (m_ui->m_progressBar->isEnabled()) {
event->ignore();
}
else {
QDialog::keyPressEvent(event);
}
}
void FormDatabaseCleanup::updateDaysSuffix(int number) {
m_ui->m_spinDays->setSuffix(tr(" day(s)", 0, number));
}
void FormDatabaseCleanup::startPurging() {
CleanerOrders orders;
orders.m_removeRecycleBin = m_ui->m_checkRemoveRecycleBin->isChecked();
orders.m_removeOldMessages = m_ui->m_checkRemoveOldMessages->isChecked();
orders.m_barrierForRemovingOldMessagesInDays = m_ui->m_spinDays->value();
orders.m_removeReadMessages = m_ui->m_checkRemoveReadMessages->isChecked();
orders.m_shrinkDatabase = m_ui->m_checkShrink->isEnabled() && m_ui->m_checkShrink->isChecked();
orders.m_removeStarredMessages = m_ui->m_checkRemoveStarredMessages->isChecked();
emit purgeRequested(orders);
}
void FormDatabaseCleanup::onPurgeStarted() {
m_ui->m_progressBar->setValue(0);
m_ui->m_progressBar->setEnabled(true);
m_ui->m_btnBox->setEnabled(false);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Information, tr("Database cleanup is running."), tr("Database cleanup is running."));
}
void FormDatabaseCleanup::onPurgeProgress(int progress, const QString& description) {
m_ui->m_progressBar->setValue(progress);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Information, description, description);
}
void FormDatabaseCleanup::onPurgeFinished(bool finished) {
m_ui->m_progressBar->setEnabled(false);
m_ui->m_progressBar->setValue(0);
m_ui->m_btnBox->setEnabled(true);
if (finished) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Database cleanup is completed."), tr("Database cleanup is completed."));
}
else {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, tr("Database cleanup failed."), tr("Database cleanup failed."));
}
loadDatabaseInfo();
}
void FormDatabaseCleanup::loadDatabaseInfo() {
qint64 file_size = qApp->database()->getDatabaseFileSize();
qint64 data_size = qApp->database()->getDatabaseDataSize();
QString file_size_str = file_size > 0 ? QString::number(file_size / 1000000.0) + QL1S(" MB") : tr("unknown");
QString data_size_str = data_size > 0 ? QString::number(data_size / 1000000.0) + QL1S(" MB") : tr("unknown");
m_ui->m_txtFileSize->setText(tr("file: %1, data: %2").arg(file_size_str, data_size_str));
m_ui->m_txtDatabaseType->setText(qApp->database()->humanDriverName(qApp->database()->activeDatabaseDriver()));
m_ui->m_checkShrink->setEnabled(qApp->database()->activeDatabaseDriver() == DatabaseFactory::SQLITE ||
qApp->database()->activeDatabaseDriver() == DatabaseFactory::SQLITE_MEMORY);
m_ui->m_checkShrink->setChecked(m_ui->m_checkShrink->isEnabled());
}

View File

@ -1,60 +1,60 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMDATABASECLEANUP_H
#define FORMDATABASECLEANUP_H
#include <QDialog>
#include "ui_formdatabasecleanup.h"
#include "miscellaneous/databasecleaner.h"
class FormDatabaseCleanup : public QDialog {
Q_OBJECT
public:
// Constructors.
explicit FormDatabaseCleanup(QWidget *parent = 0);
virtual ~FormDatabaseCleanup();
void setCleaner(DatabaseCleaner *cleaner);
protected:
void closeEvent(QCloseEvent *event);
void keyPressEvent(QKeyEvent *event);
private slots:
void updateDaysSuffix(int number);
void startPurging();
void onPurgeStarted();
void onPurgeProgress(int progress, const QString &description);
void onPurgeFinished(bool finished);
signals:
void purgeRequested(const CleanerOrders &which_data);
private:
void loadDatabaseInfo();
private:
QScopedPointer<Ui::FormDatabaseCleanup> m_ui;
DatabaseCleaner *m_cleaner;
};
#endif // FORMDATABASECLEANUP_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMDATABASECLEANUP_H
#define FORMDATABASECLEANUP_H
#include <QDialog>
#include "ui_formdatabasecleanup.h"
#include "miscellaneous/databasecleaner.h"
class FormDatabaseCleanup : public QDialog {
Q_OBJECT
public:
// Constructors.
explicit FormDatabaseCleanup(QWidget* parent = 0);
virtual ~FormDatabaseCleanup();
void setCleaner(DatabaseCleaner* cleaner);
protected:
void closeEvent(QCloseEvent* event);
void keyPressEvent(QKeyEvent* event);
private slots:
void updateDaysSuffix(int number);
void startPurging();
void onPurgeStarted();
void onPurgeProgress(int progress, const QString& description);
void onPurgeFinished(bool finished);
signals:
void purgeRequested(const CleanerOrders& which_data);
private:
void loadDatabaseInfo();
private:
QScopedPointer<Ui::FormDatabaseCleanup> m_ui;
DatabaseCleaner* m_cleaner;
};
#endif // FORMDATABASECLEANUP_H

File diff suppressed because it is too large Load Diff

View File

@ -1,125 +1,125 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMMAIN_H
#define FORMMAIN_H
#include <QMainWindow>
#include "ui_formmain.h"
#if defined(USE_WEBENGINE)
class AdBlockIcon;
#endif
class StatusBar;
class FormMain : public QMainWindow {
Q_OBJECT
friend class TabWidget;
friend class MessagesView;
friend class FeedsView;
public:
// Constructors and destructors.
explicit FormMain(QWidget *parent = 0, Qt::WindowFlags f = 0);
virtual ~FormMain();
// Returns menu for the tray icon.
QMenu *trayMenu() const;
// Returns global tab widget.
TabWidget *tabWidget() const;
// Access to statusbar.
StatusBar *statusBar() const;
// Returns list of all globally available actions.
// NOTE: This is used for setting dynamic shortcuts
// for given actions.
QList<QAction*> allActions() const;
// Loads/saves visual state of the application.
void loadSize();
void saveSize();
#if defined(USE_WEBENGINE)
AdBlockIcon *adblockIcon() const {
return m_adblockIcon;
}
#endif
public slots:
// Displays window on top or switches its visibility.
void display();
// Switches visibility of main window.
void switchVisibility(bool force_hide = false);
// Turns on/off fullscreen mode
void switchFullscreenMode();
private slots:
void updateAddItemMenu();
void updateRecycleBinMenu();
void updateAccountsMenu();
void updateMessageButtonsAvailability();
void updateFeedButtonsAvailability();
void onFeedUpdatesStarted();
void onFeedUpdatesProgress(const Feed *feed, int current, int total);
void onFeedUpdatesFinished(const FeedDownloadResults &results);
// Displays various dialogs.
void backupDatabaseSettings();
void restoreDatabaseSettings();
void showSettings();
void showAbout();
void showUpdates();
void showWiki();
void showAddAccountDialog();
void showDbCleanupAssistant();
void reportABug();
void donate();
private:
// Event handler reimplementations.
void changeEvent(QEvent *event);
// Creates all needed menus and sets them up.
void prepareMenus();
// Creates needed connections for this window.
void createConnections();
// Sets up proper icons for this widget.
void setupIcons();
#if defined(USE_WEBENGINE)
AdBlockIcon *m_adblockIcon;
QAction *m_adblockIconAction;
#endif
QScopedPointer<Ui::FormMain> m_ui;
QMenu *m_trayMenu;
StatusBar *m_statusBar;
};
#endif // FORMMAIN_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMMAIN_H
#define FORMMAIN_H
#include <QMainWindow>
#include "ui_formmain.h"
#if defined(USE_WEBENGINE)
class AdBlockIcon;
#endif
class StatusBar;
class FormMain : public QMainWindow {
Q_OBJECT
friend class TabWidget;
friend class MessagesView;
friend class FeedsView;
public:
// Constructors and destructors.
explicit FormMain(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~FormMain();
// Returns menu for the tray icon.
QMenu* trayMenu() const;
// Returns global tab widget.
TabWidget* tabWidget() const;
// Access to statusbar.
StatusBar* statusBar() const;
// Returns list of all globally available actions.
// NOTE: This is used for setting dynamic shortcuts
// for given actions.
QList<QAction*> allActions() const;
// Loads/saves visual state of the application.
void loadSize();
void saveSize();
#if defined(USE_WEBENGINE)
AdBlockIcon* adblockIcon() const {
return m_adblockIcon;
}
#endif
public slots:
// Displays window on top or switches its visibility.
void display();
// Switches visibility of main window.
void switchVisibility(bool force_hide = false);
// Turns on/off fullscreen mode
void switchFullscreenMode();
private slots:
void updateAddItemMenu();
void updateRecycleBinMenu();
void updateAccountsMenu();
void updateMessageButtonsAvailability();
void updateFeedButtonsAvailability();
void onFeedUpdatesStarted();
void onFeedUpdatesProgress(const Feed* feed, int current, int total);
void onFeedUpdatesFinished(const FeedDownloadResults& results);
// Displays various dialogs.
void backupDatabaseSettings();
void restoreDatabaseSettings();
void showSettings();
void showAbout();
void showUpdates();
void showWiki();
void showAddAccountDialog();
void showDbCleanupAssistant();
void reportABug();
void donate();
private:
// Event handler reimplementations.
void changeEvent(QEvent* event);
// Creates all needed menus and sets them up.
void prepareMenus();
// Creates needed connections for this window.
void createConnections();
// Sets up proper icons for this widget.
void setupIcons();
#if defined(USE_WEBENGINE)
AdBlockIcon* m_adblockIcon;
QAction* m_adblockIconAction;
#endif
QScopedPointer<Ui::FormMain> m_ui;
QMenu* m_trayMenu;
StatusBar* m_statusBar;
};
#endif // FORMMAIN_H

View File

@ -1,139 +1,136 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formrestoredatabasesettings.h"
#include "gui/messagebox.h"
#include "gui/dialogs/formmain.h"
#include "miscellaneous/iconfactory.h"
#include "exceptions/applicationexception.h"
#include "QFileDialog"
FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget *parent)
: QDialog(parent), m_ui(new Ui::FormRestoreDatabaseSettings), m_shouldRestart(false) {
m_ui->setupUi(this);
m_btnRestart = m_ui->m_buttonBox->addButton(tr("Restart"), QDialogButtonBox::ActionRole);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Warning, tr("No operation executed yet."), tr("No operation executed yet."));
setWindowIcon(qApp->icons()->fromTheme(QSL("document-import")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
connect(m_btnRestart, &QPushButton::clicked, this, [=]() {
m_shouldRestart = true;
close();
});
connect(m_ui->m_btnSelectFolder, SIGNAL(clicked()), this, SLOT(selectFolder()));
connect(m_ui->m_groupDatabase, SIGNAL(toggled(bool)), this, SLOT(checkOkButton()));
connect(m_ui->m_groupSettings, SIGNAL(toggled(bool)), this, SLOT(checkOkButton()));
connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(performRestoration()));
selectFolder(qApp->getDocumentsFolderPath());
}
FormRestoreDatabaseSettings::~FormRestoreDatabaseSettings() {
qDebug("Destroying FormRestoreDatabaseSettings instance.");
}
void FormRestoreDatabaseSettings::performRestoration() {
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
try {
qApp->restoreDatabaseSettings(m_ui->m_groupDatabase->isChecked(),
m_ui->m_groupSettings->isChecked(),
m_ui->m_listDatabase->currentRow() >= 0 ?
m_ui->m_listDatabase->currentItem()->data(Qt::UserRole).toString() :
QString(),
m_ui->m_listSettings->currentRow() >= 0 ?
m_ui->m_listSettings->currentItem()->data(Qt::UserRole).toString() :
QString());
m_btnRestart->setEnabled(true);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Restoration was initiated. Restart to proceed."),
tr("You need to restart application for restoration process to finish."));
}
catch (const ApplicationException &ex) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(),
tr("Database and/or settings were not copied to restoration directory successully."));
}
}
void FormRestoreDatabaseSettings::checkOkButton() {
m_btnRestart->setEnabled(false);
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!m_ui->m_lblSelectFolder->label()->text().isEmpty() &&
((m_ui->m_groupDatabase->isChecked() &&
m_ui->m_listDatabase->currentRow() >= 0) ||
(m_ui->m_groupSettings->isChecked() &&
m_ui->m_listSettings->currentRow() >= 0)));
}
void FormRestoreDatabaseSettings::selectFolderWithGui() {
selectFolder();
}
void FormRestoreDatabaseSettings::selectFolder(QString folder) {
if (folder.isEmpty()) {
folder = QFileDialog::getExistingDirectory(this, tr("Select source directory"), m_ui->m_lblSelectFolder->label()->text());
}
if (!folder.isEmpty()) {
m_ui->m_lblSelectFolder->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(folder),
tr("Good source directory is specified."));
}
else {
return;
}
const QDir selected_folder(folder);
const QFileInfoList available_databases = selected_folder.entryInfoList(QStringList()
<< QString("*") + BACKUP_SUFFIX_DATABASE ,
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable |
QDir::CaseSensitive | QDir::NoSymLinks,
QDir::Name);
const QFileInfoList available_settings = selected_folder.entryInfoList(QStringList()
<< QString("*") + BACKUP_SUFFIX_SETTINGS ,
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable |
QDir::CaseSensitive | QDir::NoSymLinks,
QDir::Name);
m_ui->m_listDatabase->clear();
m_ui->m_listSettings->clear();
foreach (const QFileInfo &database_file, available_databases) {
QListWidgetItem *database_item = new QListWidgetItem(database_file.fileName(), m_ui->m_listDatabase);
database_item->setData(Qt::UserRole, database_file.absoluteFilePath());
database_item->setToolTip(QDir::toNativeSeparators(database_file.absoluteFilePath()));
}
foreach (const QFileInfo &settings_file, available_settings) {
QListWidgetItem *settings_item = new QListWidgetItem(settings_file.fileName(), m_ui->m_listSettings);
settings_item->setData(Qt::UserRole, settings_file.absoluteFilePath());
settings_item->setToolTip(QDir::toNativeSeparators(settings_file.absoluteFilePath()));
}
if (!available_databases.isEmpty()) {
m_ui->m_listDatabase->setCurrentRow(0);
}
if (!available_settings.isEmpty()) {
m_ui->m_listSettings->setCurrentRow(0);
}
m_ui->m_groupDatabase->setChecked(!available_databases.isEmpty());
m_ui->m_groupSettings->setChecked(!available_settings.isEmpty());
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formrestoredatabasesettings.h"
#include "gui/messagebox.h"
#include "gui/dialogs/formmain.h"
#include "miscellaneous/iconfactory.h"
#include "exceptions/applicationexception.h"
#include "QFileDialog"
FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget* parent)
: QDialog(parent), m_ui(new Ui::FormRestoreDatabaseSettings), m_shouldRestart(false) {
m_ui->setupUi(this);
m_btnRestart = m_ui->m_buttonBox->addButton(tr("Restart"), QDialogButtonBox::ActionRole);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Warning, tr("No operation executed yet."), tr("No operation executed yet."));
setWindowIcon(qApp->icons()->fromTheme(QSL("document-import")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
connect(m_btnRestart, &QPushButton::clicked, this, [ = ]() {
m_shouldRestart = true;
close();
});
connect(m_ui->m_btnSelectFolder, SIGNAL(clicked()), this, SLOT(selectFolder()));
connect(m_ui->m_groupDatabase, SIGNAL(toggled(bool)), this, SLOT(checkOkButton()));
connect(m_ui->m_groupSettings, SIGNAL(toggled(bool)), this, SLOT(checkOkButton()));
connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(performRestoration()));
selectFolder(qApp->getDocumentsFolderPath());
}
FormRestoreDatabaseSettings::~FormRestoreDatabaseSettings() {
qDebug("Destroying FormRestoreDatabaseSettings instance.");
}
void FormRestoreDatabaseSettings::performRestoration() {
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
try {
qApp->restoreDatabaseSettings(m_ui->m_groupDatabase->isChecked(),
m_ui->m_groupSettings->isChecked(),
m_ui->m_listDatabase->currentRow() >= 0 ?
m_ui->m_listDatabase->currentItem()->data(Qt::UserRole).toString() :
QString(),
m_ui->m_listSettings->currentRow() >= 0 ?
m_ui->m_listSettings->currentItem()->data(Qt::UserRole).toString() :
QString());
m_btnRestart->setEnabled(true);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Restoration was initiated. Restart to proceed."),
tr("You need to restart application for restoration process to finish."));
}
catch (const ApplicationException& ex) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(),
tr("Database and/or settings were not copied to restoration directory successully."));
}
}
void FormRestoreDatabaseSettings::checkOkButton() {
m_btnRestart->setEnabled(false);
m_ui->m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!m_ui->m_lblSelectFolder->label()->text().isEmpty() &&
((m_ui->m_groupDatabase->isChecked() &&
m_ui->m_listDatabase->currentRow() >= 0) ||
(m_ui->m_groupSettings->isChecked() &&
m_ui->m_listSettings->currentRow() >= 0)));
}
void FormRestoreDatabaseSettings::selectFolderWithGui() {
selectFolder();
}
void FormRestoreDatabaseSettings::selectFolder(QString folder) {
if (folder.isEmpty()) {
folder = QFileDialog::getExistingDirectory(this, tr("Select source directory"), m_ui->m_lblSelectFolder->label()->text());
}
if (!folder.isEmpty()) {
m_ui->m_lblSelectFolder->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(folder),
tr("Good source directory is specified."));
}
else {
return;
}
const QDir selected_folder(folder);
const QFileInfoList available_databases = selected_folder.entryInfoList(QStringList()
<< QString("*") + BACKUP_SUFFIX_DATABASE,
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable |
QDir::CaseSensitive | QDir::NoSymLinks,
QDir::Name);
const QFileInfoList available_settings = selected_folder.entryInfoList(QStringList()
<< QString("*") + BACKUP_SUFFIX_SETTINGS,
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable |
QDir::CaseSensitive | QDir::NoSymLinks,
QDir::Name);
m_ui->m_listDatabase->clear();
m_ui->m_listSettings->clear();
foreach (const QFileInfo& database_file, available_databases) {
QListWidgetItem* database_item = new QListWidgetItem(database_file.fileName(), m_ui->m_listDatabase);
database_item->setData(Qt::UserRole, database_file.absoluteFilePath());
database_item->setToolTip(QDir::toNativeSeparators(database_file.absoluteFilePath()));
}
foreach (const QFileInfo& settings_file, available_settings) {
QListWidgetItem* settings_item = new QListWidgetItem(settings_file.fileName(), m_ui->m_listSettings);
settings_item->setData(Qt::UserRole, settings_file.absoluteFilePath());
settings_item->setToolTip(QDir::toNativeSeparators(settings_file.absoluteFilePath()));
}
if (!available_databases.isEmpty()) {
m_ui->m_listDatabase->setCurrentRow(0);
}
if (!available_settings.isEmpty()) {
m_ui->m_listSettings->setCurrentRow(0);
}
m_ui->m_groupDatabase->setChecked(!available_databases.isEmpty());
m_ui->m_groupSettings->setChecked(!available_settings.isEmpty());
}

View File

@ -1,51 +1,51 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMRESTOREDATABASESETTINGS_H
#define FORMRESTOREDATABASESETTINGS_H
#include <QDialog>
#include "ui_formrestoredatabasesettings.h"
class FormRestoreDatabaseSettings : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormRestoreDatabaseSettings(QWidget *parent = 0);
virtual ~FormRestoreDatabaseSettings();
bool shouldRestart() const {
return m_shouldRestart;
}
private slots:
void performRestoration();
void checkOkButton();
void selectFolderWithGui();
void selectFolder(QString folder = QString());
private:
QScopedPointer<Ui::FormRestoreDatabaseSettings> m_ui;
QPushButton *m_btnRestart;
bool m_shouldRestart;
};
#endif // FORMRESTOREDATABASESETTINGS_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMRESTOREDATABASESETTINGS_H
#define FORMRESTOREDATABASESETTINGS_H
#include <QDialog>
#include "ui_formrestoredatabasesettings.h"
class FormRestoreDatabaseSettings : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormRestoreDatabaseSettings(QWidget* parent = 0);
virtual ~FormRestoreDatabaseSettings();
bool shouldRestart() const {
return m_shouldRestart;
}
private slots:
void performRestoration();
void checkOkButton();
void selectFolderWithGui();
void selectFolder(QString folder = QString());
private:
QScopedPointer<Ui::FormRestoreDatabaseSettings> m_ui;
QPushButton* m_btnRestart;
bool m_shouldRestart;
};
#endif // FORMRESTOREDATABASESETTINGS_H

View File

@ -1,146 +1,139 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formsettings.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "miscellaneous/settings.h"
#include "miscellaneous/iconfactory.h"
#include "gui/messagebox.h"
#include "gui/settings/settingsbrowsermail.h"
#include "gui/settings/settingsdatabase.h"
#include "gui/settings/settingsdownloads.h"
#include "gui/settings/settingsfeedsmessages.h"
#include "gui/settings/settingsgeneral.h"
#include "gui/settings/settingsgui.h"
#include "gui/settings/settingslocalization.h"
#include "gui/settings/settingsshortcuts.h"
FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_panels(QList<SettingsPanel*>()), m_ui(new Ui::FormSettings), m_settings(qApp->settings()) {
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("emblem-system")));
m_btnApply = m_ui->m_buttonBox->button(QDialogButtonBox::Apply);
m_btnApply->setEnabled(false);
// Establish needed connections.
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormSettings::saveSettings);
connect(m_ui->m_buttonBox, &QDialogButtonBox::rejected, this, &FormSettings::cancelSettings);
connect(m_btnApply, &QPushButton::clicked, this, &FormSettings::applySettings);
addSettingsPanel(new SettingsGeneral(m_settings, this));
addSettingsPanel(new SettingsDatabase(m_settings, this));
addSettingsPanel(new SettingsGui(m_settings, this));
addSettingsPanel(new SettingsLocalization(m_settings, this));
addSettingsPanel(new SettingsShortcuts(m_settings, this));
addSettingsPanel(new SettingsBrowserMail(m_settings, this));
addSettingsPanel(new SettingsDownloads(m_settings, this));
addSettingsPanel(new SettingsFeedsMessages(m_settings, this));
m_ui->m_listSettings->setCurrentRow(0);
}
FormSettings::~FormSettings() {
qDebug("Destroying FormSettings distance.");
}
void FormSettings::saveSettings() {
applySettings();
accept();
}
void FormSettings::applySettings() {
// Save all settings.
m_settings->checkSettings();
QStringList panels_for_restart;
foreach (SettingsPanel *panel, m_panels) {
if (panel->isDirty()) {
panel->saveSettings();
}
if (panel->requiresRestart()) {
panels_for_restart.append(panel->title().toLower());
panel->setRequiresRestart(false);
}
}
if (!panels_for_restart.isEmpty()) {
const QStringList changed_settings_description = panels_for_restart.replaceInStrings(QRegExp(QSL("^")), QString::fromUtf8(""));
const QMessageBox::StandardButton clicked_button = MessageBox::show(this,
QMessageBox::Question,
tr("Critical settings were changed"),
tr("Some critical settings were changed and will be applied after the application gets restarted. "
"\n\nYou have to restart manually."),
tr("Do you want to restart now?"),
tr("Changed categories of settings:\n%1.").arg(changed_settings_description .join(QSL(",\n"))),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (clicked_button == QMessageBox::Yes) {
qApp->restart();
}
}
m_btnApply->setEnabled(false);
}
void FormSettings::cancelSettings() {
QStringList changed_panels;
foreach (SettingsPanel *panel, m_panels) {
if (panel->isDirty()) {
changed_panels.append(panel->title().toLower());
}
}
if (changed_panels.isEmpty()) {
reject();
}
else {
const QStringList changed_settings_description = changed_panels.replaceInStrings(QRegExp(QSL("^")), QString::fromUtf8(""));
if (MessageBox::show(this,
QMessageBox::Critical,
tr("Some settings are changed and will be lost"),
tr("Some settings were changed and by cancelling this dialog, you would lose these changes."),
tr("Do you really want to close this dialog without saving any settings?"),
tr("Changed categories of settings:\n%1.").arg(changed_settings_description .join(QSL(",\n"))),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) ==
QMessageBox::Yes) {
reject();
}
}
}
void FormSettings::addSettingsPanel(SettingsPanel *panel) {
m_ui->m_listSettings->addItem(panel->title());
m_panels.append(panel);
m_ui->m_stackedSettings->addWidget(panel);
panel->loadSettings();
connect(panel, &SettingsPanel::settingsChanged, [this]() {
m_btnApply->setEnabled(true);
});
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formsettings.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "miscellaneous/settings.h"
#include "miscellaneous/iconfactory.h"
#include "gui/messagebox.h"
#include "gui/settings/settingsbrowsermail.h"
#include "gui/settings/settingsdatabase.h"
#include "gui/settings/settingsdownloads.h"
#include "gui/settings/settingsfeedsmessages.h"
#include "gui/settings/settingsgeneral.h"
#include "gui/settings/settingsgui.h"
#include "gui/settings/settingslocalization.h"
#include "gui/settings/settingsshortcuts.h"
FormSettings::FormSettings(QWidget* parent) : QDialog(parent), m_panels(QList<SettingsPanel*>()), m_ui(new Ui::FormSettings), m_settings(qApp->settings()) {
m_ui->setupUi(this);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("emblem-system")));
m_btnApply = m_ui->m_buttonBox->button(QDialogButtonBox::Apply);
m_btnApply->setEnabled(false);
// Establish needed connections.
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormSettings::saveSettings);
connect(m_ui->m_buttonBox, &QDialogButtonBox::rejected, this, &FormSettings::cancelSettings);
connect(m_btnApply, &QPushButton::clicked, this, &FormSettings::applySettings);
addSettingsPanel(new SettingsGeneral(m_settings, this));
addSettingsPanel(new SettingsDatabase(m_settings, this));
addSettingsPanel(new SettingsGui(m_settings, this));
addSettingsPanel(new SettingsLocalization(m_settings, this));
addSettingsPanel(new SettingsShortcuts(m_settings, this));
addSettingsPanel(new SettingsBrowserMail(m_settings, this));
addSettingsPanel(new SettingsDownloads(m_settings, this));
addSettingsPanel(new SettingsFeedsMessages(m_settings, this));
m_ui->m_listSettings->setCurrentRow(0);
}
FormSettings::~FormSettings() {
qDebug("Destroying FormSettings distance.");
}
void FormSettings::saveSettings() {
applySettings();
accept();
}
void FormSettings::applySettings() {
// Save all settings.
m_settings->checkSettings();
QStringList panels_for_restart;
foreach (SettingsPanel* panel, m_panels) {
if (panel->isDirty()) {
panel->saveSettings();
}
if (panel->requiresRestart()) {
panels_for_restart.append(panel->title().toLower());
panel->setRequiresRestart(false);
}
}
if (!panels_for_restart.isEmpty()) {
const QStringList changed_settings_description = panels_for_restart.replaceInStrings(QRegExp(QSL("^")), QString::fromUtf8(""));
const QMessageBox::StandardButton clicked_button = MessageBox::show(this,
QMessageBox::Question,
tr("Critical settings were changed"),
tr("Some critical settings were changed and will be applied after the application gets restarted. "
"\n\nYou have to restart manually."),
tr("Do you want to restart now?"),
tr("Changed categories of settings:\n%1.").arg(changed_settings_description .join(QSL(",\n"))),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (clicked_button == QMessageBox::Yes) {
qApp->restart();
}
}
m_btnApply->setEnabled(false);
}
void FormSettings::cancelSettings() {
QStringList changed_panels;
foreach (SettingsPanel* panel, m_panels) {
if (panel->isDirty()) {
changed_panels.append(panel->title().toLower());
}
}
if (changed_panels.isEmpty()) {
reject();
}
else {
const QStringList changed_settings_description = changed_panels.replaceInStrings(QRegExp(QSL("^")), QString::fromUtf8(""));
if (MessageBox::show(this,
QMessageBox::Critical,
tr("Some settings are changed and will be lost"),
tr("Some settings were changed and by cancelling this dialog, you would lose these changes."),
tr("Do you really want to close this dialog without saving any settings?"),
tr("Changed categories of settings:\n%1.").arg(changed_settings_description .join(QSL(",\n"))),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) ==
QMessageBox::Yes) {
reject();
}
}
}
void FormSettings::addSettingsPanel(SettingsPanel* panel) {
m_ui->m_listSettings->addItem(panel->title());
m_panels.append(panel);
m_ui->m_stackedSettings->addWidget(panel);
panel->loadSettings();
connect(panel, &SettingsPanel::settingsChanged, [this]() {
m_btnApply->setEnabled(true);
});
}

View File

@ -1,52 +1,52 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMSETTINGS_H
#define FORMSETTINGS_H
#include <QDialog>
#include "ui_formsettings.h"
class Settings;
class SettingsPanel;
class FormSettings : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormSettings(QWidget *parent = 0);
virtual ~FormSettings();
private slots:
// Saves settings into global configuration.
void saveSettings();
void applySettings();
void cancelSettings();
private:
void addSettingsPanel(SettingsPanel *panel);
QList<SettingsPanel*> m_panels;
QScopedPointer<Ui::FormSettings> m_ui;
QPushButton *m_btnApply;
Settings *m_settings;
};
#endif // FORMSETTINGS_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMSETTINGS_H
#define FORMSETTINGS_H
#include <QDialog>
#include "ui_formsettings.h"
class Settings;
class SettingsPanel;
class FormSettings : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormSettings(QWidget* parent = 0);
virtual ~FormSettings();
private slots:
// Saves settings into global configuration.
void saveSettings();
void applySettings();
void cancelSettings();
private:
void addSettingsPanel(SettingsPanel* panel);
QList<SettingsPanel*> m_panels;
QScopedPointer<Ui::FormSettings> m_ui;
QPushButton* m_btnApply;
Settings* m_settings;
};
#endif // FORMSETTINGS_H

View File

@ -1,259 +1,259 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formupdate.h"
#include "definitions/definitions.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/iofactory.h"
#include "network-web/networkfactory.h"
#include "network-web/webfactory.h"
#include "network-web/downloader.h"
#include "gui/messagebox.h"
#include <QNetworkReply>
#include <QProcess>
#if defined(Q_OS_WIN)
#include <windows.h>
#endif
FormUpdate::FormUpdate(QWidget *parent)
: QDialog(parent), m_downloader(nullptr), m_readyToInstall(false), m_ui(new Ui::FormUpdate), m_lastDownloadedBytes(0) {
m_ui->setupUi(this);
m_ui->m_lblCurrentRelease->setText(APP_VERSION);
m_ui->m_tabInfo->removeTab(1);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about")));
if (isSelfUpdateSupported()) {
m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Download selected update"), QDialogButtonBox::ActionRole);
m_btnUpdate->setToolTip(tr("Download new installation files."));
}
else {
m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Go to application website"), QDialogButtonBox::ActionRole);
m_btnUpdate->setToolTip(tr("Go to application website to get update packages manually."));
}
m_btnUpdate->setVisible(false);
connect(m_btnUpdate, &QPushButton::clicked, this, &FormUpdate::startUpdate);
checkForUpdates();
}
FormUpdate::~FormUpdate() {
}
bool FormUpdate::isSelfUpdateSupported() const {
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
return true;
#else
return false;
#endif
}
void FormUpdate::checkForUpdates() {
const QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> update = qApp->system()->checkForUpdates();
if (update.second != QNetworkReply::NoError) {
m_updateInfo = UpdateInfo();
m_ui->m_tabInfo->setEnabled(false);
//: Unknown release.
m_ui->m_lblAvailableRelease->setText(tr("unknown"));
m_ui->m_txtChanges->clear();
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Error,
tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)),
tr("List with updates was not\ndownloaded successfully."));
}
else {
const bool self_update_supported = isSelfUpdateSupported();
m_updateInfo = update.first.at(0);
m_ui->m_tabInfo->setEnabled(true);
m_ui->m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion);
m_ui->m_txtChanges->setText(m_updateInfo.m_changes);
if (SystemFactory::isVersionNewer(m_updateInfo.m_availableVersion, APP_VERSION)) {
m_btnUpdate->setVisible(true);
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok,
tr("New release available."),
tr("This is new version which can be\ndownloaded."));
if (self_update_supported) {
loadAvailableFiles();
}
}
else {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Warning,
tr("No new release available."),
tr("This release is not newer than\ncurrently installed one."));
}
}
}
void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) {
if (bytes_received - m_lastDownloadedBytes > 500000 || m_lastDownloadedBytes == 0) {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Information,
tr("Downloaded %1% (update size is %2 kB).").arg(QString::number(bytes_total == 0 ? 0 : (bytes_received * 100.0) / bytes_total,
'f',
2),
QString::number(bytes_total / 1000,
'f',
2)),
tr("Downloading update..."));
m_ui->m_lblStatus->repaint();
m_lastDownloadedBytes = bytes_received;
}
}
void FormUpdate::saveUpdateFile(const QByteArray &file_contents) {
const QString url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString();
const QString temp_directory = qApp->getTempFolderPath();
if (!temp_directory.isEmpty()) {
const QString output_file_name = url_file.mid(url_file.lastIndexOf('/') + 1);
QFile output_file(temp_directory + QDir::separator() + output_file_name);
if (output_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qDebug("Storing update file to temporary location '%s'.",
qPrintable(QDir::toNativeSeparators(output_file.fileName())));
output_file.write(file_contents);
output_file.flush();
output_file.close();
qDebug("Update file contents was successfuly saved.");
m_updateFilePath = output_file.fileName();
m_readyToInstall = true;
}
else {
qDebug("Cannot save downloaded update file because target temporary file '%s' cannot be "
"opened for writing.", qPrintable(output_file_name));
}
}
else {
qDebug("Cannot save downloaded update file because no TEMP directory is available.");
}
}
void FormUpdate::loadAvailableFiles() {
m_ui->m_listFiles->clear();
foreach (const UpdateUrl &url, m_updateInfo.m_urls) {
QListWidgetItem *item = new QListWidgetItem(url.m_name + tr(" (size ") + url.m_size + QSL(")"));
item->setData(Qt::UserRole, url.m_fileUrl);
item->setToolTip(url.m_fileUrl);
m_ui->m_listFiles->addItem(item);
}
if (m_ui->m_listFiles->count() > 0) {
m_ui->m_listFiles->setCurrentRow(0);
}
else {
m_btnUpdate->setEnabled(false);
}
m_ui->m_tabInfo->addTab(m_ui->tabFiles, tr("Available update files"));
m_ui->m_tabInfo->setCurrentIndex(1);
}
void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, QByteArray contents) {
qDebug("Download of application update file was completed with code '%d'.", status);
switch (status) {
case QNetworkReply::NoError:
saveUpdateFile(contents);
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok, tr("Downloaded successfully"), tr("Package was downloaded successfully.\nYou can install it now."));
m_btnUpdate->setText(tr("Install"));
m_btnUpdate->setEnabled(true);
break;
default:
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Error, tr("Error occured"), tr("Error occured during downloading of the package."));
m_btnUpdate->setText(tr("Error occured"));
break;
}
}
void FormUpdate::startUpdate() {
QString url_file;
const bool update_for_this_system = isSelfUpdateSupported();
if (update_for_this_system && m_ui->m_listFiles->currentItem() != nullptr) {
url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString();
m_ui->m_listFiles->setEnabled(false);
}
else {
url_file = APP_URL;
}
if (m_readyToInstall) {
close();
qDebug("Preparing to launch external installer '%s'.", qPrintable(QDir::toNativeSeparators(m_updateFilePath)));
#if defined(Q_OS_WIN)
HINSTANCE exec_result = ShellExecute(nullptr,
nullptr,
reinterpret_cast<const WCHAR*>(QDir::toNativeSeparators(m_updateFilePath).utf16()),
nullptr,
nullptr,
SW_NORMAL);
if (((int)exec_result) <= 32) {
qDebug("External updater was not launched due to error.");
qApp->showGuiMessage(tr("Cannot update application"),
tr("Cannot launch external updater. Update application manually."),
QSystemTrayIcon::Warning, this);
}
else {
qApp->quit();
}
#endif
}
else if (update_for_this_system) {
// Nothing is downloaded yet, but update for this system
// is available and self-update feature is present.
if (m_downloader == nullptr) {
// Initialie downloader.
m_downloader = new Downloader(this);
connect(m_downloader, &Downloader::progress, this, &FormUpdate::updateProgress);
connect(m_downloader, &Downloader::completed, this, &FormUpdate::updateCompleted);
updateProgress(0, 100);
}
m_btnUpdate->setText(tr("Downloading update..."));
m_btnUpdate->setEnabled(false);
m_downloader->downloadFile(url_file);
}
else {
// Self-update and package are not available.
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {
qApp->showGuiMessage(tr("Cannot update application"),
tr("Cannot navigate to installation file. Check new installation downloads manually on project website."),
QSystemTrayIcon::Warning,
this, true);
}
}
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/dialogs/formupdate.h"
#include "definitions/definitions.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/iofactory.h"
#include "network-web/networkfactory.h"
#include "network-web/webfactory.h"
#include "network-web/downloader.h"
#include "gui/messagebox.h"
#include <QNetworkReply>
#include <QProcess>
#if defined(Q_OS_WIN)
#include <windows.h>
#endif
FormUpdate::FormUpdate(QWidget* parent)
: QDialog(parent), m_downloader(nullptr), m_readyToInstall(false), m_ui(new Ui::FormUpdate), m_lastDownloadedBytes(0) {
m_ui->setupUi(this);
m_ui->m_lblCurrentRelease->setText(APP_VERSION);
m_ui->m_tabInfo->removeTab(1);
// Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about")));
if (isSelfUpdateSupported()) {
m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Download selected update"), QDialogButtonBox::ActionRole);
m_btnUpdate->setToolTip(tr("Download new installation files."));
}
else {
m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Go to application website"), QDialogButtonBox::ActionRole);
m_btnUpdate->setToolTip(tr("Go to application website to get update packages manually."));
}
m_btnUpdate->setVisible(false);
connect(m_btnUpdate, &QPushButton::clicked, this, &FormUpdate::startUpdate);
checkForUpdates();
}
FormUpdate::~FormUpdate() {
}
bool FormUpdate::isSelfUpdateSupported() const {
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
return true;
#else
return false;
#endif
}
void FormUpdate::checkForUpdates() {
const QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> update = qApp->system()->checkForUpdates();
if (update.second != QNetworkReply::NoError) {
m_updateInfo = UpdateInfo();
m_ui->m_tabInfo->setEnabled(false);
//: Unknown release.
m_ui->m_lblAvailableRelease->setText(tr("unknown"));
m_ui->m_txtChanges->clear();
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Error,
tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)),
tr("List with updates was not\ndownloaded successfully."));
}
else {
const bool self_update_supported = isSelfUpdateSupported();
m_updateInfo = update.first.at(0);
m_ui->m_tabInfo->setEnabled(true);
m_ui->m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion);
m_ui->m_txtChanges->setText(m_updateInfo.m_changes);
if (SystemFactory::isVersionNewer(m_updateInfo.m_availableVersion, APP_VERSION)) {
m_btnUpdate->setVisible(true);
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok,
tr("New release available."),
tr("This is new version which can be\ndownloaded."));
if (self_update_supported) {
loadAvailableFiles();
}
}
else {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Warning,
tr("No new release available."),
tr("This release is not newer than\ncurrently installed one."));
}
}
}
void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) {
if (bytes_received - m_lastDownloadedBytes > 500000 || m_lastDownloadedBytes == 0) {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Information,
tr("Downloaded %1% (update size is %2 kB).").arg(QString::number(bytes_total == 0 ? 0 : (bytes_received * 100.0) / bytes_total,
'f',
2),
QString::number(bytes_total / 1000,
'f',
2)),
tr("Downloading update..."));
m_ui->m_lblStatus->repaint();
m_lastDownloadedBytes = bytes_received;
}
}
void FormUpdate::saveUpdateFile(const QByteArray& file_contents) {
const QString url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString();
const QString temp_directory = qApp->getTempFolderPath();
if (!temp_directory.isEmpty()) {
const QString output_file_name = url_file.mid(url_file.lastIndexOf('/') + 1);
QFile output_file(temp_directory + QDir::separator() + output_file_name);
if (output_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qDebug("Storing update file to temporary location '%s'.",
qPrintable(QDir::toNativeSeparators(output_file.fileName())));
output_file.write(file_contents);
output_file.flush();
output_file.close();
qDebug("Update file contents was successfuly saved.");
m_updateFilePath = output_file.fileName();
m_readyToInstall = true;
}
else {
qDebug("Cannot save downloaded update file because target temporary file '%s' cannot be "
"opened for writing.", qPrintable(output_file_name));
}
}
else {
qDebug("Cannot save downloaded update file because no TEMP directory is available.");
}
}
void FormUpdate::loadAvailableFiles() {
m_ui->m_listFiles->clear();
foreach (const UpdateUrl& url, m_updateInfo.m_urls) {
QListWidgetItem* item = new QListWidgetItem(url.m_name + tr(" (size ") + url.m_size + QSL(")"));
item->setData(Qt::UserRole, url.m_fileUrl);
item->setToolTip(url.m_fileUrl);
m_ui->m_listFiles->addItem(item);
}
if (m_ui->m_listFiles->count() > 0) {
m_ui->m_listFiles->setCurrentRow(0);
}
else {
m_btnUpdate->setEnabled(false);
}
m_ui->m_tabInfo->addTab(m_ui->tabFiles, tr("Available update files"));
m_ui->m_tabInfo->setCurrentIndex(1);
}
void FormUpdate::updateCompleted(QNetworkReply::NetworkError status, QByteArray contents) {
qDebug("Download of application update file was completed with code '%d'.", status);
switch (status) {
case QNetworkReply::NoError:
saveUpdateFile(contents);
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Ok, tr("Downloaded successfully"), tr("Package was downloaded successfully.\nYou can install it now."));
m_btnUpdate->setText(tr("Install"));
m_btnUpdate->setEnabled(true);
break;
default:
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Error, tr("Error occured"), tr("Error occured during downloading of the package."));
m_btnUpdate->setText(tr("Error occured"));
break;
}
}
void FormUpdate::startUpdate() {
QString url_file;
const bool update_for_this_system = isSelfUpdateSupported();
if (update_for_this_system && m_ui->m_listFiles->currentItem() != nullptr) {
url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString();
m_ui->m_listFiles->setEnabled(false);
}
else {
url_file = APP_URL;
}
if (m_readyToInstall) {
close();
qDebug("Preparing to launch external installer '%s'.", qPrintable(QDir::toNativeSeparators(m_updateFilePath)));
#if defined(Q_OS_WIN)
HINSTANCE exec_result = ShellExecute(nullptr,
nullptr,
reinterpret_cast<const WCHAR*>(QDir::toNativeSeparators(m_updateFilePath).utf16()),
nullptr,
nullptr,
SW_NORMAL);
if (((int)exec_result) <= 32) {
qDebug("External updater was not launched due to error.");
qApp->showGuiMessage(tr("Cannot update application"),
tr("Cannot launch external updater. Update application manually."),
QSystemTrayIcon::Warning, this);
}
else {
qApp->quit();
}
#endif
}
else if (update_for_this_system) {
// Nothing is downloaded yet, but update for this system
// is available and self-update feature is present.
if (m_downloader == nullptr) {
// Initialie downloader.
m_downloader = new Downloader(this);
connect(m_downloader, &Downloader::progress, this, &FormUpdate::updateProgress);
connect(m_downloader, &Downloader::completed, this, &FormUpdate::updateCompleted);
updateProgress(0, 100);
}
m_btnUpdate->setText(tr("Downloading update..."));
m_btnUpdate->setEnabled(false);
m_downloader->downloadFile(url_file);
}
else {
// Self-update and package are not available.
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {
qApp->showGuiMessage(tr("Cannot update application"),
tr("Cannot navigate to installation file. Check new installation downloads manually on project website."),
QSystemTrayIcon::Warning,
this, true);
}
}
}

View File

@ -1,66 +1,66 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMUPDATE_H
#define FORMUPDATE_H
#include <QDialog>
#include "ui_formupdate.h"
#include "miscellaneous/systemfactory.h"
#include <QPushButton>
#include <QNetworkReply>
class Downloader;
class FormUpdate : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormUpdate(QWidget *parent = 0);
virtual ~FormUpdate();
// Returns true if application can self-update
// on current platform.
bool isSelfUpdateSupported() const;
private slots:
// Check for updates and interprets the results.
void checkForUpdates();
void startUpdate();
void updateProgress(qint64 bytes_received, qint64 bytes_total);
void updateCompleted(QNetworkReply::NetworkError status, QByteArray contents);
void saveUpdateFile(const QByteArray &file_contents);
private:
void loadAvailableFiles();
Downloader *m_downloader;
bool m_readyToInstall;
QString m_updateFilePath;
QScopedPointer<Ui::FormUpdate> m_ui;
UpdateInfo m_updateInfo;
QPushButton *m_btnUpdate;
qint64 m_lastDownloadedBytes;
};
#endif // FORMUPDATE_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FORMUPDATE_H
#define FORMUPDATE_H
#include <QDialog>
#include "ui_formupdate.h"
#include "miscellaneous/systemfactory.h"
#include <QPushButton>
#include <QNetworkReply>
class Downloader;
class FormUpdate : public QDialog {
Q_OBJECT
public:
// Constructors and destructors.
explicit FormUpdate(QWidget* parent = 0);
virtual ~FormUpdate();
// Returns true if application can self-update
// on current platform.
bool isSelfUpdateSupported() const;
private slots:
// Check for updates and interprets the results.
void checkForUpdates();
void startUpdate();
void updateProgress(qint64 bytes_received, qint64 bytes_total);
void updateCompleted(QNetworkReply::NetworkError status, QByteArray contents);
void saveUpdateFile(const QByteArray& file_contents);
private:
void loadAvailableFiles();
Downloader* m_downloader;
bool m_readyToInstall;
QString m_updateFilePath;
QScopedPointer<Ui::FormUpdate> m_ui;
UpdateInfo m_updateInfo;
QPushButton* m_btnUpdate;
qint64 m_lastDownloadedBytes;
};
#endif // FORMUPDATE_H

View File

@ -1,93 +1,93 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/discoverfeedsbutton.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/feedreader.h"
#include "gui/dialogs/formmain.h"
#include "gui/tabwidget.h"
#include "gui/feedmessageviewer.h"
#include "gui/feedsview.h"
#include "core/feedsmodel.h"
#include "services/abstract/serviceroot.h"
#include <QVariant>
DiscoverFeedsButton::DiscoverFeedsButton(QWidget *parent) : QToolButton(parent), m_addresses(QStringList()) {
setEnabled(false);
setIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
setPopupMode(QToolButton::InstantPopup);
}
DiscoverFeedsButton::~DiscoverFeedsButton() {
}
void DiscoverFeedsButton::clearFeedAddresses() {
setFeedAddresses(QStringList());
}
void DiscoverFeedsButton::setFeedAddresses(const QStringList &addresses) {
setEnabled(!addresses.isEmpty());
setToolTip(addresses.isEmpty() ?
tr("This website does not contain any feeds.") :
tr("Click me to add feeds from this website.\nThis website contains %n feed(s).", 0, addresses.size()));
if (menu() == nullptr) {
// Initialize the menu.
setMenu(new QMenu(this));
connect(menu(), &QMenu::triggered, this, &DiscoverFeedsButton::linkTriggered);
connect(menu(), &QMenu::aboutToShow, this, &DiscoverFeedsButton::fillMenu);
}
menu()->hide();
m_addresses = addresses;
}
void DiscoverFeedsButton::linkTriggered(QAction *action) {
const QString url = action->property("url").toString();
ServiceRoot *root = static_cast<ServiceRoot*>(action->property("root").value<void*>());
if (root->supportsFeedAdding()) {
root->addNewFeed(url);
}
else {
qApp->showGuiMessage(tr("Not supported"),
tr("Given account does not support adding feeds."),
QSystemTrayIcon::Warning,
qApp->mainFormWidget(), true);
}
}
void DiscoverFeedsButton::fillMenu() {
menu()->clear();
foreach (const ServiceRoot *root, qApp->feedReader()->feedsModel()->serviceRoots()) {
QMenu *root_menu = menu()->addMenu(root->icon(), root->title());
foreach (const QString &url, m_addresses) {
if (root->supportsFeedAdding()) {
QAction *url_action = root_menu->addAction(root->icon(), url);
url_action->setProperty("url", url);
url_action->setProperty("root", QVariant::fromValue((void*) root));
}
}
}
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/discoverfeedsbutton.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/feedreader.h"
#include "gui/dialogs/formmain.h"
#include "gui/tabwidget.h"
#include "gui/feedmessageviewer.h"
#include "gui/feedsview.h"
#include "core/feedsmodel.h"
#include "services/abstract/serviceroot.h"
#include <QVariant>
DiscoverFeedsButton::DiscoverFeedsButton(QWidget* parent) : QToolButton(parent), m_addresses(QStringList()) {
setEnabled(false);
setIcon(qApp->icons()->fromTheme(QSL("application-rss+xml")));
setPopupMode(QToolButton::InstantPopup);
}
DiscoverFeedsButton::~DiscoverFeedsButton() {
}
void DiscoverFeedsButton::clearFeedAddresses() {
setFeedAddresses(QStringList());
}
void DiscoverFeedsButton::setFeedAddresses(const QStringList& addresses) {
setEnabled(!addresses.isEmpty());
setToolTip(addresses.isEmpty() ?
tr("This website does not contain any feeds.") :
tr("Click me to add feeds from this website.\nThis website contains %n feed(s).", 0, addresses.size()));
if (menu() == nullptr) {
// Initialize the menu.
setMenu(new QMenu(this));
connect(menu(), &QMenu::triggered, this, &DiscoverFeedsButton::linkTriggered);
connect(menu(), &QMenu::aboutToShow, this, &DiscoverFeedsButton::fillMenu);
}
menu()->hide();
m_addresses = addresses;
}
void DiscoverFeedsButton::linkTriggered(QAction* action) {
const QString url = action->property("url").toString();
ServiceRoot* root = static_cast<ServiceRoot*>(action->property("root").value<void*>());
if (root->supportsFeedAdding()) {
root->addNewFeed(url);
}
else {
qApp->showGuiMessage(tr("Not supported"),
tr("Given account does not support adding feeds."),
QSystemTrayIcon::Warning,
qApp->mainFormWidget(), true);
}
}
void DiscoverFeedsButton::fillMenu() {
menu()->clear();
foreach (const ServiceRoot* root, qApp->feedReader()->feedsModel()->serviceRoots()) {
QMenu* root_menu = menu()->addMenu(root->icon(), root->title());
foreach (const QString& url, m_addresses) {
if (root->supportsFeedAdding()) {
QAction* url_action = root_menu->addAction(root->icon(), url);
url_action->setProperty("url", url);
url_action->setProperty("root", QVariant::fromValue((void*) root));
}
}
}
}

View File

@ -1,45 +1,45 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 DISCOVERFEEDSBUTTON_H
#define DISCOVERFEEDSBUTTON_H
#include <QToolButton>
class DiscoverFeedsButton : public QToolButton {
Q_OBJECT
public:
// Constructors.
explicit DiscoverFeedsButton(QWidget *parent = 0);
virtual ~DiscoverFeedsButton();
// Feed addresses manipulators.
void clearFeedAddresses();
void setFeedAddresses(const QStringList &addresses);
private slots:
// User chose any of addresses.
void linkTriggered(QAction *action);
void fillMenu();
private:
QStringList m_addresses;
};
#endif // DISCOVERFEEDSBUTTON_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 DISCOVERFEEDSBUTTON_H
#define DISCOVERFEEDSBUTTON_H
#include <QToolButton>
class DiscoverFeedsButton : public QToolButton {
Q_OBJECT
public:
// Constructors.
explicit DiscoverFeedsButton(QWidget* parent = 0);
virtual ~DiscoverFeedsButton();
// Feed addresses manipulators.
void clearFeedAddresses();
void setFeedAddresses(const QStringList& addresses);
private slots:
// User chose any of addresses.
void linkTriggered(QAction* action);
void fillMenu();
private:
QStringList m_addresses;
};
#endif // DISCOVERFEEDSBUTTON_H

View File

@ -20,49 +20,50 @@
#include <QKeyEvent>
EditTableView::EditTableView(QWidget *parent) : QTableView(parent) {
EditTableView::EditTableView(QWidget* parent) : QTableView(parent) {
}
void EditTableView::keyPressEvent(QKeyEvent *event) {
if (model() && event->key() == Qt::Key_Delete) {
removeSelected();
event->accept();
}
else {
QAbstractItemView::keyPressEvent(event);
}
void EditTableView::keyPressEvent(QKeyEvent* event) {
if (model() && event->key() == Qt::Key_Delete) {
removeSelected();
event->accept();
}
else {
QAbstractItemView::keyPressEvent(event);
}
}
void EditTableView::removeSelected() {
if (!model() || !selectionModel() || !selectionModel()->hasSelection()) {
return;
}
if (!model() || !selectionModel() || !selectionModel()->hasSelection()) {
return;
}
const QModelIndexList selected_rows = selectionModel()->selectedRows();
const QModelIndexList selected_rows = selectionModel()->selectedRows();
if (selected_rows.isEmpty()) {
return;
}
if (selected_rows.isEmpty()) {
return;
}
const int new_selected_row = selected_rows.at(0).row();
const int new_selected_row = selected_rows.at(0).row();
for (int i = selected_rows.count() - 1; i >= 0; i--) {
QModelIndex idx = selected_rows.at(i);
model()->removeRow(idx.row(), rootIndex());
}
for (int i = selected_rows.count() - 1; i >= 0; i--) {
QModelIndex idx = selected_rows.at(i);
model()->removeRow(idx.row(), rootIndex());
}
QModelIndex new_selected_index = model()->index(new_selected_row, 0, rootIndex());
QModelIndex new_selected_index = model()->index(new_selected_row, 0, rootIndex());
if (!new_selected_index.isValid()) {
new_selected_index = model()->index(new_selected_row - 1, 0, rootIndex());
}
if (!new_selected_index.isValid()) {
new_selected_index = model()->index(new_selected_row - 1, 0, rootIndex());
}
selectionModel()->select(new_selected_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
setCurrentIndex(new_selected_index);
selectionModel()->select(new_selected_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
setCurrentIndex(new_selected_index);
}
void EditTableView::removeAll() {
if (model() != nullptr) {
model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
}
if (model() != nullptr) {
model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
}
}

View File

@ -22,17 +22,17 @@
class EditTableView : public QTableView {
Q_OBJECT
Q_OBJECT
public:
explicit EditTableView(QWidget *parent = 0);
public:
explicit EditTableView(QWidget* parent = 0);
public slots:
void removeSelected();
void removeAll();
public slots:
void removeSelected();
void removeAll();
private:
void keyPressEvent(QKeyEvent *event);
private:
void keyPressEvent(QKeyEvent* event);
};
#endif // EDITTABLEVIEW_H

View File

@ -63,240 +63,220 @@
#include <QPointer>
FeedMessageViewer::FeedMessageViewer(QWidget *parent)
: TabContent(parent),
m_toolBarsEnabled(true),
m_listHeadersEnabled(true),
m_toolBarFeeds(new FeedsToolBar(tr("Toolbar for feeds"), this)),
m_toolBarMessages(new MessagesToolBar(tr("Toolbar for messages"), this)),
m_messagesView(new MessagesView(this)),
m_feedsView(new FeedsView(this)),
FeedMessageViewer::FeedMessageViewer(QWidget* parent)
: TabContent(parent),
m_toolBarsEnabled(true),
m_listHeadersEnabled(true),
m_toolBarFeeds(new FeedsToolBar(tr("Toolbar for feeds"), this)),
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)) {
m_messagesBrowser(new WebBrowser(this)) {
#else
m_messagesBrowser(new MessagePreviewer(this)) {
m_messagesBrowser(new MessagePreviewer(this)) {
#endif
initialize();
initializeViews();
loadMessageViewerFonts();
createConnections();
initialize();
initializeViews();
loadMessageViewerFonts();
createConnections();
}
FeedMessageViewer::~FeedMessageViewer() {
qDebug("Destroying FeedMessageViewer instance.");
qDebug("Destroying FeedMessageViewer instance.");
}
#if defined(USE_WEBENGINE)
WebBrowser *FeedMessageViewer::webBrowser() const {
return m_messagesBrowser;
WebBrowser* FeedMessageViewer::webBrowser() const {
return m_messagesBrowser;
}
#endif
FeedsView *FeedMessageViewer::feedsView() const {
return m_feedsView;
FeedsView* FeedMessageViewer::feedsView() const {
return m_feedsView;
}
MessagesView *FeedMessageViewer::messagesView() const {
return m_messagesView;
MessagesView* FeedMessageViewer::messagesView() const {
return m_messagesView;
}
MessagesToolBar *FeedMessageViewer::messagesToolBar() const {
return m_toolBarMessages;
MessagesToolBar* FeedMessageViewer::messagesToolBar() const {
return m_toolBarMessages;
}
FeedsToolBar *FeedMessageViewer::feedsToolBar() const {
return m_toolBarFeeds;
FeedsToolBar* FeedMessageViewer::feedsToolBar() const {
return m_toolBarFeeds;
}
void FeedMessageViewer::saveSize() {
Settings *settings = qApp->settings();
m_feedsView->saveAllExpandStates();
// Store offsets of splitters.
settings->setValue(GROUP(GUI), GUI::SplitterFeeds, QString(m_feedSplitter->saveState().toBase64()));
settings->setValue(GROUP(GUI), GUI::SplitterMessages, QString(m_messageSplitter->saveState().toBase64()));
settings->setValue(GROUP(GUI), GUI::MessageViewState, QString(m_messagesView->header()->saveState().toBase64()));
// Store "visibility" of toolbars and list headers.
settings->setValue(GROUP(GUI), GUI::ToolbarsVisible, m_toolBarsEnabled);
settings->setValue(GROUP(GUI), GUI::ListHeadersVisible, m_listHeadersEnabled);
Settings* settings = qApp->settings();
m_feedsView->saveAllExpandStates();
// Store offsets of splitters.
settings->setValue(GROUP(GUI), GUI::SplitterFeeds, QString(m_feedSplitter->saveState().toBase64()));
settings->setValue(GROUP(GUI), GUI::SplitterMessages, QString(m_messageSplitter->saveState().toBase64()));
settings->setValue(GROUP(GUI), GUI::MessageViewState, QString(m_messagesView->header()->saveState().toBase64()));
// Store "visibility" of toolbars and list headers.
settings->setValue(GROUP(GUI), GUI::ToolbarsVisible, m_toolBarsEnabled);
settings->setValue(GROUP(GUI), GUI::ListHeadersVisible, m_listHeadersEnabled);
}
void FeedMessageViewer::loadSize() {
const Settings *settings = qApp->settings();
// Restore offsets of splitters.
m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::SplitterFeeds)).toString().toLocal8Bit()));
m_messageSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::SplitterMessages)).toString().toLocal8Bit()));
m_messagesView->header()->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::MessageViewState)).toString().toLocal8Bit()));
const Settings* settings = qApp->settings();
// Restore offsets of splitters.
m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::SplitterFeeds)).toString().toLocal8Bit()));
m_messageSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::SplitterMessages)).toString().toLocal8Bit()));
m_messagesView->header()->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::MessageViewState)).toString().toLocal8Bit()));
}
void FeedMessageViewer::loadMessageViewerFonts() {
m_messagesBrowser->reloadFontSettings();
void FeedMessageViewer::loadMessageViewerFonts() {
m_messagesBrowser->reloadFontSettings();
}
bool FeedMessageViewer::areToolBarsEnabled() const {
return m_toolBarsEnabled;
return m_toolBarsEnabled;
}
bool FeedMessageViewer::areListHeadersEnabled() const {
return m_listHeadersEnabled;
return m_listHeadersEnabled;
}
void FeedMessageViewer::switchMessageSplitterOrientation() {
if (m_messageSplitter->orientation() == Qt::Vertical) {
m_messageSplitter->setOrientation(Qt::Horizontal);
}
else {
m_messageSplitter->setOrientation(Qt::Vertical);
}
if (m_messageSplitter->orientation() == Qt::Vertical) {
m_messageSplitter->setOrientation(Qt::Horizontal);
}
else {
m_messageSplitter->setOrientation(Qt::Vertical);
}
}
void FeedMessageViewer::setToolBarsEnabled(bool enable) {
m_toolBarsEnabled = enable;
m_toolBarFeeds->setVisible(enable);
m_toolBarMessages->setVisible(enable);
m_toolBarsEnabled = enable;
m_toolBarFeeds->setVisible(enable);
m_toolBarMessages->setVisible(enable);
}
void FeedMessageViewer::setListHeadersEnabled(bool enable) {
m_listHeadersEnabled = enable;
m_feedsView->header()->setVisible(enable);
m_messagesView->header()->setVisible(enable);
m_listHeadersEnabled = enable;
m_feedsView->header()->setVisible(enable);
m_messagesView->header()->setVisible(enable);
}
void FeedMessageViewer::switchFeedComponentVisibility() {
QAction *sen = qobject_cast<QAction*>(sender());
QAction* sen = qobject_cast<QAction*>(sender());
if (sen != nullptr) {
m_feedsWidget->setVisible(sen->isChecked());
}
else {
m_feedsWidget->setVisible(!m_feedsWidget->isVisible());
}
if (sen != nullptr) {
m_feedsWidget->setVisible(sen->isChecked());
}
else {
m_feedsWidget->setVisible(!m_feedsWidget->isVisible());
}
}
void FeedMessageViewer::toggleShowOnlyUnreadFeeds() {
const QAction *origin = qobject_cast<QAction*>(sender());
if (origin == nullptr) {
m_feedsView->model()->invalidateReadFeedsFilter(true, false);
}
else {
m_feedsView->model()->invalidateReadFeedsFilter(true, origin->isChecked());
}
const QAction* origin = qobject_cast<QAction*>(sender());
if (origin == nullptr) {
m_feedsView->model()->invalidateReadFeedsFilter(true, false);
}
else {
m_feedsView->model()->invalidateReadFeedsFilter(true, origin->isChecked());
}
}
void FeedMessageViewer::createConnections() {
// Filtering & searching.
connect(m_toolBarMessages, &MessagesToolBar::messageSearchPatternChanged, m_messagesView, &MessagesView::searchMessages);
connect(m_toolBarMessages, &MessagesToolBar::messageFilterChanged, m_messagesView, &MessagesView::filterMessages);
// Filtering & searching.
connect(m_toolBarMessages, &MessagesToolBar::messageSearchPatternChanged, m_messagesView, &MessagesView::searchMessages);
connect(m_toolBarMessages, &MessagesToolBar::messageFilterChanged, m_messagesView, &MessagesView::filterMessages);
#if defined(USE_WEBENGINE)
connect(m_messagesView, &MessagesView::currentMessageRemoved, m_messagesBrowser, &WebBrowser::clear);
connect(m_messagesView, &MessagesView::currentMessageChanged, m_messagesBrowser, &WebBrowser::loadMessage);
connect(m_messagesBrowser, &WebBrowser::markMessageRead,
m_messagesView->sourceModel(), &MessagesModel::setMessageReadById);
connect(m_messagesBrowser, &WebBrowser::markMessageImportant,
m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById);
connect(m_messagesView, &MessagesView::currentMessageRemoved, m_messagesBrowser, &WebBrowser::clear);
connect(m_messagesView, &MessagesView::currentMessageChanged, m_messagesBrowser, &WebBrowser::loadMessage);
connect(m_messagesBrowser, &WebBrowser::markMessageRead,
m_messagesView->sourceModel(), &MessagesModel::setMessageReadById);
connect(m_messagesBrowser, &WebBrowser::markMessageImportant,
m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById);
#else
connect(m_messagesView, &MessagesView::currentMessageRemoved, m_messagesBrowser, &MessagePreviewer::clear);
connect(m_messagesView, &MessagesView::currentMessageChanged, m_messagesBrowser, &MessagePreviewer::loadMessage);
connect(m_messagesBrowser, &MessagePreviewer::markMessageRead,
m_messagesView->sourceModel(), &MessagesModel::setMessageReadById);
connect(m_messagesBrowser, &MessagePreviewer::markMessageImportant,
m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById);
connect(m_messagesView, &MessagesView::currentMessageRemoved, m_messagesBrowser, &MessagePreviewer::clear);
connect(m_messagesView, &MessagesView::currentMessageChanged, m_messagesBrowser, &MessagePreviewer::loadMessage);
connect(m_messagesBrowser, &MessagePreviewer::markMessageRead,
m_messagesView->sourceModel(), &MessagesModel::setMessageReadById);
connect(m_messagesBrowser, &MessagePreviewer::markMessageImportant,
m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById);
#endif
// If user selects feeds, load their messages.
connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem);
// State of many messages is changed, then we need
// to reload selections.
connect(m_feedsView->sourceModel(), &FeedsModel::reloadMessageListRequested,
m_messagesView, &MessagesView::reloadSelections);
// If user selects feeds, load their messages.
connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem);
// State of many messages is changed, then we need
// to reload selections.
connect(m_feedsView->sourceModel(), &FeedsModel::reloadMessageListRequested,
m_messagesView, &MessagesView::reloadSelections);
}
void FeedMessageViewer::initialize() {
// Initialize/populate toolbars.
m_toolBarFeeds->setFloatable(false);
m_toolBarFeeds->setMovable(false);
m_toolBarFeeds->setAllowedAreas(Qt::TopToolBarArea);
m_toolBarMessages->setFloatable(false);
m_toolBarMessages->setMovable(false);
m_toolBarMessages->setAllowedAreas(Qt::TopToolBarArea);
m_toolBarFeeds->loadSavedActions();
m_toolBarMessages->loadSavedActions();
m_messagesBrowser->clear();
// Now refresh visual setup.
refreshVisualProperties();
// Initialize/populate toolbars.
m_toolBarFeeds->setFloatable(false);
m_toolBarFeeds->setMovable(false);
m_toolBarFeeds->setAllowedAreas(Qt::TopToolBarArea);
m_toolBarMessages->setFloatable(false);
m_toolBarMessages->setMovable(false);
m_toolBarMessages->setAllowedAreas(Qt::TopToolBarArea);
m_toolBarFeeds->loadSavedActions();
m_toolBarMessages->loadSavedActions();
m_messagesBrowser->clear();
// Now refresh visual setup.
refreshVisualProperties();
}
void FeedMessageViewer::initializeViews() {
m_feedsWidget = new QWidget(this);
m_messagesWidget = new QWidget(this);
m_feedSplitter = new QSplitter(Qt::Horizontal, this);
m_messageSplitter = new QSplitter(Qt::Vertical, this);
// Instantiate needed components.
QVBoxLayout *central_layout = new QVBoxLayout(this);
QVBoxLayout *feed_layout = new QVBoxLayout(m_feedsWidget);
QVBoxLayout *message_layout = new QVBoxLayout(m_messagesWidget);
// Set layout properties.
central_layout->setMargin(0);
central_layout->setSpacing(0);
feed_layout->setMargin(0);
feed_layout->setSpacing(0);
message_layout->setMargin(0);
message_layout->setSpacing(0);
// Set views.
m_feedsView->setFrameStyle(QFrame::NoFrame);
m_messagesView->setFrameStyle(QFrame::NoFrame);
// Setup message splitter.
m_messageSplitter->setObjectName(QSL("MessageSplitter"));
m_messageSplitter->setHandleWidth(1);
m_messageSplitter->setOpaqueResize(false);
m_messageSplitter->setChildrenCollapsible(false);
m_messageSplitter->addWidget(m_messagesView);
m_messageSplitter->addWidget(m_messagesBrowser);
// Assemble message-related components to single widget.
message_layout->addWidget(m_toolBarMessages);
message_layout->addWidget(m_messageSplitter);
// Assemble feed-related components to another widget.
feed_layout->addWidget(m_toolBarFeeds);
feed_layout->addWidget(m_feedsView);
// Assembler everything together.
m_feedSplitter->setHandleWidth(1);
m_feedSplitter->setOpaqueResize(false);
m_feedSplitter->setChildrenCollapsible(false);
m_feedSplitter->addWidget(m_feedsWidget);
m_feedSplitter->addWidget(m_messagesWidget);
// Add toolbar and main feeds/messages widget to main layout.
central_layout->addWidget(m_feedSplitter);
setTabOrder(m_feedsView, m_messagesView);
setTabOrder(m_messagesView, m_toolBarFeeds);
setTabOrder(m_toolBarFeeds, m_toolBarMessages);
setTabOrder(m_toolBarMessages, m_messagesBrowser);
m_feedsWidget = new QWidget(this);
m_messagesWidget = new QWidget(this);
m_feedSplitter = new QSplitter(Qt::Horizontal, this);
m_messageSplitter = new QSplitter(Qt::Vertical, this);
// Instantiate needed components.
QVBoxLayout* central_layout = new QVBoxLayout(this);
QVBoxLayout* feed_layout = new QVBoxLayout(m_feedsWidget);
QVBoxLayout* message_layout = new QVBoxLayout(m_messagesWidget);
// Set layout properties.
central_layout->setMargin(0);
central_layout->setSpacing(0);
feed_layout->setMargin(0);
feed_layout->setSpacing(0);
message_layout->setMargin(0);
message_layout->setSpacing(0);
// Set views.
m_feedsView->setFrameStyle(QFrame::NoFrame);
m_messagesView->setFrameStyle(QFrame::NoFrame);
// Setup message splitter.
m_messageSplitter->setObjectName(QSL("MessageSplitter"));
m_messageSplitter->setHandleWidth(1);
m_messageSplitter->setOpaqueResize(false);
m_messageSplitter->setChildrenCollapsible(false);
m_messageSplitter->addWidget(m_messagesView);
m_messageSplitter->addWidget(m_messagesBrowser);
// Assemble message-related components to single widget.
message_layout->addWidget(m_toolBarMessages);
message_layout->addWidget(m_messageSplitter);
// Assemble feed-related components to another widget.
feed_layout->addWidget(m_toolBarFeeds);
feed_layout->addWidget(m_feedsView);
// Assembler everything together.
m_feedSplitter->setHandleWidth(1);
m_feedSplitter->setOpaqueResize(false);
m_feedSplitter->setChildrenCollapsible(false);
m_feedSplitter->addWidget(m_feedsWidget);
m_feedSplitter->addWidget(m_messagesWidget);
// Add toolbar and main feeds/messages widget to main layout.
central_layout->addWidget(m_feedSplitter);
setTabOrder(m_feedsView, m_messagesView);
setTabOrder(m_messagesView, m_toolBarFeeds);
setTabOrder(m_toolBarFeeds, m_toolBarMessages);
setTabOrder(m_toolBarMessages, m_messagesBrowser);
}
void FeedMessageViewer::refreshVisualProperties() {
const Qt::ToolButtonStyle button_style = static_cast<Qt::ToolButtonStyle>(qApp->settings()->value(GROUP(GUI),
SETTING(GUI::ToolbarStyle)).toInt());
m_toolBarFeeds->setToolButtonStyle(button_style);
m_toolBarMessages->setToolButtonStyle(button_style);
const Qt::ToolButtonStyle button_style = static_cast<Qt::ToolButtonStyle>(qApp->settings()->value(GROUP(GUI),
SETTING(GUI::ToolbarStyle)).toInt());
m_toolBarFeeds->setToolButtonStyle(button_style);
m_toolBarMessages->setToolButtonStyle(button_style);
}

View File

@ -41,79 +41,79 @@ class QSplitter;
class QProgressBar;
class FeedMessageViewer : public TabContent {
Q_OBJECT
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedMessageViewer(QWidget *parent = 0);
virtual ~FeedMessageViewer();
public:
// Constructors and destructors.
explicit FeedMessageViewer(QWidget* parent = 0);
virtual ~FeedMessageViewer();
#if defined(USE_WEBENGINE)
WebBrowser *webBrowser() const;
WebBrowser* webBrowser() const;
#endif
FeedsView *feedsView() const;
MessagesView *messagesView() const;
MessagesToolBar *messagesToolBar() const;
FeedsToolBar *feedsToolBar() const;
FeedsView* feedsView() const;
MessagesView* messagesView() const;
MessagesToolBar* messagesToolBar() const;
FeedsToolBar* feedsToolBar() const;
bool areToolBarsEnabled() const;
bool areListHeadersEnabled() const;
bool areToolBarsEnabled() const;
bool areListHeadersEnabled() const;
public slots:
// Loads/saves sizes and states of ALL
// underlying widgets, this contains primarily
// splitters, toolbar and views.
void saveSize();
void loadSize();
public slots:
// Loads/saves sizes and states of ALL
// underlying widgets, this contains primarily
// splitters, toolbar and views.
void saveSize();
void loadSize();
void loadMessageViewerFonts();
void loadMessageViewerFonts();
// Switches orientation horizontal/vertical.
void switchMessageSplitterOrientation();
// Switches orientation horizontal/vertical.
void switchMessageSplitterOrientation();
// Enables/disables main toolbars or list headers.
void setToolBarsEnabled(bool enable);
void setListHeadersEnabled(bool enable);
// Enables/disables main toolbars or list headers.
void setToolBarsEnabled(bool enable);
void setListHeadersEnabled(bool enable);
// Reloads some changeable visual settings.
void refreshVisualProperties();
// Reloads some changeable visual settings.
void refreshVisualProperties();
// Switches visibility of feed list and related
// toolbar.
void switchFeedComponentVisibility();
// Switches visibility of feed list and related
// toolbar.
void switchFeedComponentVisibility();
// Toggles displayed feeds.
void toggleShowOnlyUnreadFeeds();
// Toggles displayed feeds.
void toggleShowOnlyUnreadFeeds();
protected:
// Initializes some properties of the widget.
void initialize();
protected:
// Initializes some properties of the widget.
void initialize();
// Initializes both messages/feeds views.
void initializeViews();
// Initializes both messages/feeds views.
void initializeViews();
// Sets up connections.
void createConnections();
// Sets up connections.
void createConnections();
private:
bool m_toolBarsEnabled;
bool m_listHeadersEnabled;
FeedsToolBar *m_toolBarFeeds;
MessagesToolBar *m_toolBarMessages;
private:
bool m_toolBarsEnabled;
bool m_listHeadersEnabled;
FeedsToolBar* m_toolBarFeeds;
MessagesToolBar* m_toolBarMessages;
QSplitter *m_feedSplitter;
QSplitter *m_messageSplitter;
QSplitter* m_feedSplitter;
QSplitter* m_messageSplitter;
MessagesView *m_messagesView;
FeedsView *m_feedsView;
QWidget *m_feedsWidget;
QWidget *m_messagesWidget;
MessagesView* m_messagesView;
FeedsView* m_feedsView;
QWidget* m_feedsWidget;
QWidget* m_messagesWidget;
#if defined(USE_WEBENGINE)
WebBrowser *m_messagesBrowser;
WebBrowser* m_messagesBrowser;
#else
MessagePreviewer *m_messagesBrowser;
MessagePreviewer* m_messagesBrowser;
#endif
};

View File

@ -1,105 +1,102 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/feedstoolbar.h"
#include "miscellaneous/application.h"
#include "miscellaneous/settings.h"
#include "miscellaneous/iconfactory.h"
#include <QWidgetAction>
FeedsToolBar::FeedsToolBar(const QString &title, QWidget *parent) : BaseToolBar(title, parent) {
// Update right margin of filter textbox.
QMargins margins = contentsMargins();
margins.setRight(margins.right() + FILTER_RIGHT_MARGIN);
setContentsMargins(margins);
}
FeedsToolBar::~FeedsToolBar() {
}
QList<QAction*> FeedsToolBar::availableActions() const {
return qApp->userActions();
}
QList<QAction*> FeedsToolBar::changeableActions() const {
return actions();
}
void FeedsToolBar::saveChangeableActions(const QStringList &actions) {
qApp->settings()->setValue(GROUP(GUI), GUI::FeedsToolbarActions, actions.join(QSL(",")));
loadSpecificActions(getSpecificActions(actions));
}
QList<QAction*> FeedsToolBar::getSpecificActions(const QStringList &actions) {
QList<QAction*> available_actions = availableActions();
QList<QAction*> spec_actions;
// Iterate action names and add respectable actions into the toolbar.
foreach (const QString &action_name, actions) {
QAction *matching_action = findMatchingAction(action_name, available_actions);
if (matching_action != nullptr) {
// Add existing standard action.
spec_actions.append(matching_action);
}
else if (action_name == SEPARATOR_ACTION_NAME) {
// Add new separator.
QAction *act = new QAction(this);
act->setSeparator(true);
spec_actions.append(act);
}
else if (action_name == SPACER_ACTION_NAME) {
// Add new spacer.
QWidget *spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QWidgetAction *action = new QWidgetAction(this);
action->setDefaultWidget(spacer);
action->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
action->setProperty("type", SPACER_ACTION_NAME);
action->setProperty("name", tr("Toolbar spacer"));
spec_actions.append(action);
}
}
return spec_actions;
}
void FeedsToolBar::loadSpecificActions(const QList<QAction*> &actions) {
clear();
foreach (QAction *act, actions) {
addAction(act);
}
}
QStringList FeedsToolBar::defaultActions() const {
return QString(GUI::FeedsToolbarActionsDef).split(',',
QString::SkipEmptyParts);
}
QStringList FeedsToolBar::savedActions() const {
return qApp->settings()->value(GROUP(GUI), SETTING(GUI::FeedsToolbarActions)).toString().split(',',
QString::SkipEmptyParts);
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/feedstoolbar.h"
#include "miscellaneous/application.h"
#include "miscellaneous/settings.h"
#include "miscellaneous/iconfactory.h"
#include <QWidgetAction>
FeedsToolBar::FeedsToolBar(const QString& title, QWidget* parent) : BaseToolBar(title, parent) {
// Update right margin of filter textbox.
QMargins margins = contentsMargins();
margins.setRight(margins.right() + FILTER_RIGHT_MARGIN);
setContentsMargins(margins);
}
FeedsToolBar::~FeedsToolBar() {
}
QList<QAction*> FeedsToolBar::availableActions() const {
return qApp->userActions();
}
QList<QAction*> FeedsToolBar::changeableActions() const {
return actions();
}
void FeedsToolBar::saveChangeableActions(const QStringList& actions) {
qApp->settings()->setValue(GROUP(GUI), GUI::FeedsToolbarActions, actions.join(QSL(",")));
loadSpecificActions(getSpecificActions(actions));
}
QList<QAction*> FeedsToolBar::getSpecificActions(const QStringList& actions) {
QList<QAction*> available_actions = availableActions();
QList<QAction*> spec_actions;
// Iterate action names and add respectable actions into the toolbar.
foreach (const QString& action_name, actions) {
QAction* matching_action = findMatchingAction(action_name, available_actions);
if (matching_action != nullptr) {
// Add existing standard action.
spec_actions.append(matching_action);
}
else if (action_name == SEPARATOR_ACTION_NAME) {
// Add new separator.
QAction* act = new QAction(this);
act->setSeparator(true);
spec_actions.append(act);
}
else if (action_name == SPACER_ACTION_NAME) {
// Add new spacer.
QWidget* spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QWidgetAction* action = new QWidgetAction(this);
action->setDefaultWidget(spacer);
action->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
action->setProperty("type", SPACER_ACTION_NAME);
action->setProperty("name", tr("Toolbar spacer"));
spec_actions.append(action);
}
}
return spec_actions;
}
void FeedsToolBar::loadSpecificActions(const QList<QAction*>& actions) {
clear();
foreach (QAction* act, actions) {
addAction(act);
}
}
QStringList FeedsToolBar::defaultActions() const {
return QString(GUI::FeedsToolbarActionsDef).split(',',
QString::SkipEmptyParts);
}
QStringList FeedsToolBar::savedActions() const {
return qApp->settings()->value(GROUP(GUI), SETTING(GUI::FeedsToolbarActions)).toString().split(',',
QString::SkipEmptyParts);
}

View File

@ -1,43 +1,43 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDSTOOLBAR_H
#define FEEDSTOOLBAR_H
#include "gui/basetoolbar.h"
class FeedsToolBar : public BaseToolBar {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedsToolBar(const QString &title, QWidget *parent = 0);
virtual ~FeedsToolBar();
QList<QAction*> availableActions() const;
QList<QAction*> changeableActions() const;
void saveChangeableActions(const QStringList &actions);
QList<QAction*> getSpecificActions(const QStringList &actions);
void loadSpecificActions(const QList<QAction*> &actions);
QStringList defaultActions() const;
QStringList savedActions() const;
};
#endif // FEEDSTOOLBAR_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDSTOOLBAR_H
#define FEEDSTOOLBAR_H
#include "gui/basetoolbar.h"
class FeedsToolBar : public BaseToolBar {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedsToolBar(const QString& title, QWidget* parent = 0);
virtual ~FeedsToolBar();
QList<QAction*> availableActions() const;
QList<QAction*> changeableActions() const;
void saveChangeableActions(const QStringList& actions);
QList<QAction*> getSpecificActions(const QStringList& actions);
void loadSpecificActions(const QList<QAction*>& actions);
QStringList defaultActions() const;
QStringList savedActions() const;
};
#endif // FEEDSTOOLBAR_H

File diff suppressed because it is too large Load Diff

View File

@ -1,146 +1,146 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDSVIEW_H
#define FEEDSVIEW_H
#include <QTreeView>
#include "core/feedsmodel.h"
#include <QStyledItemDelegate>
class FeedsProxyModel;
class Feed;
class Category;
class FeedsView : public QTreeView {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedsView(QWidget *parent = 0);
virtual ~FeedsView();
// Fundamental accessors.
inline FeedsProxyModel *model() const {
return m_proxyModel;
}
inline FeedsModel *sourceModel() const {
return m_sourceModel;
}
void setSortingEnabled(bool enable);
// Returns list of selected/all feeds.
// NOTE: This is recursive method which returns all descendants.
QList<Feed*> selectedFeeds() const;
// Returns pointers to selected feed/category if they are really
// selected.
RootItem *selectedItem() const;
// Saves/loads expand states of all nodes (feeds/categories) of the list to/from settings.
void saveAllExpandStates();
void loadAllExpandStates();
public slots:
void sortByColumn(int column, Qt::SortOrder order);
void addFeedIntoSelectedAccount();
void addCategoryIntoSelectedAccount();
void expandCollapseCurrentItem();
// Feed updating.
void updateSelectedItems();
// Feed read/unread manipulators.
void markSelectedItemRead();
void markSelectedItemUnread();
void markAllItemsRead();
// Newspaper accessors.
void openSelectedItemsInNewspaperMode();
// Feed clearers.
void clearSelectedFeeds();
void clearAllFeeds();
// Base manipulators.
void editSelectedItem();
void deleteSelectedItem();
// Selects next/previous item (feed/category) in the list.
void selectNextItem();
void selectPreviousItem();
// Switches visibility of the widget.
void switchVisibility();
signals:
// Emitted if user selects new feeds.
void itemSelected(RootItem *item);
// Requests opening of given messages in newspaper mode.
void openMessagesInNewspaperView(RootItem *root, const QList<Message> &messages);
protected:
// Handle selections.
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
// React on "Del" key.
void keyPressEvent(QKeyEvent *event);
// Show custom context menu.
void contextMenuEvent(QContextMenuEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
private slots:
void expandItemDelayed(const QModelIndex &idx);
void markSelectedItemReadStatus(RootItem::ReadStatus read);
void markAllItemsReadStatus(RootItem::ReadStatus read);
void saveSortState(int column, Qt::SortOrder order);
void validateItemAfterDragDrop(const QModelIndex &source_index);
void onItemExpandRequested(const QList<RootItem*> &items, bool exp);
void onItemExpandStateSaveRequested(RootItem *item);
private:
// Initializes context menus.
QMenu *initializeContextMenuCategories(RootItem *clicked_item);
QMenu *initializeContextMenuFeeds(RootItem *clicked_item);
QMenu *initializeContextMenuEmptySpace();
QMenu *initializeContextMenuOtherItem(RootItem *clicked_item);
// Sets up appearance of this widget.
void setupAppearance();
void saveExpandStates(RootItem *item);
QMenu *m_contextMenuCategories;
QMenu *m_contextMenuFeeds;
QMenu *m_contextMenuEmptySpace;
QMenu *m_contextMenuOtherItems;
FeedsModel *m_sourceModel;
FeedsProxyModel *m_proxyModel;
};
#endif // FEEDSVIEW_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 FEEDSVIEW_H
#define FEEDSVIEW_H
#include <QTreeView>
#include "core/feedsmodel.h"
#include <QStyledItemDelegate>
class FeedsProxyModel;
class Feed;
class Category;
class FeedsView : public QTreeView {
Q_OBJECT
public:
// Constructors and destructors.
explicit FeedsView(QWidget* parent = 0);
virtual ~FeedsView();
// Fundamental accessors.
inline FeedsProxyModel* model() const {
return m_proxyModel;
}
inline FeedsModel* sourceModel() const {
return m_sourceModel;
}
void setSortingEnabled(bool enable);
// Returns list of selected/all feeds.
// NOTE: This is recursive method which returns all descendants.
QList<Feed*> selectedFeeds() const;
// Returns pointers to selected feed/category if they are really
// selected.
RootItem* selectedItem() const;
// Saves/loads expand states of all nodes (feeds/categories) of the list to/from settings.
void saveAllExpandStates();
void loadAllExpandStates();
public slots:
void sortByColumn(int column, Qt::SortOrder order);
void addFeedIntoSelectedAccount();
void addCategoryIntoSelectedAccount();
void expandCollapseCurrentItem();
// Feed updating.
void updateSelectedItems();
// Feed read/unread manipulators.
void markSelectedItemRead();
void markSelectedItemUnread();
void markAllItemsRead();
// Newspaper accessors.
void openSelectedItemsInNewspaperMode();
// Feed clearers.
void clearSelectedFeeds();
void clearAllFeeds();
// Base manipulators.
void editSelectedItem();
void deleteSelectedItem();
// Selects next/previous item (feed/category) in the list.
void selectNextItem();
void selectPreviousItem();
// Switches visibility of the widget.
void switchVisibility();
signals:
// Emitted if user selects new feeds.
void itemSelected(RootItem* item);
// Requests opening of given messages in newspaper mode.
void openMessagesInNewspaperView(RootItem* root, const QList<Message>& messages);
protected:
// Handle selections.
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
// React on "Del" key.
void keyPressEvent(QKeyEvent* event);
// Show custom context menu.
void contextMenuEvent(QContextMenuEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);
private slots:
void expandItemDelayed(const QModelIndex& idx);
void markSelectedItemReadStatus(RootItem::ReadStatus read);
void markAllItemsReadStatus(RootItem::ReadStatus read);
void saveSortState(int column, Qt::SortOrder order);
void validateItemAfterDragDrop(const QModelIndex& source_index);
void onItemExpandRequested(const QList<RootItem*>& items, bool exp);
void onItemExpandStateSaveRequested(RootItem* item);
private:
// Initializes context menus.
QMenu* initializeContextMenuCategories(RootItem* clicked_item);
QMenu* initializeContextMenuFeeds(RootItem* clicked_item);
QMenu* initializeContextMenuEmptySpace();
QMenu* initializeContextMenuOtherItem(RootItem* clicked_item);
// Sets up appearance of this widget.
void setupAppearance();
void saveExpandStates(RootItem* item);
QMenu* m_contextMenuCategories;
QMenu* m_contextMenuFeeds;
QMenu* m_contextMenuEmptySpace;
QMenu* m_contextMenuOtherItems;
FeedsModel* m_sourceModel;
FeedsProxyModel* m_proxyModel;
};
#endif // FEEDSVIEW_H

View File

@ -1,37 +1,38 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/guiutilities.h"
#include "definitions/definitions.h"
#include <QLabel>
void GuiUtilities::setLabelAsNotice(QLabel *label, bool is_warning) {
label->setMargin(6);
if (is_warning) {
label->setStyleSheet(QSL("font-weight: bold; font-style: italic; color: red"));
}
else {
label->setStyleSheet(QSL("font-style: italic;"));
}
}
GuiUtilities::GuiUtilities() {
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/guiutilities.h"
#include "definitions/definitions.h"
#include <QLabel>
void GuiUtilities::setLabelAsNotice(QLabel* label, bool is_warning) {
label->setMargin(6);
if (is_warning) {
label->setStyleSheet(QSL("font-weight: bold; font-style: italic; color: red"));
}
else {
label->setStyleSheet(QSL("font-style: italic;"));
}
}
GuiUtilities::GuiUtilities() {
}

View File

@ -1,32 +1,32 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 GUIUTILITIES_H
#define GUIUTILITIES_H
class QLabel;
class GuiUtilities {
public:
static void setLabelAsNotice(QLabel *label, bool is_warning);
private:
explicit GuiUtilities();
};
#endif // GUIUTILITIES_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 GUIUTILITIES_H
#define GUIUTILITIES_H
class QLabel;
class GuiUtilities {
public:
static void setLabelAsNotice(QLabel* label, bool is_warning);
private:
explicit GuiUtilities();
};
#endif // GUIUTILITIES_H

View File

@ -1,46 +1,44 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/labelwithstatus.h"
#include "gui/plaintoolbutton.h"
#include <QHBoxLayout>
LabelWithStatus::LabelWithStatus(QWidget *parent)
: WidgetWithStatus(parent) {
m_wdgInput = new QLabel(this);
// Set correct size for the tool button.
int label_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(label_height, label_height);
// Compose the layout.
m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus);
}
LabelWithStatus::~LabelWithStatus() {
}
void LabelWithStatus::setStatus(WidgetWithStatus::StatusType status,
const QString &label_text,
const QString &status_text) {
WidgetWithStatus::setStatus(status, status_text);
label()->setText(label_text);
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/labelwithstatus.h"
#include "gui/plaintoolbutton.h"
#include <QHBoxLayout>
LabelWithStatus::LabelWithStatus(QWidget* parent)
: WidgetWithStatus(parent) {
m_wdgInput = new QLabel(this);
// Set correct size for the tool button.
int label_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(label_height, label_height);
// Compose the layout.
m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus);
}
LabelWithStatus::~LabelWithStatus() {
}
void LabelWithStatus::setStatus(WidgetWithStatus::StatusType status,
const QString& label_text,
const QString& status_text) {
WidgetWithStatus::setStatus(status, status_text);
label()->setText(label_text);
}

View File

@ -1,42 +1,42 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 LABELWITHSTATUS_H
#define LABELWITHSTATUS_H
#include "gui/widgetwithstatus.h"
#include <QLabel>
class LabelWithStatus : public WidgetWithStatus {
Q_OBJECT
public:
// Constructors and destructors.
explicit LabelWithStatus(QWidget *parent = 0);
virtual ~LabelWithStatus();
void setStatus(StatusType status, const QString &label_text, const QString &status_text);
// Access to label.
inline QLabel *label() const {
return static_cast<QLabel*>(m_wdgInput);
}
};
#endif // LABELWITHSTATUS_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 LABELWITHSTATUS_H
#define LABELWITHSTATUS_H
#include "gui/widgetwithstatus.h"
#include <QLabel>
class LabelWithStatus : public WidgetWithStatus {
Q_OBJECT
public:
// Constructors and destructors.
explicit LabelWithStatus(QWidget* parent = 0);
virtual ~LabelWithStatus();
void setStatus(StatusType status, const QString& label_text, const QString& status_text);
// Access to label.
inline QLabel* label() const {
return static_cast<QLabel*>(m_wdgInput);
}
};
#endif // LABELWITHSTATUS_H

View File

@ -1,42 +1,39 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/lineeditwithstatus.h"
#include "gui/plaintoolbutton.h"
#include "gui/baselineedit.h"
#include <QHBoxLayout>
LineEditWithStatus::LineEditWithStatus(QWidget *parent)
: WidgetWithStatus(parent) {
m_wdgInput = new BaseLineEdit(this);
setFocusProxy(m_wdgInput);
// Set correct size for the tool button.
const int txt_input_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(txt_input_height, txt_input_height);
// Compose the layout.
m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus);
}
LineEditWithStatus::~LineEditWithStatus() {
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/lineeditwithstatus.h"
#include "gui/plaintoolbutton.h"
#include "gui/baselineedit.h"
#include <QHBoxLayout>
LineEditWithStatus::LineEditWithStatus(QWidget* parent)
: WidgetWithStatus(parent) {
m_wdgInput = new BaseLineEdit(this);
setFocusProxy(m_wdgInput);
// Set correct size for the tool button.
const int txt_input_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(txt_input_height, txt_input_height);
// Compose the layout.
m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus);
}
LineEditWithStatus::~LineEditWithStatus() {
}

View File

@ -1,40 +1,40 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 LINEEDITWITHSTATUS_H
#define LINEEDITWITHSTATUS_H
#include "gui/widgetwithstatus.h"
#include "gui/baselineedit.h"
class LineEditWithStatus : public WidgetWithStatus {
Q_OBJECT
public:
// Constructors and destructors.
explicit LineEditWithStatus(QWidget *parent = 0);
virtual ~LineEditWithStatus();
// Access to line edit.
inline BaseLineEdit *lineEdit() const {
return static_cast<BaseLineEdit*>(m_wdgInput);
}
};
#endif // LINEEDITWITHSTATUS_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 LINEEDITWITHSTATUS_H
#define LINEEDITWITHSTATUS_H
#include "gui/widgetwithstatus.h"
#include "gui/baselineedit.h"
class LineEditWithStatus : public WidgetWithStatus {
Q_OBJECT
public:
// Constructors and destructors.
explicit LineEditWithStatus(QWidget* parent = 0);
virtual ~LineEditWithStatus();
// Access to line edit.
inline BaseLineEdit* lineEdit() const {
return static_cast<BaseLineEdit*>(m_wdgInput);
}
};
#endif // LINEEDITWITHSTATUS_H

View File

@ -1,53 +1,52 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/locationlineedit.h"
#include "network-web/googlesuggest.h"
#include <QMouseEvent>
LocationLineEdit::LocationLineEdit(QWidget *parent)
: BaseLineEdit(parent), m_mouseSelectsAllText(true), m_googleSuggest(new GoogleSuggest(this)) {
setPlaceholderText(tr("Website address goes here"));
connect(this, &LocationLineEdit::submitted, m_googleSuggest, &GoogleSuggest::preventSuggest);
}
LocationLineEdit::~LocationLineEdit() {
}
void LocationLineEdit::focusOutEvent(QFocusEvent *event) {
BaseLineEdit::focusOutEvent(event);
// User now left text box, when he enters it again and clicks,
// then all text should be selected.
m_mouseSelectsAllText = true;
}
void LocationLineEdit::mousePressEvent(QMouseEvent *event) {
if (m_mouseSelectsAllText) {
event->ignore();
selectAll();
// User clicked and all text was selected.
m_mouseSelectsAllText = false;
}
else {
BaseLineEdit::mousePressEvent(event);
}
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/locationlineedit.h"
#include "network-web/googlesuggest.h"
#include <QMouseEvent>
LocationLineEdit::LocationLineEdit(QWidget* parent)
: BaseLineEdit(parent), m_mouseSelectsAllText(true), m_googleSuggest(new GoogleSuggest(this)) {
setPlaceholderText(tr("Website address goes here"));
connect(this, &LocationLineEdit::submitted, m_googleSuggest, &GoogleSuggest::preventSuggest);
}
LocationLineEdit::~LocationLineEdit() {
}
void LocationLineEdit::focusOutEvent(QFocusEvent* event) {
BaseLineEdit::focusOutEvent(event);
// User now left text box, when he enters it again and clicks,
// then all text should be selected.
m_mouseSelectsAllText = true;
}
void LocationLineEdit::mousePressEvent(QMouseEvent* event) {
if (m_mouseSelectsAllText) {
event->ignore();
selectAll();
// User clicked and all text was selected.
m_mouseSelectsAllText = false;
}
else {
BaseLineEdit::mousePressEvent(event);
}
}

View File

@ -1,44 +1,44 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 LOCATIONLINEEDIT_H
#define LOCATIONLINEEDIT_H
#include "gui/baselineedit.h"
class WebBrowser;
class GoogleSuggest;
class LocationLineEdit : public BaseLineEdit {
Q_OBJECT
public:
// Constructors and destructors.
explicit LocationLineEdit(QWidget *parent = 0);
virtual ~LocationLineEdit();
protected:
void focusOutEvent(QFocusEvent *event);
void mousePressEvent(QMouseEvent *event);
private:
bool m_mouseSelectsAllText;
GoogleSuggest *m_googleSuggest;
};
#endif // LOCATIONLINEEDIT_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 LOCATIONLINEEDIT_H
#define LOCATIONLINEEDIT_H
#include "gui/baselineedit.h"
class WebBrowser;
class GoogleSuggest;
class LocationLineEdit : public BaseLineEdit {
Q_OBJECT
public:
// Constructors and destructors.
explicit LocationLineEdit(QWidget* parent = 0);
virtual ~LocationLineEdit();
protected:
void focusOutEvent(QFocusEvent* event);
void mousePressEvent(QMouseEvent* event);
private:
bool m_mouseSelectsAllText;
GoogleSuggest* m_googleSuggest;
};
#endif // LOCATIONLINEEDIT_H

View File

@ -1,110 +1,107 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/messagebox.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include <QtGlobal>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QStyle>
#include <QCheckBox>
MessageBox::MessageBox(QWidget *parent) : QMessageBox(parent) {
}
MessageBox::~MessageBox() {
}
void MessageBox::setIcon(QMessageBox::Icon icon) {
// Determine correct status icon size.
const int icon_size = qApp->style()->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this);
// Setup status icon.
setIconPixmap(iconForStatus(icon).pixmap(icon_size, icon_size));
}
void MessageBox::setCheckBox(QMessageBox *msg_box, const QString &text, bool *data) {
// Add "don't show this again checkbox.
QCheckBox *check_box = new QCheckBox(msg_box);
check_box->setChecked(*data);
check_box->setText(text);
connect(check_box, &QCheckBox::toggled, [=](bool checked) {
*data = checked;
});
msg_box->setCheckBox(check_box);
}
QIcon MessageBox::iconForStatus(QMessageBox::Icon status) {
switch (status) {
case QMessageBox::Information:
return qApp->icons()->fromTheme(QSL("dialog-information"));
case QMessageBox::Warning:
return qApp->icons()->fromTheme(QSL("dialog-warning"));
case QMessageBox::Critical:
return qApp->icons()->fromTheme(QSL("dialog-error"));
case QMessageBox::Question:
return qApp->icons()->fromTheme(QSL("dialog-question"));
case QMessageBox::NoIcon:
default:
return QIcon();
}
}
QMessageBox::StandardButton MessageBox::show(QWidget *parent,
QMessageBox::Icon icon,
const QString &title,
const QString &text,
const QString &informative_text,
const QString &detailed_text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton default_button,
bool *dont_show_again) {
// Create and find needed components.
MessageBox msg_box(parent);
// Initialize message box properties.
msg_box.setWindowTitle(title);
msg_box.setText(text);
msg_box.setInformativeText(informative_text);
msg_box.setDetailedText(detailed_text);
msg_box.setIcon(icon);
msg_box.setStandardButtons(buttons);
msg_box.setDefaultButton(default_button);
if (dont_show_again != nullptr) {
MessageBox::setCheckBox(&msg_box, tr("Do not show this dialog again."), dont_show_again);
}
// Display it.
if (msg_box.exec() == -1) {
return QMessageBox::Cancel;
}
else {
return msg_box.standardButton(msg_box.clickedButton());
}
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/messagebox.h"
#include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h"
#include <QtGlobal>
#include <QDialogButtonBox>
#include <QPushButton>
#include <QDialogButtonBox>
#include <QStyle>
#include <QCheckBox>
MessageBox::MessageBox(QWidget* parent) : QMessageBox(parent) {
}
MessageBox::~MessageBox() {
}
void MessageBox::setIcon(QMessageBox::Icon icon) {
// Determine correct status icon size.
const int icon_size = qApp->style()->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this);
// Setup status icon.
setIconPixmap(iconForStatus(icon).pixmap(icon_size, icon_size));
}
void MessageBox::setCheckBox(QMessageBox* msg_box, const QString& text, bool* data) {
// Add "don't show this again checkbox.
QCheckBox* check_box = new QCheckBox(msg_box);
check_box->setChecked(*data);
check_box->setText(text);
connect(check_box, &QCheckBox::toggled, [ = ](bool checked) {
*data = checked;
});
msg_box->setCheckBox(check_box);
}
QIcon MessageBox::iconForStatus(QMessageBox::Icon status) {
switch (status) {
case QMessageBox::Information:
return qApp->icons()->fromTheme(QSL("dialog-information"));
case QMessageBox::Warning:
return qApp->icons()->fromTheme(QSL("dialog-warning"));
case QMessageBox::Critical:
return qApp->icons()->fromTheme(QSL("dialog-error"));
case QMessageBox::Question:
return qApp->icons()->fromTheme(QSL("dialog-question"));
case QMessageBox::NoIcon:
default:
return QIcon();
}
}
QMessageBox::StandardButton MessageBox::show(QWidget* parent,
QMessageBox::Icon icon,
const QString& title,
const QString& text,
const QString& informative_text,
const QString& detailed_text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton default_button,
bool* dont_show_again) {
// Create and find needed components.
MessageBox msg_box(parent);
// Initialize message box properties.
msg_box.setWindowTitle(title);
msg_box.setText(text);
msg_box.setInformativeText(informative_text);
msg_box.setDetailedText(detailed_text);
msg_box.setIcon(icon);
msg_box.setStandardButtons(buttons);
msg_box.setDefaultButton(default_button);
if (dont_show_again != nullptr) {
MessageBox::setCheckBox(&msg_box, tr("Do not show this dialog again."), dont_show_again);
}
// Display it.
if (msg_box.exec() == -1) {
return QMessageBox::Cancel;
}
else {
return msg_box.standardButton(msg_box.clickedButton());
}
}

View File

@ -1,52 +1,52 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGEBOX_H
#define MESSAGEBOX_H
#include <QMessageBox>
#include <QDialogButtonBox>
class MessageBox : public QMessageBox {
Q_OBJECT
public:
// Constructors and destructors.
explicit MessageBox(QWidget *parent = 0);
virtual ~MessageBox();
// Custom icon setting.
void setIcon(Icon icon);
static void setCheckBox(QMessageBox *msg_box, const QString &text, bool *data);
// Displays custom message box.
static QMessageBox::StandardButton show(QWidget *parent,
QMessageBox::Icon icon,
const QString &title,
const QString &text,
const QString &informative_text = QString(),
const QString &detailed_text = QString(),
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton default_button = QMessageBox::Ok,
bool *dont_show_again = nullptr);
static QIcon iconForStatus(QMessageBox::Icon status);
};
#endif // MESSAGEBOX_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGEBOX_H
#define MESSAGEBOX_H
#include <QMessageBox>
#include <QDialogButtonBox>
class MessageBox : public QMessageBox {
Q_OBJECT
public:
// Constructors and destructors.
explicit MessageBox(QWidget* parent = 0);
virtual ~MessageBox();
// Custom icon setting.
void setIcon(Icon icon);
static void setCheckBox(QMessageBox* msg_box, const QString& text, bool* data);
// Displays custom message box.
static QMessageBox::StandardButton show(QWidget* parent,
QMessageBox::Icon icon,
const QString& title,
const QString& text,
const QString& informative_text = QString(),
const QString& detailed_text = QString(),
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
QMessageBox::StandardButton default_button = QMessageBox::Ok,
bool* dont_show_again = nullptr);
static QIcon iconForStatus(QMessageBox::Icon status);
};
#endif // MESSAGEBOX_H

View File

@ -1,234 +1,219 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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()) {
bool open_externally_now = qApp->settings()->value(GROUP(Browser),
SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool();
if (open_externally_now) {
WebFactory::instance()->openUrlInExternalBrowser(url.toString());
}
else {
// 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);
bool always;
MessageBox::setCheckBox(&box, tr("Always open links in external browser."), &always);
box.setDefaultButton(QMessageBox::Cancel);
box.exec();
if (box.clickedButton() != box.button(QMessageBox::Cancel)) {
// Store selected checkbox value.
qApp->settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, always);
}
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() {
markMessageAsReadUnread(RootItem::Read);
}
void MessagePreviewer::markMessageAsUnread() {
markMessageAsReadUnread(RootItem::Unread);
}
void MessagePreviewer::markMessageAsReadUnread(RootItem::ReadStatus read) {
if (!m_root.isNull()) {
if (m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(),
QList<Message>() << m_message,
read)) {
DatabaseQueries::markMessagesReadUnread(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(m_message.m_id),
read);
m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(),
QList<Message>() << m_message,
read);
m_message.m_isRead = read == RootItem::Read;
emit markMessageRead(m_message.m_id, read);
updateButtons();
}
}
}
void MessagePreviewer::switchMessageImportance(bool checked) {
if (!m_root.isNull()) {
if (m_root->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(m_message,
m_message.m_isImportant ?
RootItem::NotImportant :
RootItem::Important))) {
DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(m_message.m_id));
m_root->getParentServiceRoot()->onAfterSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(m_message,
m_message.m_isImportant ?
RootItem::NotImportant :
RootItem::Important));
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;
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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()) {
bool open_externally_now = qApp->settings()->value(GROUP(Browser),
SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool();
if (open_externally_now) {
WebFactory::instance()->openUrlInExternalBrowser(url.toString());
}
else {
// 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);
bool always;
MessageBox::setCheckBox(&box, tr("Always open links in external browser."), &always);
box.setDefaultButton(QMessageBox::Cancel);
box.exec();
if (box.clickedButton() != box.button(QMessageBox::Cancel)) {
// Store selected checkbox value.
qApp->settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, always);
}
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() {
markMessageAsReadUnread(RootItem::Read);
}
void MessagePreviewer::markMessageAsUnread() {
markMessageAsReadUnread(RootItem::Unread);
}
void MessagePreviewer::markMessageAsReadUnread(RootItem::ReadStatus read) {
if (!m_root.isNull()) {
if (m_root->getParentServiceRoot()->onBeforeSetMessagesRead(m_root.data(),
QList<Message>() << m_message,
read)) {
DatabaseQueries::markMessagesReadUnread(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(m_message.m_id),
read);
m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(),
QList<Message>() << m_message,
read);
m_message.m_isRead = read == RootItem::Read;
emit markMessageRead(m_message.m_id, read);
updateButtons();
}
}
}
void MessagePreviewer::switchMessageImportance(bool checked) {
if (!m_root.isNull()) {
if (m_root->getParentServiceRoot()->onBeforeSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(m_message,
m_message.m_isImportant ?
RootItem::NotImportant :
RootItem::Important))) {
DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(m_message.m_id));
m_root->getParentServiceRoot()->onAfterSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(m_message,
m_message.m_isImportant ?
RootItem::NotImportant :
RootItem::Important));
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;
}

View File

@ -1,78 +1,78 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 markMessageAsReadUnread(RootItem::ReadStatus read);
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
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 markMessageAsReadUnread(RootItem::ReadStatus read);
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

View File

@ -1,25 +1,25 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/messagessearchlineedit.h"
MessagesSearchLineEdit::MessagesSearchLineEdit(QWidget *parent) : BaseLineEdit(parent) {
}
MessagesSearchLineEdit::~MessagesSearchLineEdit() {
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/messagessearchlineedit.h"
MessagesSearchLineEdit::MessagesSearchLineEdit(QWidget* parent) : BaseLineEdit(parent) {
}
MessagesSearchLineEdit::~MessagesSearchLineEdit() {
}

View File

@ -1,35 +1,35 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGESEARCHLINEEDIT_H
#define MESSAGESEARCHLINEEDIT_H
#include "gui/baselineedit.h"
class PlainToolButton;
class MessagesSearchLineEdit : public BaseLineEdit {
Q_OBJECT
public:
// Constructors and destructors.
explicit MessagesSearchLineEdit(QWidget *parent = 0);
virtual ~MessagesSearchLineEdit();
};
#endif // MESSAGESEARCHLINEEDIT_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGESEARCHLINEEDIT_H
#define MESSAGESEARCHLINEEDIT_H
#include "gui/baselineedit.h"
class PlainToolButton;
class MessagesSearchLineEdit : public BaseLineEdit {
Q_OBJECT
public:
// Constructors and destructors.
explicit MessagesSearchLineEdit(QWidget* parent = 0);
virtual ~MessagesSearchLineEdit();
};
#endif // MESSAGESEARCHLINEEDIT_H

View File

@ -1,173 +1,165 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/messagestoolbar.h"
#include "definitions/definitions.h"
#include "gui/baselineedit.h"
#include "gui/messagessearchlineedit.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/settings.h"
#include <QWidgetAction>
#include <QToolButton>
#include <QMenu>
MessagesToolBar::MessagesToolBar(const QString &title, QWidget *parent)
: BaseToolBar(title, parent) {
initializeSearchBox();
initializeHighlighter();
}
MessagesToolBar::~MessagesToolBar() {
}
QList<QAction*> MessagesToolBar::availableActions() const {
QList<QAction*> available_actions = qApp->userActions();
available_actions.append(m_actionSearchMessages);
available_actions.append(m_actionMessageHighlighter);
return available_actions;
}
QList<QAction*> MessagesToolBar::changeableActions() const {
return actions();
}
void MessagesToolBar::saveChangeableActions(const QStringList& actions) {
qApp->settings()->setValue(GROUP(GUI), GUI::MessagesToolbarDefaultButtons, actions.join(QSL(",")));
loadSpecificActions(getSpecificActions(actions));
// If user hidden search messages box, then remove the filter.
if (!changeableActions().contains(m_actionSearchMessages)) {
m_txtSearchMessages->clear();
}
}
QList<QAction*> MessagesToolBar::getSpecificActions(const QStringList &actions) {
QList<QAction*> available_actions = availableActions();
QList<QAction*> spec_actions;
// Iterate action names and add respectable actions into the toolbar.
foreach (const QString &action_name, actions) {
QAction *matching_action = findMatchingAction(action_name, available_actions);
if (matching_action != nullptr) {
// Add existing standard action.
spec_actions.append(matching_action);
}
else if (action_name == SEPARATOR_ACTION_NAME) {
// Add new separator.
QAction *act = new QAction(this);
act->setSeparator(true);
spec_actions.append(act);
}
else if (action_name == SEACRH_MESSAGES_ACTION_NAME) {
// Add search box.
spec_actions.append(m_actionSearchMessages);
}
else if (action_name == HIGHLIGHTER_ACTION_NAME) {
// Add filter button.
spec_actions.append(m_actionMessageHighlighter);
}
else if (action_name == SPACER_ACTION_NAME) {
// Add new spacer.
QWidget *spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QWidgetAction *action = new QWidgetAction(this);
action->setDefaultWidget(spacer);
action->setIcon(qApp->icons()->fromTheme(QSL("go-jump")));
action->setProperty("type", SPACER_ACTION_NAME);
action->setProperty("name", tr("Toolbar spacer"));
spec_actions.append(action);
}
}
return spec_actions;
}
void MessagesToolBar::loadSpecificActions(const QList<QAction*> &actions) {
clear();
foreach (QAction *act, actions) {
addAction(act);
}
}
void MessagesToolBar::handleMessageHighlighterChange(QAction *action) {
m_btnMessageHighlighter->setIcon(action->icon());
m_btnMessageHighlighter->setToolTip(action->text());
emit messageFilterChanged(action->data().value<MessagesModel::MessageHighlighter>());
}
void MessagesToolBar::initializeSearchBox() {
m_txtSearchMessages = new MessagesSearchLineEdit(this);
m_txtSearchMessages->setFixedWidth(FILTER_WIDTH);
m_txtSearchMessages->setPlaceholderText(tr("Search messages"));
// Setup wrapping action for search box.
m_actionSearchMessages = new QWidgetAction(this);
m_actionSearchMessages->setDefaultWidget(m_txtSearchMessages);
m_actionSearchMessages->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
m_actionSearchMessages->setProperty("type", SEACRH_MESSAGES_ACTION_NAME);
m_actionSearchMessages->setProperty("name", tr("Message search box"));
connect(m_txtSearchMessages, &MessagesSearchLineEdit::textChanged, this, &MessagesToolBar::messageSearchPatternChanged);
}
void MessagesToolBar::initializeHighlighter() {
m_menuMessageHighlighter = new QMenu(tr("Menu for highlighting messages"), this);
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme(QSL("mail-mark-read")),
tr("No extra highlighting"))->setData(QVariant::fromValue(MessagesModel::NoHighlighting));
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme(QSL("mail-mark-unread")),
tr("Highlight unread messages"))->setData(QVariant::fromValue(MessagesModel::HighlightUnread));
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme(QSL("mail-mark-important")),
tr("Highlight important messages"))->setData(QVariant::fromValue(MessagesModel::HighlightImportant));
m_btnMessageHighlighter = new QToolButton(this);
m_btnMessageHighlighter->setToolTip(tr("Display all messages"));
m_btnMessageHighlighter->setMenu(m_menuMessageHighlighter);
m_btnMessageHighlighter->setPopupMode(QToolButton::MenuButtonPopup);
m_btnMessageHighlighter->setIcon(qApp->icons()->fromTheme(QSL("mail-mark-read")));
m_actionMessageHighlighter = new QWidgetAction(this);
m_actionMessageHighlighter->setDefaultWidget(m_btnMessageHighlighter);
m_actionMessageHighlighter->setIcon(m_btnMessageHighlighter->icon());
m_actionMessageHighlighter->setProperty("type", HIGHLIGHTER_ACTION_NAME);
m_actionMessageHighlighter->setProperty("name", tr("Message highlighter"));
connect(m_menuMessageHighlighter, SIGNAL(triggered(QAction*)),
this, SLOT(handleMessageHighlighterChange(QAction*)));
}
QStringList MessagesToolBar::defaultActions() const {
return QString(GUI::MessagesToolbarDefaultButtonsDef).split(',',
QString::SkipEmptyParts);
}
QStringList MessagesToolBar::savedActions() const {
return qApp->settings()->value(GROUP(GUI),
SETTING(GUI::MessagesToolbarDefaultButtons)).toString().split(',',
QString::SkipEmptyParts);
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/messagestoolbar.h"
#include "definitions/definitions.h"
#include "gui/baselineedit.h"
#include "gui/messagessearchlineedit.h"
#include "miscellaneous/iconfactory.h"
#include "miscellaneous/settings.h"
#include <QWidgetAction>
#include <QToolButton>
#include <QMenu>
MessagesToolBar::MessagesToolBar(const QString& title, QWidget* parent)
: BaseToolBar(title, parent) {
initializeSearchBox();
initializeHighlighter();
}
MessagesToolBar::~MessagesToolBar() {
}
QList<QAction*> MessagesToolBar::availableActions() const {
QList<QAction*> available_actions = qApp->userActions();
available_actions.append(m_actionSearchMessages);
available_actions.append(m_actionMessageHighlighter);
return available_actions;
}
QList<QAction*> MessagesToolBar::changeableActions() const {
return actions();
}
void MessagesToolBar::saveChangeableActions(const QStringList& actions) {
qApp->settings()->setValue(GROUP(GUI), GUI::MessagesToolbarDefaultButtons, actions.join(QSL(",")));
loadSpecificActions(getSpecificActions(actions));
// If user hidden search messages box, then remove the filter.
if (!changeableActions().contains(m_actionSearchMessages)) {
m_txtSearchMessages->clear();
}
}
QList<QAction*> MessagesToolBar::getSpecificActions(const QStringList& actions) {
QList<QAction*> available_actions = availableActions();
QList<QAction*> spec_actions;
// Iterate action names and add respectable actions into the toolbar.
foreach (const QString& action_name, actions) {
QAction* matching_action = findMatchingAction(action_name, available_actions);
if (matching_action != nullptr) {
// Add existing standard action.
spec_actions.append(matching_action);
}
else if (action_name == SEPARATOR_ACTION_NAME) {
// Add new separator.
QAction* act = new QAction(this);
act->setSeparator(true);
spec_actions.append(act);
}
else if (action_name == SEACRH_MESSAGES_ACTION_NAME) {
// Add search box.
spec_actions.append(m_actionSearchMessages);
}
else if (action_name == HIGHLIGHTER_ACTION_NAME) {
// Add filter button.
spec_actions.append(m_actionMessageHighlighter);
}
else if (action_name == SPACER_ACTION_NAME) {
// Add new spacer.
QWidget* spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QWidgetAction* action = new QWidgetAction(this);
action->setDefaultWidget(spacer);
action->setIcon(qApp->icons()->fromTheme(QSL("go-jump")));
action->setProperty("type", SPACER_ACTION_NAME);
action->setProperty("name", tr("Toolbar spacer"));
spec_actions.append(action);
}
}
return spec_actions;
}
void MessagesToolBar::loadSpecificActions(const QList<QAction*>& actions) {
clear();
foreach (QAction* act, actions) {
addAction(act);
}
}
void MessagesToolBar::handleMessageHighlighterChange(QAction* action) {
m_btnMessageHighlighter->setIcon(action->icon());
m_btnMessageHighlighter->setToolTip(action->text());
emit messageFilterChanged(action->data().value<MessagesModel::MessageHighlighter>());
}
void MessagesToolBar::initializeSearchBox() {
m_txtSearchMessages = new MessagesSearchLineEdit(this);
m_txtSearchMessages->setFixedWidth(FILTER_WIDTH);
m_txtSearchMessages->setPlaceholderText(tr("Search messages"));
// Setup wrapping action for search box.
m_actionSearchMessages = new QWidgetAction(this);
m_actionSearchMessages->setDefaultWidget(m_txtSearchMessages);
m_actionSearchMessages->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
m_actionSearchMessages->setProperty("type", SEACRH_MESSAGES_ACTION_NAME);
m_actionSearchMessages->setProperty("name", tr("Message search box"));
connect(m_txtSearchMessages, &MessagesSearchLineEdit::textChanged, this, &MessagesToolBar::messageSearchPatternChanged);
}
void MessagesToolBar::initializeHighlighter() {
m_menuMessageHighlighter = new QMenu(tr("Menu for highlighting messages"), this);
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme(QSL("mail-mark-read")),
tr("No extra highlighting"))->setData(QVariant::fromValue(MessagesModel::NoHighlighting));
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme(QSL("mail-mark-unread")),
tr("Highlight unread messages"))->setData(QVariant::fromValue(MessagesModel::HighlightUnread));
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme(QSL("mail-mark-important")),
tr("Highlight important messages"))->setData(QVariant::fromValue(MessagesModel::HighlightImportant));
m_btnMessageHighlighter = new QToolButton(this);
m_btnMessageHighlighter->setToolTip(tr("Display all messages"));
m_btnMessageHighlighter->setMenu(m_menuMessageHighlighter);
m_btnMessageHighlighter->setPopupMode(QToolButton::MenuButtonPopup);
m_btnMessageHighlighter->setIcon(qApp->icons()->fromTheme(QSL("mail-mark-read")));
m_actionMessageHighlighter = new QWidgetAction(this);
m_actionMessageHighlighter->setDefaultWidget(m_btnMessageHighlighter);
m_actionMessageHighlighter->setIcon(m_btnMessageHighlighter->icon());
m_actionMessageHighlighter->setProperty("type", HIGHLIGHTER_ACTION_NAME);
m_actionMessageHighlighter->setProperty("name", tr("Message highlighter"));
connect(m_menuMessageHighlighter, SIGNAL(triggered(QAction*)),
this, SLOT(handleMessageHighlighterChange(QAction*)));
}
QStringList MessagesToolBar::defaultActions() const {
return QString(GUI::MessagesToolbarDefaultButtonsDef).split(',',
QString::SkipEmptyParts);
}
QStringList MessagesToolBar::savedActions() const {
return qApp->settings()->value(GROUP(GUI),
SETTING(GUI::MessagesToolbarDefaultButtons)).toString().split(',',
QString::SkipEmptyParts);
}

View File

@ -1,82 +1,82 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 NEWSTOOLBAR_H
#define NEWSTOOLBAR_H
#include "gui/basetoolbar.h"
#include "core/messagesmodel.h"
class MessagesSearchLineEdit;
class QWidgetAction;
class QToolButton;
class QMenu;
class MessagesToolBar : public BaseToolBar {
Q_OBJECT
public:
// Constructors and destructors.
explicit MessagesToolBar(const QString &title, QWidget *parent = 0);
virtual ~MessagesToolBar();
// External access to search line edit.
inline MessagesSearchLineEdit *searchLineEdit() {
return m_txtSearchMessages;
}
// Implementation of BaseToolBar interface.
QList<QAction*> availableActions() const;
QList<QAction*> changeableActions() const;
void saveChangeableActions(const QStringList &actions);
// Loads actions as specified by external actions list.
// NOTE: This is used primarily for reloading actions
// when they are changed from settings.
void loadSpecificActions(const QList<QAction*> &actions);
QList<QAction*> getSpecificActions(const QStringList &actions);
QStringList defaultActions() const;
QStringList savedActions() const;
signals:
void messageSearchPatternChanged(const QString &pattern);
// Emitted if message filter is changed.
void messageFilterChanged(MessagesModel::MessageHighlighter filter);
private slots:
// Called when highlighter gets changed.
void handleMessageHighlighterChange(QAction *action);
private:
void initializeSearchBox();
void initializeHighlighter();
private:
QWidgetAction *m_actionMessageHighlighter;
QToolButton *m_btnMessageHighlighter;
QMenu *m_menuMessageHighlighter;
QWidgetAction *m_actionSearchMessages;
MessagesSearchLineEdit *m_txtSearchMessages;
};
#endif // NEWSTOOLBAR_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 NEWSTOOLBAR_H
#define NEWSTOOLBAR_H
#include "gui/basetoolbar.h"
#include "core/messagesmodel.h"
class MessagesSearchLineEdit;
class QWidgetAction;
class QToolButton;
class QMenu;
class MessagesToolBar : public BaseToolBar {
Q_OBJECT
public:
// Constructors and destructors.
explicit MessagesToolBar(const QString& title, QWidget* parent = 0);
virtual ~MessagesToolBar();
// External access to search line edit.
inline MessagesSearchLineEdit* searchLineEdit() {
return m_txtSearchMessages;
}
// Implementation of BaseToolBar interface.
QList<QAction*> availableActions() const;
QList<QAction*> changeableActions() const;
void saveChangeableActions(const QStringList& actions);
// Loads actions as specified by external actions list.
// NOTE: This is used primarily for reloading actions
// when they are changed from settings.
void loadSpecificActions(const QList<QAction*>& actions);
QList<QAction*> getSpecificActions(const QStringList& actions);
QStringList defaultActions() const;
QStringList savedActions() const;
signals:
void messageSearchPatternChanged(const QString& pattern);
// Emitted if message filter is changed.
void messageFilterChanged(MessagesModel::MessageHighlighter filter);
private slots:
// Called when highlighter gets changed.
void handleMessageHighlighterChange(QAction* action);
private:
void initializeSearchBox();
void initializeHighlighter();
private:
QWidgetAction* m_actionMessageHighlighter;
QToolButton* m_btnMessageHighlighter;
QMenu* m_menuMessageHighlighter;
QWidgetAction* m_actionSearchMessages;
MessagesSearchLineEdit* m_txtSearchMessages;
};
#endif // NEWSTOOLBAR_H

File diff suppressed because it is too large Load Diff

View File

@ -1,125 +1,125 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGESVIEW_H
#define MESSAGESVIEW_H
#include "core/messagesmodel.h"
#include "services/abstract/rootitem.h"
#include <QTreeView>
#include <QHeaderView>
class MessagesProxyModel;
class MessagesView : public QTreeView {
Q_OBJECT
public:
// Constructors and destructors.
explicit MessagesView(QWidget *parent = 0);
virtual ~MessagesView();
// Model accessors.
inline MessagesProxyModel *model() const {
return m_proxyModel;
}
inline MessagesModel *sourceModel() const {
return m_sourceModel;
}
public slots:
void keyboardSearch(const QString &search);
// Called after data got changed externally
// and it needs to be reloaded to the view.
void reloadSelections();
// Loads un-deleted messages from selected feeds.
void loadItem(RootItem *item);
// Message manipulators.
void openSelectedSourceMessagesExternally();
void openSelectedMessagesInternally();
void sendSelectedMessageViaEmail();
// Works with SELECTED messages only.
void setSelectedMessagesReadStatus(RootItem::ReadStatus read);
void markSelectedMessagesRead();
void markSelectedMessagesUnread();
void switchSelectedMessagesImportance();
void deleteSelectedMessages();
void restoreSelectedMessages();
void selectNextItem();
void selectPreviousItem();
void selectNextUnreadItem();
// Searchs the visible message according to given pattern.
void searchMessages(const QString &pattern);
void filterMessages(MessagesModel::MessageHighlighter filter);
private slots:
// Marks given indexes as selected.
void reselectIndexes(const QModelIndexList &indexes);
// Changes resize mode for all columns.
void adjustColumns();
// Saves current sort state.
void onSortIndicatorChanged(int column, Qt::SortOrder order);
signals:
// Link/message openers.
void openLinkNewTab(const QString &link);
void openLinkMiniBrowser(const QString &link);
void openMessagesInNewspaperView(RootItem *root, const QList<Message> &messages);
// Notify others about message selections.
void currentMessageChanged(const Message &message, RootItem *root);
void currentMessageRemoved();
private:
void sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header);
// Creates needed connections.
void createConnections();
// Initializes context menu.
void initializeContextMenu();
// Sets up appearance.
void setupAppearance();
// Event reimplementations.
void contextMenuEvent(QContextMenuEvent *event);
void mousePressEvent(QMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
QMenu *m_contextMenu;
MessagesProxyModel *m_proxyModel;
MessagesModel *m_sourceModel;
bool m_columnsAdjusted;
};
#endif // MESSAGESVIEW_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 MESSAGESVIEW_H
#define MESSAGESVIEW_H
#include "core/messagesmodel.h"
#include "services/abstract/rootitem.h"
#include <QTreeView>
#include <QHeaderView>
class MessagesProxyModel;
class MessagesView : public QTreeView {
Q_OBJECT
public:
// Constructors and destructors.
explicit MessagesView(QWidget* parent = 0);
virtual ~MessagesView();
// Model accessors.
inline MessagesProxyModel* model() const {
return m_proxyModel;
}
inline MessagesModel* sourceModel() const {
return m_sourceModel;
}
public slots:
void keyboardSearch(const QString& search);
// Called after data got changed externally
// and it needs to be reloaded to the view.
void reloadSelections();
// Loads un-deleted messages from selected feeds.
void loadItem(RootItem* item);
// Message manipulators.
void openSelectedSourceMessagesExternally();
void openSelectedMessagesInternally();
void sendSelectedMessageViaEmail();
// Works with SELECTED messages only.
void setSelectedMessagesReadStatus(RootItem::ReadStatus read);
void markSelectedMessagesRead();
void markSelectedMessagesUnread();
void switchSelectedMessagesImportance();
void deleteSelectedMessages();
void restoreSelectedMessages();
void selectNextItem();
void selectPreviousItem();
void selectNextUnreadItem();
// Searchs the visible message according to given pattern.
void searchMessages(const QString& pattern);
void filterMessages(MessagesModel::MessageHighlighter filter);
private slots:
// Marks given indexes as selected.
void reselectIndexes(const QModelIndexList& indexes);
// Changes resize mode for all columns.
void adjustColumns();
// Saves current sort state.
void onSortIndicatorChanged(int column, Qt::SortOrder order);
signals:
// Link/message openers.
void openLinkNewTab(const QString& link);
void openLinkMiniBrowser(const QString& link);
void openMessagesInNewspaperView(RootItem* root, const QList<Message>& messages);
// Notify others about message selections.
void currentMessageChanged(const Message& message, RootItem* root);
void currentMessageRemoved();
private:
void sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header);
// Creates needed connections.
void createConnections();
// Initializes context menu.
void initializeContextMenu();
// Sets up appearance.
void setupAppearance();
// Event reimplementations.
void contextMenuEvent(QContextMenuEvent* event);
void mousePressEvent(QMouseEvent* event);
void keyPressEvent(QKeyEvent* event);
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
QMenu* m_contextMenu;
MessagesProxyModel* m_proxyModel;
MessagesModel* m_sourceModel;
bool m_columnsAdjusted;
};
#endif // MESSAGESVIEW_H

View File

@ -1,51 +1,51 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/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);
}
return m_imagePlaceholder;
}
default:
return QTextBrowser::loadResource(type, name);
}
}
void MessageTextBrowser::wheelEvent(QWheelEvent *e) {
QTextBrowser::wheelEvent(e);
qApp->settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, font().toString());
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/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);
}
return m_imagePlaceholder;
}
default:
return QTextBrowser::loadResource(type, name);
}
}
void MessageTextBrowser::wheelEvent(QWheelEvent* e) {
QTextBrowser::wheelEvent(e);
qApp->settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, font().toString());
}

View File

@ -1,40 +1,40 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 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);
protected:
void wheelEvent(QWheelEvent *e);
private:
QPixmap m_imagePlaceholder;
};
#endif // MESSAGETEXTBROWSER_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 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);
protected:
void wheelEvent(QWheelEvent* e);
private:
QPixmap m_imagePlaceholder;
};
#endif // MESSAGETEXTBROWSER_H

View File

@ -1,65 +1,64 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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, &QPushButton::clicked, this, &NewspaperPreviewer::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, &MessagePreviewer::requestMessageListReload, this, &NewspaperPreviewer::requestMessageListReload);
margins.setRight(0);
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);
}
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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, &QPushButton::clicked, this, &NewspaperPreviewer::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, &MessagePreviewer::requestMessageListReload, this, &NewspaperPreviewer::requestMessageListReload);
margins.setRight(0);
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);
}
}

View File

@ -1,58 +1,58 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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

View File

@ -25,57 +25,56 @@
#include <QAction>
PlainToolButton::PlainToolButton(QWidget *parent) : QToolButton(parent), m_padding(0) {
PlainToolButton::PlainToolButton(QWidget* parent) : QToolButton(parent), m_padding(0) {
}
PlainToolButton::~PlainToolButton() {
}
void PlainToolButton::paintEvent(QPaintEvent *e) {
Q_UNUSED(e)
void PlainToolButton::paintEvent(QPaintEvent* e) {
Q_UNUSED(e)
QPainter p(this);
QRect rect(QPoint(0, 0), size());
// Set padding.
rect.adjust(m_padding, m_padding, -m_padding, -m_padding);
QPainter p(this);
QRect rect(QPoint(0, 0), size());
if (isEnabled()) {
if (underMouse() || isChecked()) {
p.setOpacity(0.7);
}
}
// Set padding.
rect.adjust(m_padding, m_padding, -m_padding, -m_padding);
else {
p.setOpacity(0.3);
}
if (isEnabled()) {
if (underMouse() || isChecked()) {
p.setOpacity(0.7);
}
}
else {
p.setOpacity(0.3);
}
icon().paint(&p, rect);
icon().paint(&p, rect);
}
int PlainToolButton::padding() const {
return m_padding;
return m_padding;
}
void PlainToolButton::setPadding(int padding) {
m_padding = padding;
repaint();
m_padding = padding;
repaint();
}
void PlainToolButton::setChecked(bool checked) {
QToolButton::setChecked(checked);
repaint();
QToolButton::setChecked(checked);
repaint();
}
void PlainToolButton::reactOnActionChange(QAction *action) {
if (action != nullptr) {
setEnabled(action->isEnabled());
setCheckable(action->isCheckable());
setChecked(action->isChecked());
setIcon(action->icon());
setToolTip(action->toolTip());
}
void PlainToolButton::reactOnActionChange(QAction* action) {
if (action != nullptr) {
setEnabled(action->isEnabled());
setCheckable(action->isCheckable());
setChecked(action->isChecked());
setIcon(action->icon());
setToolTip(action->toolTip());
}
}
void PlainToolButton::reactOnSenderActionChange() {
reactOnActionChange(qobject_cast<QAction*>(sender()));
reactOnActionChange(qobject_cast<QAction*>(sender()));
}

View File

@ -22,28 +22,28 @@
class PlainToolButton : public QToolButton {
Q_OBJECT
Q_OBJECT
public:
// Contructors and destructors.
explicit PlainToolButton(QWidget *parent = 0);
virtual ~PlainToolButton();
public:
// Contructors and destructors.
explicit PlainToolButton(QWidget* parent = 0);
virtual ~PlainToolButton();
// Padding changers.
int padding() const;
void setPadding(int padding);
// Padding changers.
int padding() const;
void setPadding(int padding);
public slots:
void setChecked(bool checked);
void reactOnActionChange(QAction *action);
void reactOnSenderActionChange();
public slots:
void setChecked(bool checked);
void reactOnActionChange(QAction* action);
void reactOnSenderActionChange();
protected:
// Custom look.
void paintEvent(QPaintEvent *e);
protected:
// Custom look.
void paintEvent(QPaintEvent* e);
private:
int m_padding;
private:
int m_padding;
};
#endif // CLOSEBUTTON_H

View File

@ -1,202 +1,185 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsbrowsermail.h"
#include "network-web/silentnetworkaccessmanager.h"
#include "miscellaneous/application.h"
#include "miscellaneous/textfactory.h"
#include "gui/guiutilities.h"
#include <QNetworkProxy>
#include <QFileDialog>
SettingsBrowserMail::SettingsBrowserMail(Settings *settings, QWidget *parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) {
m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(m_ui->label, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblExternalEmailInfo, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblProxyInfo, false);
#if defined(USE_WEBENGINE)
m_ui->m_checkOpenLinksInExternal->setVisible(false);
#else
connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
#endif
connect(m_ui->m_cmbProxyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtProxyHost, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtProxyPassword, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtProxyUsername, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_spinProxyPort, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_grpCustomExternalBrowser, &QGroupBox::toggled, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_grpCustomExternalEmail, &QGroupBox::toggled, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalBrowserArguments, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalBrowserExecutable, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalEmailArguments, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalEmailExecutable, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_cmbProxyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::onProxyTypeChanged);
connect(m_ui->m_checkShowPassword, &QCheckBox::stateChanged, this, &SettingsBrowserMail::displayProxyPassword);
connect(m_ui->m_cmbExternalBrowserPreset, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::changeDefaultBrowserArguments);
connect(m_ui->m_btnExternalBrowserExecutable, &QPushButton::clicked, this, &SettingsBrowserMail::selectBrowserExecutable);
connect(m_ui->m_cmbExternalEmailPreset, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::changeDefaultEmailArguments);
connect(m_ui->m_btnExternalEmailExecutable, &QPushButton::clicked, this, &SettingsBrowserMail::selectEmailExecutable);
}
SettingsBrowserMail::~SettingsBrowserMail() {
delete m_ui;
}
void SettingsBrowserMail::changeDefaultBrowserArguments(int index) {
if (index != 0) {
m_ui->m_txtExternalBrowserArguments->setText(m_ui->m_cmbExternalBrowserPreset->itemData(index).toString());
}
}
void SettingsBrowserMail::selectBrowserExecutable() {
const QString executable_file = QFileDialog::getOpenFileName(this,
tr("Select web browser executable"),
qApp->getHomeFolderPath(),
//: File filter for external browser selection dialog.
#if defined(Q_OS_LINUX)
tr("Executables (*)")
#else
tr("Executables (*.*)")
#endif
);
if (!executable_file.isEmpty()) {
m_ui->m_txtExternalBrowserExecutable->setText(QDir::toNativeSeparators(executable_file));
}
}
void SettingsBrowserMail::displayProxyPassword(int state) {
if (state == Qt::Checked) {
m_ui->m_txtProxyPassword->setEchoMode(QLineEdit::Normal);
}
else {
m_ui->m_txtProxyPassword->setEchoMode(QLineEdit::PasswordEchoOnEdit);
}
}
void SettingsBrowserMail::onProxyTypeChanged(int index) {
const QNetworkProxy::ProxyType selected_type = static_cast<QNetworkProxy::ProxyType>(m_ui->m_cmbProxyType->itemData(index).toInt());
const bool is_proxy_selected = selected_type != QNetworkProxy::NoProxy && selected_type != QNetworkProxy::DefaultProxy;
m_ui->m_txtProxyHost->setEnabled(is_proxy_selected);
m_ui->m_txtProxyPassword->setEnabled(is_proxy_selected);
m_ui->m_txtProxyUsername->setEnabled(is_proxy_selected);
m_ui->m_spinProxyPort->setEnabled(is_proxy_selected);
m_ui->m_checkShowPassword->setEnabled(is_proxy_selected);
m_ui->m_lblProxyHost->setEnabled(is_proxy_selected);
m_ui->m_lblProxyInfo->setEnabled(is_proxy_selected);
m_ui->m_lblProxyPassword->setEnabled(is_proxy_selected);
m_ui->m_lblProxyPort->setEnabled(is_proxy_selected);
m_ui->m_lblProxyUsername->setEnabled(is_proxy_selected);
}
void SettingsBrowserMail::changeDefaultEmailArguments(int index) {
if (index != 0) {
m_ui->m_txtExternalEmailArguments->setText(m_ui->m_cmbExternalEmailPreset->itemData(index).toString());
}
}
void SettingsBrowserMail::selectEmailExecutable() {
QString executable_file = QFileDialog::getOpenFileName(this,
tr("Select e-mail executable"),
qApp->getHomeFolderPath(),
//: File filter for external e-mail selection dialog.
#if defined(Q_OS_LINUX)
tr("Executables (*)")
#else
tr("Executables (*.*)")
#endif
);
if (!executable_file.isEmpty()) {
m_ui->m_txtExternalEmailExecutable->setText(QDir::toNativeSeparators(executable_file));
}
}
void SettingsBrowserMail::loadSettings() {
onBeginLoadSettings();
#if !defined(USE_WEBENGINE)
m_ui->m_checkOpenLinksInExternal->setChecked(settings()->value(GROUP(Browser),
SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool());
#endif
// Load settings of web browser GUI.
m_ui->m_cmbExternalBrowserPreset->addItem(tr("Opera 12 or older"), QSL("-nosession %1"));
m_ui->m_txtExternalBrowserExecutable->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserExecutable)).toString());
m_ui->m_txtExternalBrowserArguments->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserArguments)).toString());
m_ui->m_grpCustomExternalBrowser->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool());
// Load settings of e-mail.
m_ui->m_cmbExternalEmailPreset->addItem(tr("Mozilla Thunderbird"), QSL("-compose \"subject='%1',body='%2'\""));
m_ui->m_txtExternalEmailExecutable->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailExecutable)).toString());
m_ui->m_txtExternalEmailArguments->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailArguments)).toString());
m_ui->m_grpCustomExternalEmail->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailEnabled)).toBool());
m_ui->m_cmbProxyType->addItem(tr("No proxy"), QNetworkProxy::NoProxy);
m_ui->m_cmbProxyType->addItem(tr("System proxy"), QNetworkProxy::DefaultProxy);
m_ui->m_cmbProxyType->addItem(tr("Socks5"), QNetworkProxy::Socks5Proxy);
m_ui->m_cmbProxyType->addItem(tr("Http"), QNetworkProxy::HttpProxy);
// Load the settings.
QNetworkProxy::ProxyType selected_proxy_type = static_cast<QNetworkProxy::ProxyType>(settings()->value(GROUP(Proxy), SETTING(Proxy::Type)).toInt());
m_ui->m_cmbProxyType->setCurrentIndex(m_ui->m_cmbProxyType->findData(selected_proxy_type));
m_ui->m_txtProxyHost->setText(settings()->value(GROUP(Proxy), SETTING(Proxy::Host)).toString());
m_ui->m_txtProxyUsername->setText(settings()->value(GROUP(Proxy), SETTING(Proxy::Username)).toString());
m_ui->m_txtProxyPassword->setText(TextFactory::decrypt(settings()->value(GROUP(Proxy), SETTING(Proxy::Password)).toString()));
m_ui->m_spinProxyPort->setValue(settings()->value(GROUP(Proxy), SETTING(Proxy::Port)).toInt());
onEndLoadSettings();
}
void SettingsBrowserMail::saveSettings() {
onBeginSaveSettings();
#if !defined(USE_WEBENGINE)
settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, m_ui->m_checkOpenLinksInExternal->isChecked());
#endif
// Save settings of GUI of web browser.
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserEnabled, m_ui->m_grpCustomExternalBrowser->isChecked());
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserExecutable, m_ui->m_txtExternalBrowserExecutable->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserArguments, m_ui->m_txtExternalBrowserArguments->text());
// Save settings of e-mail.
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailExecutable, m_ui->m_txtExternalEmailExecutable->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailArguments, m_ui->m_txtExternalEmailArguments->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailEnabled, m_ui->m_grpCustomExternalEmail->isChecked());
settings()->setValue(GROUP(Proxy), Proxy::Type, m_ui->m_cmbProxyType->itemData(m_ui->m_cmbProxyType->currentIndex()));
settings()->setValue(GROUP(Proxy), Proxy::Host, m_ui->m_txtProxyHost->text());
settings()->setValue(GROUP(Proxy), Proxy::Username, m_ui->m_txtProxyUsername->text());
settings()->setValue(GROUP(Proxy), Proxy::Password, TextFactory::encrypt(m_ui->m_txtProxyPassword->text()));
settings()->setValue(GROUP(Proxy), Proxy::Port, m_ui->m_spinProxyPort->value());
// Reload settings for all network access managers.
SilentNetworkAccessManager::instance()->loadSettings();
onEndSaveSettings();
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsbrowsermail.h"
#include "network-web/silentnetworkaccessmanager.h"
#include "miscellaneous/application.h"
#include "miscellaneous/textfactory.h"
#include "gui/guiutilities.h"
#include <QNetworkProxy>
#include <QFileDialog>
SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) {
m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(m_ui->label, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblExternalEmailInfo, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblProxyInfo, false);
#if defined(USE_WEBENGINE)
m_ui->m_checkOpenLinksInExternal->setVisible(false);
#else
connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
#endif
connect(m_ui->m_cmbProxyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtProxyHost, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtProxyPassword, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtProxyUsername, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_spinProxyPort, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_grpCustomExternalBrowser, &QGroupBox::toggled, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_grpCustomExternalEmail, &QGroupBox::toggled, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalBrowserArguments, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalBrowserExecutable, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalEmailArguments, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalEmailExecutable, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_cmbProxyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::onProxyTypeChanged);
connect(m_ui->m_checkShowPassword, &QCheckBox::stateChanged, this, &SettingsBrowserMail::displayProxyPassword);
connect(m_ui->m_cmbExternalBrowserPreset, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::changeDefaultBrowserArguments);
connect(m_ui->m_btnExternalBrowserExecutable, &QPushButton::clicked, this, &SettingsBrowserMail::selectBrowserExecutable);
connect(m_ui->m_cmbExternalEmailPreset, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::changeDefaultEmailArguments);
connect(m_ui->m_btnExternalEmailExecutable, &QPushButton::clicked, this, &SettingsBrowserMail::selectEmailExecutable);
}
SettingsBrowserMail::~SettingsBrowserMail() {
delete m_ui;
}
void SettingsBrowserMail::changeDefaultBrowserArguments(int index) {
if (index != 0) {
m_ui->m_txtExternalBrowserArguments->setText(m_ui->m_cmbExternalBrowserPreset->itemData(index).toString());
}
}
void SettingsBrowserMail::selectBrowserExecutable() {
const QString executable_file = QFileDialog::getOpenFileName(this,
tr("Select web browser executable"),
qApp->getHomeFolderPath(),
//: File filter for external browser selection dialog.
#if defined(Q_OS_LINUX)
tr("Executables (*)")
#else
tr("Executables (*.*)")
#endif
);
if (!executable_file.isEmpty()) {
m_ui->m_txtExternalBrowserExecutable->setText(QDir::toNativeSeparators(executable_file));
}
}
void SettingsBrowserMail::displayProxyPassword(int state) {
if (state == Qt::Checked) {
m_ui->m_txtProxyPassword->setEchoMode(QLineEdit::Normal);
}
else {
m_ui->m_txtProxyPassword->setEchoMode(QLineEdit::PasswordEchoOnEdit);
}
}
void SettingsBrowserMail::onProxyTypeChanged(int index) {
const QNetworkProxy::ProxyType selected_type = static_cast<QNetworkProxy::ProxyType>(m_ui->m_cmbProxyType->itemData(index).toInt());
const bool is_proxy_selected = selected_type != QNetworkProxy::NoProxy && selected_type != QNetworkProxy::DefaultProxy;
m_ui->m_txtProxyHost->setEnabled(is_proxy_selected);
m_ui->m_txtProxyPassword->setEnabled(is_proxy_selected);
m_ui->m_txtProxyUsername->setEnabled(is_proxy_selected);
m_ui->m_spinProxyPort->setEnabled(is_proxy_selected);
m_ui->m_checkShowPassword->setEnabled(is_proxy_selected);
m_ui->m_lblProxyHost->setEnabled(is_proxy_selected);
m_ui->m_lblProxyInfo->setEnabled(is_proxy_selected);
m_ui->m_lblProxyPassword->setEnabled(is_proxy_selected);
m_ui->m_lblProxyPort->setEnabled(is_proxy_selected);
m_ui->m_lblProxyUsername->setEnabled(is_proxy_selected);
}
void SettingsBrowserMail::changeDefaultEmailArguments(int index) {
if (index != 0) {
m_ui->m_txtExternalEmailArguments->setText(m_ui->m_cmbExternalEmailPreset->itemData(index).toString());
}
}
void SettingsBrowserMail::selectEmailExecutable() {
QString executable_file = QFileDialog::getOpenFileName(this,
tr("Select e-mail executable"),
qApp->getHomeFolderPath(),
//: File filter for external e-mail selection dialog.
#if defined(Q_OS_LINUX)
tr("Executables (*)")
#else
tr("Executables (*.*)")
#endif
);
if (!executable_file.isEmpty()) {
m_ui->m_txtExternalEmailExecutable->setText(QDir::toNativeSeparators(executable_file));
}
}
void SettingsBrowserMail::loadSettings() {
onBeginLoadSettings();
#if !defined(USE_WEBENGINE)
m_ui->m_checkOpenLinksInExternal->setChecked(settings()->value(GROUP(Browser),
SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool());
#endif
// Load settings of web browser GUI.
m_ui->m_cmbExternalBrowserPreset->addItem(tr("Opera 12 or older"), QSL("-nosession %1"));
m_ui->m_txtExternalBrowserExecutable->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserExecutable)).toString());
m_ui->m_txtExternalBrowserArguments->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserArguments)).toString());
m_ui->m_grpCustomExternalBrowser->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool());
// Load settings of e-mail.
m_ui->m_cmbExternalEmailPreset->addItem(tr("Mozilla Thunderbird"), QSL("-compose \"subject='%1',body='%2'\""));
m_ui->m_txtExternalEmailExecutable->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailExecutable)).toString());
m_ui->m_txtExternalEmailArguments->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailArguments)).toString());
m_ui->m_grpCustomExternalEmail->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailEnabled)).toBool());
m_ui->m_cmbProxyType->addItem(tr("No proxy"), QNetworkProxy::NoProxy);
m_ui->m_cmbProxyType->addItem(tr("System proxy"), QNetworkProxy::DefaultProxy);
m_ui->m_cmbProxyType->addItem(tr("Socks5"), QNetworkProxy::Socks5Proxy);
m_ui->m_cmbProxyType->addItem(tr("Http"), QNetworkProxy::HttpProxy);
// Load the settings.
QNetworkProxy::ProxyType selected_proxy_type = static_cast<QNetworkProxy::ProxyType>(settings()->value(GROUP(Proxy), SETTING(Proxy::Type)).toInt());
m_ui->m_cmbProxyType->setCurrentIndex(m_ui->m_cmbProxyType->findData(selected_proxy_type));
m_ui->m_txtProxyHost->setText(settings()->value(GROUP(Proxy), SETTING(Proxy::Host)).toString());
m_ui->m_txtProxyUsername->setText(settings()->value(GROUP(Proxy), SETTING(Proxy::Username)).toString());
m_ui->m_txtProxyPassword->setText(TextFactory::decrypt(settings()->value(GROUP(Proxy), SETTING(Proxy::Password)).toString()));
m_ui->m_spinProxyPort->setValue(settings()->value(GROUP(Proxy), SETTING(Proxy::Port)).toInt());
onEndLoadSettings();
}
void SettingsBrowserMail::saveSettings() {
onBeginSaveSettings();
#if !defined(USE_WEBENGINE)
settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, m_ui->m_checkOpenLinksInExternal->isChecked());
#endif
// Save settings of GUI of web browser.
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserEnabled, m_ui->m_grpCustomExternalBrowser->isChecked());
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserExecutable, m_ui->m_txtExternalBrowserExecutable->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserArguments, m_ui->m_txtExternalBrowserArguments->text());
// Save settings of e-mail.
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailExecutable, m_ui->m_txtExternalEmailExecutable->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailArguments, m_ui->m_txtExternalEmailArguments->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailEnabled, m_ui->m_grpCustomExternalEmail->isChecked());
settings()->setValue(GROUP(Proxy), Proxy::Type, m_ui->m_cmbProxyType->itemData(m_ui->m_cmbProxyType->currentIndex()));
settings()->setValue(GROUP(Proxy), Proxy::Host, m_ui->m_txtProxyHost->text());
settings()->setValue(GROUP(Proxy), Proxy::Username, m_ui->m_txtProxyUsername->text());
settings()->setValue(GROUP(Proxy), Proxy::Password, TextFactory::encrypt(m_ui->m_txtProxyPassword->text()));
settings()->setValue(GROUP(Proxy), Proxy::Port, m_ui->m_spinProxyPort->value());
// Reload settings for all network access managers.
SilentNetworkAccessManager::instance()->loadSettings();
onEndSaveSettings();
}

View File

@ -1,52 +1,52 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 SETTINGSBROWSERMAIL_H
#define SETTINGSBROWSERMAIL_H
#include "gui/settings/settingspanel.h"
#include "ui_settingsbrowsermail.h"
class SettingsBrowserMail : public SettingsPanel {
Q_OBJECT
public:
explicit SettingsBrowserMail(Settings *settings, QWidget *parent = 0);
virtual ~SettingsBrowserMail();
inline QString title() const {
return tr("Web browser & e-mail & proxy");
}
void loadSettings();
void saveSettings();
private slots:
void changeDefaultBrowserArguments(int index);
void selectBrowserExecutable();
void changeDefaultEmailArguments(int index);
void selectEmailExecutable();
void displayProxyPassword(int state);
void onProxyTypeChanged(int index);
private:
Ui::SettingsBrowserMail *m_ui;
};
#endif // SETTINGSBROWSERMAIL_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 SETTINGSBROWSERMAIL_H
#define SETTINGSBROWSERMAIL_H
#include "gui/settings/settingspanel.h"
#include "ui_settingsbrowsermail.h"
class SettingsBrowserMail : public SettingsPanel {
Q_OBJECT
public:
explicit SettingsBrowserMail(Settings* settings, QWidget* parent = 0);
virtual ~SettingsBrowserMail();
inline QString title() const {
return tr("Web browser & e-mail & proxy");
}
void loadSettings();
void saveSettings();
private slots:
void changeDefaultBrowserArguments(int index);
void selectBrowserExecutable();
void changeDefaultEmailArguments(int index);
void selectEmailExecutable();
void displayProxyPassword(int state);
void onProxyTypeChanged(int index);
private:
Ui::SettingsBrowserMail* m_ui;
};
#endif // SETTINGSBROWSERMAIL_H

View File

@ -1,216 +1,206 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsdatabase.h"
#include "miscellaneous/databasefactory.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "miscellaneous/textfactory.h"
#include "gui/guiutilities.h"
SettingsDatabase::SettingsDatabase(Settings *settings, QWidget *parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsDatabase) {
m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(m_ui->m_lblDataStorageWarning, true);
GuiUtilities::setLabelAsNotice(m_ui->m_lblMysqlInfo, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblSqliteInMemoryWarnings, true);
connect(m_ui->m_cmbDatabaseDriver, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_checkSqliteUseInMemoryDatabase, &QCheckBox::toggled, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlDatabase->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlHostname->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlPassword->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_checkUseTransactions, &QCheckBox::toggled, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlUsername->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_spinMysqlPort, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_cmbDatabaseDriver, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsDatabase::selectSqlBackend);
connect(m_ui->m_checkMysqlShowPassword, &QCheckBox::toggled, this, &SettingsDatabase::switchMysqlPasswordVisiblity);
connect(m_ui->m_txtMysqlUsername->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlUsernameChanged);
connect(m_ui->m_txtMysqlHostname->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlHostnameChanged);
connect(m_ui->m_txtMysqlPassword->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlPasswordChanged);
connect(m_ui->m_txtMysqlDatabase->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlDatabaseChanged);
connect(m_ui->m_btnMysqlTestSetup, &QPushButton::clicked, this, &SettingsDatabase::mysqlTestConnection);
connect(m_ui->m_cmbDatabaseDriver, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsDatabase::requireRestart);
connect(m_ui->m_checkSqliteUseInMemoryDatabase, &QCheckBox::toggled, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_spinMysqlPort, &QSpinBox::editingFinished, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_txtMysqlHostname->lineEdit(), &BaseLineEdit::textEdited, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_txtMysqlPassword->lineEdit(), &BaseLineEdit::textEdited, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_txtMysqlUsername->lineEdit(), &BaseLineEdit::textEdited, this, &SettingsDatabase::requireRestart);
}
SettingsDatabase::~SettingsDatabase() {
delete m_ui;
}
void SettingsDatabase::mysqlTestConnection() {
const DatabaseFactory::MySQLError error_code = qApp->database()->mysqlTestConnection(m_ui->m_txtMysqlHostname->lineEdit()->text(),
m_ui->m_spinMysqlPort->value(),
m_ui->m_txtMysqlDatabase->lineEdit()->text(),
m_ui->m_txtMysqlUsername->lineEdit()->text(),
m_ui->m_txtMysqlPassword->lineEdit()->text());
const QString interpretation = qApp->database()->mysqlInterpretErrorCode(error_code);
switch (error_code) {
case DatabaseFactory::MySQLOk:
case DatabaseFactory::MySQLUnknownDatabase:
m_ui->m_lblMysqlTestResult->setStatus(WidgetWithStatus::Ok, interpretation, interpretation);
break;
default:
m_ui->m_lblMysqlTestResult->setStatus(WidgetWithStatus::Error, interpretation, interpretation);
break;
}
}
void SettingsDatabase::onMysqlHostnameChanged(const QString &new_hostname) {
if (new_hostname.isEmpty()) {
m_ui->m_txtMysqlHostname->setStatus(LineEditWithStatus::Warning, tr("Hostname is empty."));
}
else {
m_ui->m_txtMysqlHostname->setStatus(LineEditWithStatus::Ok, tr("Hostname looks ok."));
}
}
void SettingsDatabase::onMysqlUsernameChanged(const QString &new_username) {
if (new_username.isEmpty()) {
m_ui->m_txtMysqlUsername->setStatus(LineEditWithStatus::Warning, tr("Username is empty."));
}
else {
m_ui->m_txtMysqlUsername->setStatus(LineEditWithStatus::Ok, tr("Username looks ok."));
}
}
void SettingsDatabase::onMysqlPasswordChanged(const QString &new_password) {
if (new_password.isEmpty()) {
m_ui->m_txtMysqlPassword->setStatus(LineEditWithStatus::Warning, tr("Password is empty."));
}
else {
m_ui->m_txtMysqlPassword->setStatus(LineEditWithStatus::Ok, tr("Password looks ok."));
}
}
void SettingsDatabase::onMysqlDatabaseChanged(const QString &new_database) {
if (new_database.isEmpty()) {
m_ui->m_txtMysqlDatabase->setStatus(LineEditWithStatus::Warning, tr("Working database is empty."));
}
else {
m_ui->m_txtMysqlDatabase->setStatus(LineEditWithStatus::Ok, tr("Working database is ok."));
}
}
void SettingsDatabase::selectSqlBackend(int index) {
const QString selected_db_driver = m_ui->m_cmbDatabaseDriver->itemData(index).toString();
if (selected_db_driver == APP_DB_SQLITE_DRIVER) {
m_ui->m_stackedDatabaseDriver->setCurrentIndex(0);
}
else if (selected_db_driver == APP_DB_MYSQL_DRIVER) {
m_ui->m_stackedDatabaseDriver->setCurrentIndex(1);
}
else {
qWarning("GUI for given database driver '%s' is not available.", qPrintable(selected_db_driver));
}
}
void SettingsDatabase::switchMysqlPasswordVisiblity(bool visible) {
m_ui->m_txtMysqlPassword->lineEdit()->setEchoMode(visible ? QLineEdit::Normal : QLineEdit::Password);
}
void SettingsDatabase::loadSettings() {
onBeginLoadSettings();
m_ui->m_checkUseTransactions->setChecked(qApp->settings()->value(GROUP(Database), SETTING(Database::UseTransactions)).toBool());
m_ui->m_lblMysqlTestResult->setStatus(WidgetWithStatus::Information, tr("No connection test triggered so far."), tr("You did not executed any connection test yet."));
// Load SQLite.
m_ui->m_cmbDatabaseDriver->addItem(qApp->database()->humanDriverName(DatabaseFactory::SQLITE), APP_DB_SQLITE_DRIVER);
// Load in-memory database status.
m_ui->m_checkSqliteUseInMemoryDatabase->setChecked(settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool());
if (QSqlDatabase::isDriverAvailable(APP_DB_MYSQL_DRIVER)) {
onMysqlHostnameChanged(QString());
onMysqlUsernameChanged(QString());
onMysqlPasswordChanged(QString());
onMysqlDatabaseChanged(QString());
// Load MySQL.
m_ui->m_cmbDatabaseDriver->addItem(qApp->database()->humanDriverName(DatabaseFactory::MYSQL), APP_DB_MYSQL_DRIVER);
// Setup placeholders.
m_ui->m_txtMysqlHostname->lineEdit()->setPlaceholderText(tr("Hostname of your MySQL server"));
m_ui->m_txtMysqlUsername->lineEdit()->setPlaceholderText(tr("Username to login with"));
m_ui->m_txtMysqlPassword->lineEdit()->setPlaceholderText(tr("Password for your username"));
m_ui->m_txtMysqlDatabase->lineEdit()->setPlaceholderText(tr("Working database which you have full access to."));
m_ui->m_txtMysqlHostname->lineEdit()->setText(settings()->value(GROUP(Database), SETTING(Database::MySQLHostname)).toString());
m_ui->m_txtMysqlUsername->lineEdit()->setText(settings()->value(GROUP(Database), SETTING(Database::MySQLUsername)).toString());
m_ui->m_txtMysqlPassword->lineEdit()->setText(TextFactory::decrypt(settings()->value(GROUP(Database), SETTING(Database::MySQLPassword)).toString()));
m_ui->m_txtMysqlDatabase->lineEdit()->setText(settings()->value(GROUP(Database), SETTING(Database::MySQLDatabase)).toString());
m_ui->m_spinMysqlPort->setValue(settings()->value(GROUP(Database), SETTING(Database::MySQLPort)).toInt());
m_ui->m_checkMysqlShowPassword->setChecked(false);
}
int index_current_backend = m_ui->m_cmbDatabaseDriver->findData(settings()->value(GROUP(Database), SETTING(Database::ActiveDriver)).toString());
if (index_current_backend >= 0) {
m_ui->m_cmbDatabaseDriver->setCurrentIndex(index_current_backend);
}
onEndLoadSettings();
}
void SettingsDatabase::saveSettings() {
onBeginSaveSettings();
// Setup in-memory database status.
const bool original_inmemory = settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool();
const bool new_inmemory = m_ui->m_checkSqliteUseInMemoryDatabase->isChecked();
qApp->settings()->setValue(GROUP(Database), Database::UseTransactions, m_ui->m_checkUseTransactions->isChecked());
// Save data storage settings.
QString original_db_driver = settings()->value(GROUP(Database), SETTING(Database::ActiveDriver)).toString();
QString selected_db_driver = m_ui->m_cmbDatabaseDriver->itemData(m_ui->m_cmbDatabaseDriver->currentIndex()).toString();
// Save SQLite.
settings()->setValue(GROUP(Database), Database::UseInMemory, new_inmemory);
if (QSqlDatabase::isDriverAvailable(APP_DB_MYSQL_DRIVER)) {
// Save MySQL.
settings()->setValue(GROUP(Database), Database::MySQLHostname, m_ui->m_txtMysqlHostname->lineEdit()->text());
settings()->setValue(GROUP(Database), Database::MySQLUsername, m_ui->m_txtMysqlUsername->lineEdit()->text());
settings()->setValue(GROUP(Database), Database::MySQLPassword, TextFactory::encrypt(m_ui->m_txtMysqlPassword->lineEdit()->text()));
settings()->setValue(GROUP(Database), Database::MySQLDatabase, m_ui->m_txtMysqlDatabase->lineEdit()->text());
settings()->setValue(GROUP(Database), Database::MySQLPort, m_ui->m_spinMysqlPort->value());
}
settings()->setValue(GROUP(Database), Database::ActiveDriver, selected_db_driver);
if (original_db_driver != selected_db_driver || original_inmemory != new_inmemory) {
requireRestart();
}
onEndSaveSettings();
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsdatabase.h"
#include "miscellaneous/databasefactory.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "miscellaneous/textfactory.h"
#include "gui/guiutilities.h"
SettingsDatabase::SettingsDatabase(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsDatabase) {
m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(m_ui->m_lblDataStorageWarning, true);
GuiUtilities::setLabelAsNotice(m_ui->m_lblMysqlInfo, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblSqliteInMemoryWarnings, true);
connect(m_ui->m_cmbDatabaseDriver, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_checkSqliteUseInMemoryDatabase, &QCheckBox::toggled, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlDatabase->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlHostname->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlPassword->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_checkUseTransactions, &QCheckBox::toggled, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlUsername->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_spinMysqlPort, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_cmbDatabaseDriver, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsDatabase::selectSqlBackend);
connect(m_ui->m_checkMysqlShowPassword, &QCheckBox::toggled, this, &SettingsDatabase::switchMysqlPasswordVisiblity);
connect(m_ui->m_txtMysqlUsername->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlUsernameChanged);
connect(m_ui->m_txtMysqlHostname->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlHostnameChanged);
connect(m_ui->m_txtMysqlPassword->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlPasswordChanged);
connect(m_ui->m_txtMysqlDatabase->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlDatabaseChanged);
connect(m_ui->m_btnMysqlTestSetup, &QPushButton::clicked, this, &SettingsDatabase::mysqlTestConnection);
connect(m_ui->m_cmbDatabaseDriver, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsDatabase::requireRestart);
connect(m_ui->m_checkSqliteUseInMemoryDatabase, &QCheckBox::toggled, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_spinMysqlPort, &QSpinBox::editingFinished, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_txtMysqlHostname->lineEdit(), &BaseLineEdit::textEdited, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_txtMysqlPassword->lineEdit(), &BaseLineEdit::textEdited, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_txtMysqlUsername->lineEdit(), &BaseLineEdit::textEdited, this, &SettingsDatabase::requireRestart);
}
SettingsDatabase::~SettingsDatabase() {
delete m_ui;
}
void SettingsDatabase::mysqlTestConnection() {
const DatabaseFactory::MySQLError error_code = qApp->database()->mysqlTestConnection(m_ui->m_txtMysqlHostname->lineEdit()->text(),
m_ui->m_spinMysqlPort->value(),
m_ui->m_txtMysqlDatabase->lineEdit()->text(),
m_ui->m_txtMysqlUsername->lineEdit()->text(),
m_ui->m_txtMysqlPassword->lineEdit()->text());
const QString interpretation = qApp->database()->mysqlInterpretErrorCode(error_code);
switch (error_code) {
case DatabaseFactory::MySQLOk:
case DatabaseFactory::MySQLUnknownDatabase:
m_ui->m_lblMysqlTestResult->setStatus(WidgetWithStatus::Ok, interpretation, interpretation);
break;
default:
m_ui->m_lblMysqlTestResult->setStatus(WidgetWithStatus::Error, interpretation, interpretation);
break;
}
}
void SettingsDatabase::onMysqlHostnameChanged(const QString& new_hostname) {
if (new_hostname.isEmpty()) {
m_ui->m_txtMysqlHostname->setStatus(LineEditWithStatus::Warning, tr("Hostname is empty."));
}
else {
m_ui->m_txtMysqlHostname->setStatus(LineEditWithStatus::Ok, tr("Hostname looks ok."));
}
}
void SettingsDatabase::onMysqlUsernameChanged(const QString& new_username) {
if (new_username.isEmpty()) {
m_ui->m_txtMysqlUsername->setStatus(LineEditWithStatus::Warning, tr("Username is empty."));
}
else {
m_ui->m_txtMysqlUsername->setStatus(LineEditWithStatus::Ok, tr("Username looks ok."));
}
}
void SettingsDatabase::onMysqlPasswordChanged(const QString& new_password) {
if (new_password.isEmpty()) {
m_ui->m_txtMysqlPassword->setStatus(LineEditWithStatus::Warning, tr("Password is empty."));
}
else {
m_ui->m_txtMysqlPassword->setStatus(LineEditWithStatus::Ok, tr("Password looks ok."));
}
}
void SettingsDatabase::onMysqlDatabaseChanged(const QString& new_database) {
if (new_database.isEmpty()) {
m_ui->m_txtMysqlDatabase->setStatus(LineEditWithStatus::Warning, tr("Working database is empty."));
}
else {
m_ui->m_txtMysqlDatabase->setStatus(LineEditWithStatus::Ok, tr("Working database is ok."));
}
}
void SettingsDatabase::selectSqlBackend(int index) {
const QString selected_db_driver = m_ui->m_cmbDatabaseDriver->itemData(index).toString();
if (selected_db_driver == APP_DB_SQLITE_DRIVER) {
m_ui->m_stackedDatabaseDriver->setCurrentIndex(0);
}
else if (selected_db_driver == APP_DB_MYSQL_DRIVER) {
m_ui->m_stackedDatabaseDriver->setCurrentIndex(1);
}
else {
qWarning("GUI for given database driver '%s' is not available.", qPrintable(selected_db_driver));
}
}
void SettingsDatabase::switchMysqlPasswordVisiblity(bool visible) {
m_ui->m_txtMysqlPassword->lineEdit()->setEchoMode(visible ? QLineEdit::Normal : QLineEdit::Password);
}
void SettingsDatabase::loadSettings() {
onBeginLoadSettings();
m_ui->m_checkUseTransactions->setChecked(qApp->settings()->value(GROUP(Database), SETTING(Database::UseTransactions)).toBool());
m_ui->m_lblMysqlTestResult->setStatus(WidgetWithStatus::Information, tr("No connection test triggered so far."), tr("You did not executed any connection test yet."));
// Load SQLite.
m_ui->m_cmbDatabaseDriver->addItem(qApp->database()->humanDriverName(DatabaseFactory::SQLITE), APP_DB_SQLITE_DRIVER);
// Load in-memory database status.
m_ui->m_checkSqliteUseInMemoryDatabase->setChecked(settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool());
if (QSqlDatabase::isDriverAvailable(APP_DB_MYSQL_DRIVER)) {
onMysqlHostnameChanged(QString());
onMysqlUsernameChanged(QString());
onMysqlPasswordChanged(QString());
onMysqlDatabaseChanged(QString());
// Load MySQL.
m_ui->m_cmbDatabaseDriver->addItem(qApp->database()->humanDriverName(DatabaseFactory::MYSQL), APP_DB_MYSQL_DRIVER);
// Setup placeholders.
m_ui->m_txtMysqlHostname->lineEdit()->setPlaceholderText(tr("Hostname of your MySQL server"));
m_ui->m_txtMysqlUsername->lineEdit()->setPlaceholderText(tr("Username to login with"));
m_ui->m_txtMysqlPassword->lineEdit()->setPlaceholderText(tr("Password for your username"));
m_ui->m_txtMysqlDatabase->lineEdit()->setPlaceholderText(tr("Working database which you have full access to."));
m_ui->m_txtMysqlHostname->lineEdit()->setText(settings()->value(GROUP(Database), SETTING(Database::MySQLHostname)).toString());
m_ui->m_txtMysqlUsername->lineEdit()->setText(settings()->value(GROUP(Database), SETTING(Database::MySQLUsername)).toString());
m_ui->m_txtMysqlPassword->lineEdit()->setText(TextFactory::decrypt(settings()->value(GROUP(Database), SETTING(Database::MySQLPassword)).toString()));
m_ui->m_txtMysqlDatabase->lineEdit()->setText(settings()->value(GROUP(Database), SETTING(Database::MySQLDatabase)).toString());
m_ui->m_spinMysqlPort->setValue(settings()->value(GROUP(Database), SETTING(Database::MySQLPort)).toInt());
m_ui->m_checkMysqlShowPassword->setChecked(false);
}
int index_current_backend = m_ui->m_cmbDatabaseDriver->findData(settings()->value(GROUP(Database), SETTING(Database::ActiveDriver)).toString());
if (index_current_backend >= 0) {
m_ui->m_cmbDatabaseDriver->setCurrentIndex(index_current_backend);
}
onEndLoadSettings();
}
void SettingsDatabase::saveSettings() {
onBeginSaveSettings();
// Setup in-memory database status.
const bool original_inmemory = settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool();
const bool new_inmemory = m_ui->m_checkSqliteUseInMemoryDatabase->isChecked();
qApp->settings()->setValue(GROUP(Database), Database::UseTransactions, m_ui->m_checkUseTransactions->isChecked());
// Save data storage settings.
QString original_db_driver = settings()->value(GROUP(Database), SETTING(Database::ActiveDriver)).toString();
QString selected_db_driver = m_ui->m_cmbDatabaseDriver->itemData(m_ui->m_cmbDatabaseDriver->currentIndex()).toString();
// Save SQLite.
settings()->setValue(GROUP(Database), Database::UseInMemory, new_inmemory);
if (QSqlDatabase::isDriverAvailable(APP_DB_MYSQL_DRIVER)) {
// Save MySQL.
settings()->setValue(GROUP(Database), Database::MySQLHostname, m_ui->m_txtMysqlHostname->lineEdit()->text());
settings()->setValue(GROUP(Database), Database::MySQLUsername, m_ui->m_txtMysqlUsername->lineEdit()->text());
settings()->setValue(GROUP(Database), Database::MySQLPassword, TextFactory::encrypt(m_ui->m_txtMysqlPassword->lineEdit()->text()));
settings()->setValue(GROUP(Database), Database::MySQLDatabase, m_ui->m_txtMysqlDatabase->lineEdit()->text());
settings()->setValue(GROUP(Database), Database::MySQLPort, m_ui->m_spinMysqlPort->value());
}
settings()->setValue(GROUP(Database), Database::ActiveDriver, selected_db_driver);
if (original_db_driver != selected_db_driver || original_inmemory != new_inmemory) {
requireRestart();
}
onEndSaveSettings();
}

View File

@ -1,52 +1,52 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 SETTINGSDATABASE_H
#define SETTINGSDATABASE_H
#include "gui/settings/settingspanel.h"
#include "ui_settingsdatabase.h"
class SettingsDatabase : public SettingsPanel {
Q_OBJECT
public:
explicit SettingsDatabase(Settings *settings, QWidget *parent = 0);
virtual ~SettingsDatabase();
inline QString title() const {
return tr("Data storage");
}
void loadSettings();
void saveSettings();
private:
void mysqlTestConnection();
void onMysqlHostnameChanged(const QString &new_hostname);
void onMysqlUsernameChanged(const QString &new_username);
void onMysqlPasswordChanged(const QString &new_password);
void onMysqlDatabaseChanged(const QString &new_database);
void selectSqlBackend(int index);
void switchMysqlPasswordVisiblity(bool visible);
Ui::SettingsDatabase *m_ui;
};
#endif // SETTINGSDATABASE_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 SETTINGSDATABASE_H
#define SETTINGSDATABASE_H
#include "gui/settings/settingspanel.h"
#include "ui_settingsdatabase.h"
class SettingsDatabase : public SettingsPanel {
Q_OBJECT
public:
explicit SettingsDatabase(Settings* settings, QWidget* parent = 0);
virtual ~SettingsDatabase();
inline QString title() const {
return tr("Data storage");
}
void loadSettings();
void saveSettings();
private:
void mysqlTestConnection();
void onMysqlHostnameChanged(const QString& new_hostname);
void onMysqlUsernameChanged(const QString& new_username);
void onMysqlPasswordChanged(const QString& new_password);
void onMysqlDatabaseChanged(const QString& new_database);
void selectSqlBackend(int index);
void switchMysqlPasswordVisiblity(bool visible);
Ui::SettingsDatabase* m_ui;
};
#endif // SETTINGSDATABASE_H

View File

@ -1,75 +1,69 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsdownloads.h"
#include "miscellaneous/settings.h"
#include "network-web/downloadmanager.h"
#include "miscellaneous/application.h"
#include <QFileDialog>
SettingsDownloads::SettingsDownloads(Settings *settings, QWidget *parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsDownloads) {
m_ui->setupUi(this);
connect(m_ui->m_checkOpenManagerWhenDownloadStarts, &QCheckBox::toggled, this, &SettingsDownloads::dirtifySettings);
connect(m_ui->m_txtDownloadsTargetDirectory, &QLineEdit::textChanged, this, &SettingsDownloads::dirtifySettings);
connect(m_ui->m_rbDownloadsAskEachFile, &QRadioButton::toggled, this, &SettingsDownloads::dirtifySettings);
connect(m_ui->m_btnDownloadsTargetDirectory, &QPushButton::clicked, this, &SettingsDownloads::selectDownloadsDirectory);
}
SettingsDownloads::~SettingsDownloads() {
delete m_ui;
}
void SettingsDownloads::selectDownloadsDirectory() {
const QString target_directory = QFileDialog::getExistingDirectory(this,
tr("Select downloads target directory"),
m_ui->m_txtDownloadsTargetDirectory->text()
);
if (!target_directory.isEmpty()) {
m_ui->m_txtDownloadsTargetDirectory->setText(QDir::toNativeSeparators(target_directory));
}
}
void SettingsDownloads::loadSettings() {
onBeginLoadSettings();
m_ui->m_checkOpenManagerWhenDownloadStarts->setChecked(settings()->value(GROUP(Downloads),
SETTING(Downloads::ShowDownloadsWhenNewDownloadStarts)).toBool());
m_ui->m_txtDownloadsTargetDirectory->setText(QDir::toNativeSeparators(settings()->value(GROUP(Downloads),
SETTING(Downloads::TargetDirectory)).toString()));
m_ui->m_rbDownloadsAskEachFile->setChecked(settings()->value(GROUP(Downloads),
SETTING(Downloads::AlwaysPromptForFilename)).toBool());
onEndLoadSettings();
}
void SettingsDownloads::saveSettings() {
onBeginSaveSettings();
settings()->setValue(GROUP(Downloads), Downloads::ShowDownloadsWhenNewDownloadStarts, m_ui->m_checkOpenManagerWhenDownloadStarts->isChecked());
settings()->setValue(GROUP(Downloads), Downloads::TargetDirectory, m_ui->m_txtDownloadsTargetDirectory->text());
settings()->setValue(GROUP(Downloads), Downloads::AlwaysPromptForFilename, m_ui->m_rbDownloadsAskEachFile->isChecked());
qApp->downloadManager()->setDownloadDirectory(m_ui->m_txtDownloadsTargetDirectory->text());
onEndSaveSettings();
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsdownloads.h"
#include "miscellaneous/settings.h"
#include "network-web/downloadmanager.h"
#include "miscellaneous/application.h"
#include <QFileDialog>
SettingsDownloads::SettingsDownloads(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsDownloads) {
m_ui->setupUi(this);
connect(m_ui->m_checkOpenManagerWhenDownloadStarts, &QCheckBox::toggled, this, &SettingsDownloads::dirtifySettings);
connect(m_ui->m_txtDownloadsTargetDirectory, &QLineEdit::textChanged, this, &SettingsDownloads::dirtifySettings);
connect(m_ui->m_rbDownloadsAskEachFile, &QRadioButton::toggled, this, &SettingsDownloads::dirtifySettings);
connect(m_ui->m_btnDownloadsTargetDirectory, &QPushButton::clicked, this, &SettingsDownloads::selectDownloadsDirectory);
}
SettingsDownloads::~SettingsDownloads() {
delete m_ui;
}
void SettingsDownloads::selectDownloadsDirectory() {
const QString target_directory = QFileDialog::getExistingDirectory(this,
tr("Select downloads target directory"),
m_ui->m_txtDownloadsTargetDirectory->text()
);
if (!target_directory.isEmpty()) {
m_ui->m_txtDownloadsTargetDirectory->setText(QDir::toNativeSeparators(target_directory));
}
}
void SettingsDownloads::loadSettings() {
onBeginLoadSettings();
m_ui->m_checkOpenManagerWhenDownloadStarts->setChecked(settings()->value(GROUP(Downloads),
SETTING(Downloads::ShowDownloadsWhenNewDownloadStarts)).toBool());
m_ui->m_txtDownloadsTargetDirectory->setText(QDir::toNativeSeparators(settings()->value(GROUP(Downloads),
SETTING(Downloads::TargetDirectory)).toString()));
m_ui->m_rbDownloadsAskEachFile->setChecked(settings()->value(GROUP(Downloads),
SETTING(Downloads::AlwaysPromptForFilename)).toBool());
onEndLoadSettings();
}
void SettingsDownloads::saveSettings() {
onBeginSaveSettings();
settings()->setValue(GROUP(Downloads), Downloads::ShowDownloadsWhenNewDownloadStarts, m_ui->m_checkOpenManagerWhenDownloadStarts->isChecked());
settings()->setValue(GROUP(Downloads), Downloads::TargetDirectory, m_ui->m_txtDownloadsTargetDirectory->text());
settings()->setValue(GROUP(Downloads), Downloads::AlwaysPromptForFilename, m_ui->m_rbDownloadsAskEachFile->isChecked());
qApp->downloadManager()->setDownloadDirectory(m_ui->m_txtDownloadsTargetDirectory->text());
onEndSaveSettings();
}

View File

@ -1,47 +1,47 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 SETTINGSDOWNLOADS_H
#define SETTINGSDOWNLOADS_H
#include "gui/settings/settingspanel.h"
#include "ui_settingsdownloads.h"
class SettingsDownloads : public SettingsPanel {
Q_OBJECT
public:
explicit SettingsDownloads(Settings *settings, QWidget *parent = 0);
virtual ~SettingsDownloads();
inline QString title() const {
return tr("Downloads");
}
void loadSettings();
void saveSettings();
private slots:
void selectDownloadsDirectory();
private:
Ui::SettingsDownloads *m_ui;
};
#endif // SETTINGSDOWNLOADS_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 SETTINGSDOWNLOADS_H
#define SETTINGSDOWNLOADS_H
#include "gui/settings/settingspanel.h"
#include "ui_settingsdownloads.h"
class SettingsDownloads : public SettingsPanel {
Q_OBJECT
public:
explicit SettingsDownloads(Settings* settings, QWidget* parent = 0);
virtual ~SettingsDownloads();
inline QString title() const {
return tr("Downloads");
}
void loadSettings();
void saveSettings();
private slots:
void selectDownloadsDirectory();
private:
Ui::SettingsDownloads* m_ui;
};
#endif // SETTINGSDOWNLOADS_H

View File

@ -1,150 +1,139 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsfeedsmessages.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "miscellaneous/feedreader.h"
#include "gui/dialogs/formmain.h"
#include "gui/feedmessageviewer.h"
#include "gui/feedsview.h"
#include "gui/messagesview.h"
#include "gui/timespinbox.h"
#include "gui/guiutilities.h"
#include <QFontDialog>
SettingsFeedsMessages::SettingsFeedsMessages(Settings *settings, QWidget *parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsFeedsMessages){
m_ui->setupUi(this);
initializeMessageDateFormats();
GuiUtilities::setLabelAsNotice(m_ui->label_9, false);
connect(m_ui->m_checkAutoUpdateNotification, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkAutoUpdate, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkKeppMessagesInTheMiddle, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkMessagesDateTimeFormat, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkRemoveReadMessagesOnExit, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkUpdateAllFeedsOnStartup, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_spinAutoUpdateInterval, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_spinHeightImageAttachments, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkAutoUpdate, &QCheckBox::toggled, m_ui->m_spinAutoUpdateInterval, &TimeSpinBox::setEnabled);
connect(m_ui->m_spinFeedUpdateTimeout, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbMessagesDateTimeFormat, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbCountsFeedList, &QComboBox::currentTextChanged, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbCountsFeedList, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_btnChangeMessagesFont, &QPushButton::clicked, this, &SettingsFeedsMessages::changeMessagesFont);
if (!m_ui->m_spinFeedUpdateTimeout->suffix().startsWith(' ')) {
m_ui->m_spinFeedUpdateTimeout->setSuffix(QSL(" ") + m_ui->m_spinFeedUpdateTimeout->suffix());
}
}
SettingsFeedsMessages::~SettingsFeedsMessages() {
delete m_ui;
}
void SettingsFeedsMessages::initializeMessageDateFormats() {
QStringList best_formats; best_formats << QSL("d/M/yyyy hh:mm:ss") << QSL("ddd, d. M. yy hh:mm:ss") <<
QSL("yyyy-MM-dd HH:mm:ss.z") << QSL("yyyy-MM-ddThh:mm:ss") <<
QSL("MMM d yyyy hh:mm:ss");;
const QLocale current_locale = qApp->localization()->loadedLocale();
const QDateTime current_dt = QDateTime::currentDateTime();
foreach (const QString &format, best_formats) {
m_ui->m_cmbMessagesDateTimeFormat->addItem(current_locale.toString(current_dt, format), format);
}
}
void SettingsFeedsMessages::changeMessagesFont() {
bool ok;
QFont new_font = QFontDialog::getFont(&ok, m_ui->m_lblMessagesFont->font(),
this, tr("Select new font for message viewer"),
QFontDialog::DontUseNativeDialog);
if (ok) {
m_ui->m_lblMessagesFont->setFont(new_font);
dirtifySettings();
}
}
void SettingsFeedsMessages::loadSettings() {
onBeginLoadSettings();
m_ui->m_checkAutoUpdateNotification->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::EnableAutoUpdateNotification)).toBool());
m_ui->m_checkKeppMessagesInTheMiddle->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::KeepCursorInCenter)).toBool());
m_ui->m_checkRemoveReadMessagesOnExit->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::ClearReadOnExit)).toBool());
m_ui->m_checkAutoUpdate->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateEnabled)).toBool());
m_ui->m_spinAutoUpdateInterval->setValue(settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateInterval)).toInt());
m_ui->m_spinFeedUpdateTimeout->setValue(settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt());
m_ui->m_checkUpdateAllFeedsOnStartup->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::FeedsUpdateOnStartup)).toBool());
m_ui->m_cmbCountsFeedList->addItems(QStringList() << "(%unread)" << "[%unread]" << "%unread/%all" << "%unread-%all" << "[%unread|%all]");
m_ui->m_cmbCountsFeedList->setEditText(settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString());
m_ui->m_spinHeightImageAttachments->setValue(settings()->value(GROUP(Messages), SETTING(Messages::MessageHeadImageHeight)).toInt());
initializeMessageDateFormats();
m_ui->m_checkMessagesDateTimeFormat->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool());
const int index_format = m_ui->m_cmbMessagesDateTimeFormat->findData(settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString());
if (index_format >= 0) {
m_ui->m_cmbMessagesDateTimeFormat->setCurrentIndex(index_format);
}
m_ui->m_lblMessagesFont->setText(tr("Font preview"));
QFont fon;
fon.fromString(settings()->value(GROUP(Messages),
SETTING(Messages::PreviewerFontStandard)).toString());
m_ui->m_lblMessagesFont->setFont(fon);
onEndLoadSettings();
}
void SettingsFeedsMessages::saveSettings() {
onBeginSaveSettings();
settings()->setValue(GROUP(Feeds), Feeds::EnableAutoUpdateNotification, m_ui->m_checkAutoUpdateNotification->isChecked());
settings()->setValue(GROUP(Messages), Messages::KeepCursorInCenter, m_ui->m_checkKeppMessagesInTheMiddle->isChecked());
settings()->setValue(GROUP(Messages), Messages::ClearReadOnExit, m_ui->m_checkRemoveReadMessagesOnExit->isChecked());
settings()->setValue(GROUP(Feeds), Feeds::AutoUpdateEnabled, m_ui->m_checkAutoUpdate->isChecked());
settings()->setValue(GROUP(Feeds), Feeds::AutoUpdateInterval, m_ui->m_spinAutoUpdateInterval->value());
settings()->setValue(GROUP(Feeds), Feeds::UpdateTimeout, m_ui->m_spinFeedUpdateTimeout->value());
settings()->setValue(GROUP(Feeds), Feeds::FeedsUpdateOnStartup, m_ui->m_checkUpdateAllFeedsOnStartup->isChecked());
settings()->setValue(GROUP(Feeds), Feeds::CountFormat, m_ui->m_cmbCountsFeedList->currentText());
settings()->setValue(GROUP(Messages), Messages::UseCustomDate, m_ui->m_checkMessagesDateTimeFormat->isChecked());
settings()->setValue(GROUP(Messages), Messages::MessageHeadImageHeight, m_ui->m_spinHeightImageAttachments->value());
settings()->setValue(GROUP(Messages), Messages::CustomDateFormat,
m_ui->m_cmbMessagesDateTimeFormat->itemData(m_ui->m_cmbMessagesDateTimeFormat->currentIndex()).toString());
// Save fonts.
settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, m_ui->m_lblMessagesFont->font().toString());
qApp->mainForm()->tabWidget()->feedMessageViewer()->loadMessageViewerFonts();
qApp->feedReader()->updateAutoUpdateStatus();
qApp->feedReader()->feedsModel()->reloadWholeLayout();
qApp->feedReader()->messagesModel()->updateDateFormat();
qApp->feedReader()->messagesModel()->reloadWholeLayout();
onEndSaveSettings();
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsfeedsmessages.h"
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "miscellaneous/feedreader.h"
#include "gui/dialogs/formmain.h"
#include "gui/feedmessageviewer.h"
#include "gui/feedsview.h"
#include "gui/messagesview.h"
#include "gui/timespinbox.h"
#include "gui/guiutilities.h"
#include <QFontDialog>
SettingsFeedsMessages::SettingsFeedsMessages(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsFeedsMessages) {
m_ui->setupUi(this);
initializeMessageDateFormats();
GuiUtilities::setLabelAsNotice(m_ui->label_9, false);
connect(m_ui->m_checkAutoUpdateNotification, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkAutoUpdate, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkKeppMessagesInTheMiddle, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkMessagesDateTimeFormat, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkRemoveReadMessagesOnExit, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkUpdateAllFeedsOnStartup, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_spinAutoUpdateInterval, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),
this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_spinHeightImageAttachments, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkAutoUpdate, &QCheckBox::toggled, m_ui->m_spinAutoUpdateInterval, &TimeSpinBox::setEnabled);
connect(m_ui->m_spinFeedUpdateTimeout, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbMessagesDateTimeFormat, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbCountsFeedList, &QComboBox::currentTextChanged, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbCountsFeedList, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_btnChangeMessagesFont, &QPushButton::clicked, this, &SettingsFeedsMessages::changeMessagesFont);
if (!m_ui->m_spinFeedUpdateTimeout->suffix().startsWith(' ')) {
m_ui->m_spinFeedUpdateTimeout->setSuffix(QSL(" ") + m_ui->m_spinFeedUpdateTimeout->suffix());
}
}
SettingsFeedsMessages::~SettingsFeedsMessages() {
delete m_ui;
}
void SettingsFeedsMessages::initializeMessageDateFormats() {
QStringList best_formats;
best_formats << QSL("d/M/yyyy hh:mm:ss") << QSL("ddd, d. M. yy hh:mm:ss") <<
QSL("yyyy-MM-dd HH:mm:ss.z") << QSL("yyyy-MM-ddThh:mm:ss") <<
QSL("MMM d yyyy hh:mm:ss");;
const QLocale current_locale = qApp->localization()->loadedLocale();
const QDateTime current_dt = QDateTime::currentDateTime();
foreach (const QString& format, best_formats) {
m_ui->m_cmbMessagesDateTimeFormat->addItem(current_locale.toString(current_dt, format), format);
}
}
void SettingsFeedsMessages::changeMessagesFont() {
bool ok;
QFont new_font = QFontDialog::getFont(&ok, m_ui->m_lblMessagesFont->font(),
this, tr("Select new font for message viewer"),
QFontDialog::DontUseNativeDialog);
if (ok) {
m_ui->m_lblMessagesFont->setFont(new_font);
dirtifySettings();
}
}
void SettingsFeedsMessages::loadSettings() {
onBeginLoadSettings();
m_ui->m_checkAutoUpdateNotification->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::EnableAutoUpdateNotification)).toBool());
m_ui->m_checkKeppMessagesInTheMiddle->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::KeepCursorInCenter)).toBool());
m_ui->m_checkRemoveReadMessagesOnExit->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::ClearReadOnExit)).toBool());
m_ui->m_checkAutoUpdate->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateEnabled)).toBool());
m_ui->m_spinAutoUpdateInterval->setValue(settings()->value(GROUP(Feeds), SETTING(Feeds::AutoUpdateInterval)).toInt());
m_ui->m_spinFeedUpdateTimeout->setValue(settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt());
m_ui->m_checkUpdateAllFeedsOnStartup->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::FeedsUpdateOnStartup)).toBool());
m_ui->m_cmbCountsFeedList->addItems(QStringList() << "(%unread)" << "[%unread]" << "%unread/%all" << "%unread-%all" << "[%unread|%all]");
m_ui->m_cmbCountsFeedList->setEditText(settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString());
m_ui->m_spinHeightImageAttachments->setValue(settings()->value(GROUP(Messages), SETTING(Messages::MessageHeadImageHeight)).toInt());
initializeMessageDateFormats();
m_ui->m_checkMessagesDateTimeFormat->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool());
const int index_format = m_ui->m_cmbMessagesDateTimeFormat->findData(settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString());
if (index_format >= 0) {
m_ui->m_cmbMessagesDateTimeFormat->setCurrentIndex(index_format);
}
m_ui->m_lblMessagesFont->setText(tr("Font preview"));
QFont fon;
fon.fromString(settings()->value(GROUP(Messages),
SETTING(Messages::PreviewerFontStandard)).toString());
m_ui->m_lblMessagesFont->setFont(fon);
onEndLoadSettings();
}
void SettingsFeedsMessages::saveSettings() {
onBeginSaveSettings();
settings()->setValue(GROUP(Feeds), Feeds::EnableAutoUpdateNotification, m_ui->m_checkAutoUpdateNotification->isChecked());
settings()->setValue(GROUP(Messages), Messages::KeepCursorInCenter, m_ui->m_checkKeppMessagesInTheMiddle->isChecked());
settings()->setValue(GROUP(Messages), Messages::ClearReadOnExit, m_ui->m_checkRemoveReadMessagesOnExit->isChecked());
settings()->setValue(GROUP(Feeds), Feeds::AutoUpdateEnabled, m_ui->m_checkAutoUpdate->isChecked());
settings()->setValue(GROUP(Feeds), Feeds::AutoUpdateInterval, m_ui->m_spinAutoUpdateInterval->value());
settings()->setValue(GROUP(Feeds), Feeds::UpdateTimeout, m_ui->m_spinFeedUpdateTimeout->value());
settings()->setValue(GROUP(Feeds), Feeds::FeedsUpdateOnStartup, m_ui->m_checkUpdateAllFeedsOnStartup->isChecked());
settings()->setValue(GROUP(Feeds), Feeds::CountFormat, m_ui->m_cmbCountsFeedList->currentText());
settings()->setValue(GROUP(Messages), Messages::UseCustomDate, m_ui->m_checkMessagesDateTimeFormat->isChecked());
settings()->setValue(GROUP(Messages), Messages::MessageHeadImageHeight, m_ui->m_spinHeightImageAttachments->value());
settings()->setValue(GROUP(Messages), Messages::CustomDateFormat,
m_ui->m_cmbMessagesDateTimeFormat->itemData(m_ui->m_cmbMessagesDateTimeFormat->currentIndex()).toString());
// Save fonts.
settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, m_ui->m_lblMessagesFont->font().toString());
qApp->mainForm()->tabWidget()->feedMessageViewer()->loadMessageViewerFonts();
qApp->feedReader()->updateAutoUpdateStatus();
qApp->feedReader()->feedsModel()->reloadWholeLayout();
qApp->feedReader()->messagesModel()->updateDateFormat();
qApp->feedReader()->messagesModel()->reloadWholeLayout();
onEndSaveSettings();
}

View File

@ -1,49 +1,49 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 SETTINGSFEEDSMESSAGES_H
#define SETTINGSFEEDSMESSAGES_H
#include "gui/settings/settingspanel.h"
#include "ui_settingsfeedsmessages.h"
class SettingsFeedsMessages : public SettingsPanel {
Q_OBJECT
public:
explicit SettingsFeedsMessages(Settings *settings, QWidget *parent = 0);
virtual ~SettingsFeedsMessages();
inline QString title() const {
return tr("Feeds & messages");
}
void loadSettings();
void saveSettings();
private slots:
void changeMessagesFont();
private:
void initializeMessageDateFormats();
Ui::SettingsFeedsMessages *m_ui;
};
#endif // SETTINGSFEEDSMESSAGES_H
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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 SETTINGSFEEDSMESSAGES_H
#define SETTINGSFEEDSMESSAGES_H
#include "gui/settings/settingspanel.h"
#include "ui_settingsfeedsmessages.h"
class SettingsFeedsMessages : public SettingsPanel {
Q_OBJECT
public:
explicit SettingsFeedsMessages(Settings* settings, QWidget* parent = 0);
virtual ~SettingsFeedsMessages();
inline QString title() const {
return tr("Feeds & messages");
}
void loadSettings();
void saveSettings();
private slots:
void changeMessagesFont();
private:
void initializeMessageDateFormats();
Ui::SettingsFeedsMessages* m_ui;
};
#endif // SETTINGSFEEDSMESSAGES_H

View File

@ -1,86 +1,82 @@
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsgeneral.h"
#include "miscellaneous/systemfactory.h"
#include "miscellaneous/application.h"
SettingsGeneral::SettingsGeneral(Settings *settings, QWidget *parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsGeneral) {
m_ui->setupUi(this);
m_ui->m_checkAutostart->setText(m_ui->m_checkAutostart->text().arg(APP_NAME));
connect(m_ui->m_checkAutostart, &QCheckBox::stateChanged, this, &SettingsGeneral::dirtifySettings);
connect(m_ui->m_checkForUpdatesOnStart, &QCheckBox::stateChanged, this, &SettingsGeneral::dirtifySettings);
connect(m_ui->m_checkRemoveTrolltechJunk, &QCheckBox::stateChanged, this, &SettingsGeneral::dirtifySettings);
}
SettingsGeneral::~SettingsGeneral() {
delete m_ui;
}
void SettingsGeneral::loadSettings() {
onBeginLoadSettings();
m_ui->m_checkForUpdatesOnStart->setChecked(settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool());
// Load auto-start status.
const SystemFactory::AutoStartStatus autostart_status = qApp->system()->getAutoStartStatus();
switch (autostart_status) {
case SystemFactory::Enabled:
m_ui->m_checkAutostart->setChecked(true);
break;
case SystemFactory::Disabled:
m_ui->m_checkAutostart->setChecked(false);
break;
default:
m_ui->m_checkAutostart->setEnabled(false);
m_ui->m_checkAutostart->setText(m_ui->m_checkAutostart->text() + tr(" (not supported on this platform)"));
break;
}
#if defined(Q_OS_WIN)
m_ui->m_checkRemoveTrolltechJunk->setVisible(true);
m_ui->m_checkRemoveTrolltechJunk->setChecked(settings()->value(GROUP(General), SETTING(General::RemoveTrolltechJunk)).toBool());
#else
m_ui->m_checkRemoveTrolltechJunk->setVisible(false);
#endif
onEndLoadSettings();
}
void SettingsGeneral::saveSettings() {
onBeginSaveSettings();
// If auto-start feature is available and user wants to turn it on, then turn it on.
if (m_ui->m_checkAutostart->isChecked()) {
qApp->system()->setAutoStartStatus(SystemFactory::Enabled);
}
else {
qApp->system()->setAutoStartStatus(SystemFactory::Disabled);
}
settings()->setValue(GROUP(General), General::UpdateOnStartup, m_ui->m_checkForUpdatesOnStart->isChecked());
settings()->setValue(GROUP(General), General::RemoveTrolltechJunk, m_ui->m_checkRemoveTrolltechJunk->isChecked());
onEndSaveSettings();
}
// This file is part of RSS Guard.
//
// Copyright (C) 2011-2017 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/settings/settingsgeneral.h"
#include "miscellaneous/systemfactory.h"
#include "miscellaneous/application.h"
SettingsGeneral::SettingsGeneral(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsGeneral) {
m_ui->setupUi(this);
m_ui->m_checkAutostart->setText(m_ui->m_checkAutostart->text().arg(APP_NAME));
connect(m_ui->m_checkAutostart, &QCheckBox::stateChanged, this, &SettingsGeneral::dirtifySettings);
connect(m_ui->m_checkForUpdatesOnStart, &QCheckBox::stateChanged, this, &SettingsGeneral::dirtifySettings);
connect(m_ui->m_checkRemoveTrolltechJunk, &QCheckBox::stateChanged, this, &SettingsGeneral::dirtifySettings);
}
SettingsGeneral::~SettingsGeneral() {
delete m_ui;
}
void SettingsGeneral::loadSettings() {
onBeginLoadSettings();
m_ui->m_checkForUpdatesOnStart->setChecked(settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool());
// Load auto-start status.
const SystemFactory::AutoStartStatus autostart_status = qApp->system()->getAutoStartStatus();
switch (autostart_status) {
case SystemFactory::Enabled:
m_ui->m_checkAutostart->setChecked(true);
break;
case SystemFactory::Disabled:
m_ui->m_checkAutostart->setChecked(false);
break;
default:
m_ui->m_checkAutostart->setEnabled(false);
m_ui->m_checkAutostart->setText(m_ui->m_checkAutostart->text() + tr(" (not supported on this platform)"));
break;
}
#if defined(Q_OS_WIN)
m_ui->m_checkRemoveTrolltechJunk->setVisible(true);
m_ui->m_checkRemoveTrolltechJunk->setChecked(settings()->value(GROUP(General), SETTING(General::RemoveTrolltechJunk)).toBool());
#else
m_ui->m_checkRemoveTrolltechJunk->setVisible(false);
#endif
onEndLoadSettings();
}
void SettingsGeneral::saveSettings() {
onBeginSaveSettings();
// If auto-start feature is available and user wants to turn it on, then turn it on.
if (m_ui->m_checkAutostart->isChecked()) {
qApp->system()->setAutoStartStatus(SystemFactory::Enabled);
}
else {
qApp->system()->setAutoStartStatus(SystemFactory::Disabled);
}
settings()->setValue(GROUP(General), General::UpdateOnStartup, m_ui->m_checkForUpdatesOnStart->isChecked());
settings()->setValue(GROUP(General), General::RemoveTrolltechJunk, m_ui->m_checkRemoveTrolltechJunk->isChecked());
onEndSaveSettings();
}

Some files were not shown because too many files have changed in this diff Show More