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

@ -39,7 +39,6 @@ FeedDownloader::~FeedDownloader() {
m_mutex->tryLock(); m_mutex->tryLock();
m_mutex->unlock(); m_mutex->unlock();
delete m_mutex; delete m_mutex;
qDebug("Destroying FeedDownloader instance."); qDebug("Destroying FeedDownloader instance.");
} }
@ -51,10 +50,12 @@ void FeedDownloader::updateAvailableFeeds() {
while (!m_feeds.isEmpty()) { while (!m_feeds.isEmpty()) {
connect(m_feeds.first(), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished, connect(m_feeds.first(), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished,
(Qt::ConnectionType)(Qt::UniqueConnection | Qt::AutoConnection)); (Qt::ConnectionType)(Qt::UniqueConnection | Qt::AutoConnection));
if (m_threadPool->tryStart(m_feeds.first())) { if (m_threadPool->tryStart(m_feeds.first())) {
m_feeds.removeFirst(); m_feeds.removeFirst();
m_feedsUpdating++; m_feedsUpdating++;
} }
else { else {
// We want to start update of some feeds but all working threads are occupied. // We want to start update of some feeds but all working threads are occupied.
break; break;
@ -69,14 +70,13 @@ void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) {
qDebug("No feeds to update in worker thread, aborting update."); qDebug("No feeds to update in worker thread, aborting update.");
finalizeUpdate(); finalizeUpdate();
} }
else { else {
qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'."; qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'.";
m_feeds = feeds; m_feeds = feeds;
m_feedsOriginalCount = m_feeds.size(); m_feedsOriginalCount = m_feeds.size();
m_results.clear(); m_results.clear();
m_feedsUpdated = m_feedsUpdating = 0; m_feedsUpdated = m_feedsUpdating = 0;
// Job starts now. // Job starts now.
emit updateStarted(); emit updateStarted();
updateAvailableFeeds(); updateAvailableFeeds();
@ -90,22 +90,16 @@ void FeedDownloader::stopRunningUpdate() {
void FeedDownloader::oneFeedUpdateFinished(const QList<Message>& messages, bool error_during_obtaining) { void FeedDownloader::oneFeedUpdateFinished(const QList<Message>& messages, bool error_during_obtaining) {
QMutexLocker locker(m_mutex); QMutexLocker locker(m_mutex);
m_feedsUpdated++; m_feedsUpdated++;
m_feedsUpdating--; m_feedsUpdating--;
Feed* feed = qobject_cast<Feed*>(sender()); Feed* feed = qobject_cast<Feed*>(sender());
disconnect(feed, &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished); disconnect(feed, &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished);
// Now, we check if there are any feeds we would like to update too. // Now, we check if there are any feeds we would like to update too.
updateAvailableFeeds(); updateAvailableFeeds();
// Now make sure, that messages are actually stored to SQL in a locked state. // Now make sure, that messages are actually stored to SQL in a locked state.
qDebug().nospace() << "Saving messages of feed " qDebug().nospace() << "Saving messages of feed "
<< feed->id() << " in thread: \'" << feed->id() << " in thread: \'"
<< QThread::currentThreadId() << "\'."; << QThread::currentThreadId() << "\'.";
int updated_messages = feed->updateMessages(messages, error_during_obtaining); int updated_messages = feed->updateMessages(messages, error_during_obtaining);
/* /*
@ -128,9 +122,7 @@ void FeedDownloader::oneFeedUpdateFinished(const QList<Message> &messages, bool
void FeedDownloader::finalizeUpdate() { void FeedDownloader::finalizeUpdate() {
qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'."; qDebug().nospace() << "Finished feed updates in thread: \'" << QThread::currentThreadId() << "\'.";
m_results.sort(); m_results.sort();
// Update of feeds has finished. // Update of feeds has finished.
// NOTE: This means that now "update lock" can be unlocked // NOTE: This means that now "update lock" can be unlocked
// and feeds can be added/edited/deleted and application // and feeds can be added/edited/deleted and application

View File

@ -40,27 +40,21 @@
FeedsModel::FeedsModel(QObject* parent) : QAbstractItemModel(parent) { FeedsModel::FeedsModel(QObject* parent) : QAbstractItemModel(parent) {
setObjectName(QSL("FeedsModel")); setObjectName(QSL("FeedsModel"));
// Create root item. // Create root item.
m_rootItem = new RootItem(); m_rootItem = new RootItem();
//: Name of root item of feed list which can be seen in feed add/edit dialog. //: Name of root item of feed list which can be seen in feed add/edit dialog.
m_rootItem->setTitle(tr("Root")); m_rootItem->setTitle(tr("Root"));
m_rootItem->setIcon(qApp->icons()->fromTheme(QSL("folder"))); m_rootItem->setIcon(qApp->icons()->fromTheme(QSL("folder")));
// Setup icons. // Setup icons.
m_countsIcon = qApp->icons()->fromTheme(QSL("mail-mark-unread")); m_countsIcon = qApp->icons()->fromTheme(QSL("mail-mark-unread"));
//: Title text in the feed list header. //: Title text in the feed list header.
m_headerData << tr("Title"); m_headerData << tr("Title");
m_tooltipData << /*: Feed list header "titles" column tooltip.*/ tr("Titles of feeds/categories.") << m_tooltipData << /*: Feed list header "titles" column tooltip.*/ tr("Titles of feeds/categories.") <<
/*: Feed list header "counts" column tooltip.*/ tr("Counts of unread/all mesages."); /*: Feed list header "counts" column tooltip.*/ tr("Counts of unread/all mesages.");
} }
FeedsModel::~FeedsModel() { FeedsModel::~FeedsModel() {
qDebug("Destroying FeedsModel instance."); qDebug("Destroying FeedsModel instance.");
// Delete all model items. // Delete all model items.
delete m_rootItem; delete m_rootItem;
} }
@ -97,6 +91,7 @@ bool FeedsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int
if (action == Qt::IgnoreAction) { if (action == Qt::IgnoreAction) {
return true; return true;
} }
else if (action != Qt::MoveAction) { else if (action != Qt::MoveAction) {
return false; return false;
} }
@ -106,13 +101,13 @@ bool FeedsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int
if (dragged_items_data.isEmpty()) { if (dragged_items_data.isEmpty()) {
return false; return false;
} }
else { else {
QDataStream stream(&dragged_items_data, QIODevice::ReadOnly); QDataStream stream(&dragged_items_data, QIODevice::ReadOnly);
while (!stream.atEnd()) { while (!stream.atEnd()) {
quintptr pointer_to_item; quintptr pointer_to_item;
stream >> pointer_to_item; stream >> pointer_to_item;
// We have item we want to drag, we also determine the target item. // We have item we want to drag, we also determine the target item.
RootItem* dragged_item = (RootItem*) pointer_to_item; RootItem* dragged_item = (RootItem*) pointer_to_item;
RootItem* target_item = itemForIndex(parent); RootItem* target_item = itemForIndex(parent);
@ -131,7 +126,6 @@ bool FeedsModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int
QSystemTrayIcon::Warning, QSystemTrayIcon::Warning,
qApp->mainFormWidget(), qApp->mainFormWidget(),
true); true);
qDebug("Dragged item cannot be dragged into different account. Cancelling drag-drop action."); qDebug("Dragged item cannot be dragged into different account. Cancelling drag-drop action.");
return false; return false;
} }
@ -157,7 +151,6 @@ Qt::ItemFlags FeedsModel::flags(const QModelIndex &index) const {
Qt::ItemFlags base_flags = QAbstractItemModel::flags(index); Qt::ItemFlags base_flags = QAbstractItemModel::flags(index);
const RootItem* item_for_index = itemForIndex(index); const RootItem* item_for_index = itemForIndex(index);
Qt::ItemFlags additional_flags = item_for_index->additionalFlags(); Qt::ItemFlags additional_flags = item_for_index->additionalFlags();
return base_flags | additional_flags; return base_flags | additional_flags;
} }
@ -171,6 +164,7 @@ QVariant FeedsModel::headerData(int section, Qt::Orientation orientation, int ro
if (section == FDS_MODEL_TITLE_INDEX) { if (section == FDS_MODEL_TITLE_INDEX) {
return m_headerData.at(FDS_MODEL_TITLE_INDEX); return m_headerData.at(FDS_MODEL_TITLE_INDEX);
} }
else { else {
return QVariant(); return QVariant();
} }
@ -182,6 +176,7 @@ QVariant FeedsModel::headerData(int section, Qt::Orientation orientation, int ro
if (section == FDS_MODEL_COUNTS_INDEX) { if (section == FDS_MODEL_COUNTS_INDEX) {
return m_countsIcon; return m_countsIcon;
} }
else { else {
return QVariant(); return QVariant();
} }
@ -202,6 +197,7 @@ QModelIndex FeedsModel::index(int row, int column, const QModelIndex &parent) co
if (child_item) { if (child_item) {
return createIndex(row, column, child_item); return createIndex(row, column, child_item);
} }
else { else {
return QModelIndex(); return QModelIndex();
} }
@ -218,6 +214,7 @@ QModelIndex FeedsModel::parent(const QModelIndex &child) const {
if (parent_item == m_rootItem) { if (parent_item == m_rootItem) {
return QModelIndex(); return QModelIndex();
} }
else { else {
return createIndex(parent_item->row(), 0, parent_item); return createIndex(parent_item->row(), 0, parent_item);
} }
@ -227,6 +224,7 @@ int FeedsModel::rowCount(const QModelIndex &parent) const {
if (parent.column() > 0) { if (parent.column() > 0) {
return 0; return 0;
} }
else { else {
return itemForIndex(parent)->childCount(); return itemForIndex(parent)->childCount();
} }
@ -251,11 +249,9 @@ void FeedsModel::removeItem(const QModelIndex &index) {
RootItem* deleting_item = itemForIndex(index); RootItem* deleting_item = itemForIndex(index);
QModelIndex parent_index = index.parent(); QModelIndex parent_index = index.parent();
RootItem* parent_item = deleting_item->parent(); RootItem* parent_item = deleting_item->parent();
beginRemoveRows(parent_index, index.row(), index.row()); beginRemoveRows(parent_index, index.row(), index.row());
parent_item->removeChild(deleting_item); parent_item->removeChild(deleting_item);
endRemoveRows(); endRemoveRows();
deleting_item->deleteLater(); deleting_item->deleteLater();
notifyWithCounts(); notifyWithCounts();
} }
@ -266,11 +262,9 @@ void FeedsModel::removeItem(RootItem *deleting_item) {
QModelIndex index = indexForItem(deleting_item); QModelIndex index = indexForItem(deleting_item);
QModelIndex parent_index = index.parent(); QModelIndex parent_index = index.parent();
RootItem* parent_item = deleting_item->parent(); RootItem* parent_item = deleting_item->parent();
beginRemoveRows(parent_index, index.row(), index.row()); beginRemoveRows(parent_index, index.row(), index.row());
parent_item->removeChild(deleting_item); parent_item->removeChild(deleting_item);
endRemoveRows(); endRemoveRows();
deleting_item->deleteLater(); deleting_item->deleteLater();
notifyWithCounts(); notifyWithCounts();
} }
@ -292,7 +286,6 @@ void FeedsModel::reassignNodeToNewParent(RootItem *original_node, RootItem *new_
} }
int new_index_of_item = new_parent->childCount(); int new_index_of_item = new_parent->childCount();
// ... and insert it under the new parent. // ... and insert it under the new parent.
beginInsertRows(indexForItem(new_parent), new_index_of_item, new_index_of_item); beginInsertRows(indexForItem(new_parent), new_index_of_item, new_index_of_item);
new_parent->appendChild(original_node); new_parent->appendChild(original_node);
@ -360,6 +353,7 @@ QList<Feed*> FeedsModel::feedsForScheduledUpdate(bool auto_update_now) {
feeds_for_update.append(feed); feeds_for_update.append(feed);
feed->setAutoUpdateRemainingInterval(feed->autoUpdateInitialInterval()); feed->setAutoUpdateRemainingInterval(feed->autoUpdateInitialInterval());
} }
else { else {
// Interval did not pass, set new decremented interval and do NOT // Interval did not pass, set new decremented interval and do NOT
// include this feed in the output list. // include this feed in the output list.
@ -379,7 +373,6 @@ QList<Message> FeedsModel::messagesForItem(RootItem *item) const {
int FeedsModel::columnCount(const QModelIndex& parent) const { int FeedsModel::columnCount(const QModelIndex& parent) const {
Q_UNUSED(parent) Q_UNUSED(parent)
return FEEDS_VIEW_COLUMN_COUNT; return FEEDS_VIEW_COLUMN_COUNT;
} }
@ -387,6 +380,7 @@ RootItem *FeedsModel::itemForIndex(const QModelIndex &index) const {
if (index.isValid() && index.model() == this) { if (index.isValid() && index.model() == this) {
return static_cast<RootItem*>(index.internalPointer()); return static_cast<RootItem*>(index.internalPointer());
} }
else { else {
return m_rootItem; return m_rootItem;
} }
@ -437,10 +431,8 @@ void FeedsModel::reloadChangedLayout(QModelIndexList list) {
if (indx.isValid()) { if (indx.isValid()) {
QModelIndex indx_parent = indx.parent(); QModelIndex indx_parent = indx.parent();
// Underlying data are changed. // Underlying data are changed.
emit dataChanged(index(indx.row(), 0, indx_parent), index(indx.row(), FDS_MODEL_COUNTS_INDEX, indx_parent)); emit dataChanged(index(indx.row(), 0, indx_parent), index(indx.row(), FDS_MODEL_COUNTS_INDEX, indx_parent));
list.append(indx_parent); list.append(indx_parent);
} }
} }
@ -460,6 +452,7 @@ void FeedsModel::onItemDataChanged(const QList<RootItem *> &items) {
qDebug("There is request to reload feed model for more than %d items, reloading model fully.", RELOAD_MODEL_BORDER_NUM); qDebug("There is request to reload feed model for more than %d items, reloading model fully.", RELOAD_MODEL_BORDER_NUM);
reloadWholeLayout(); reloadWholeLayout();
} }
else { else {
qDebug("There is request to reload feed model, reloading the %d items individually.", items.size()); qDebug("There is request to reload feed model, reloading the %d items individually.", items.size());
@ -478,11 +471,9 @@ void FeedsModel::reloadWholeLayout() {
bool FeedsModel::addServiceAccount(ServiceRoot* root, bool freshly_activated) { bool FeedsModel::addServiceAccount(ServiceRoot* root, bool freshly_activated) {
int new_row_index = m_rootItem->childCount(); int new_row_index = m_rootItem->childCount();
beginInsertRows(indexForItem(m_rootItem), new_row_index, new_row_index); beginInsertRows(indexForItem(m_rootItem), new_row_index, new_row_index);
m_rootItem->appendChild(root); m_rootItem->appendChild(root);
endInsertRows(); endInsertRows();
// Connect. // Connect.
connect(root, &ServiceRoot::itemRemovalRequested, this, static_cast<void (FeedsModel::*)(RootItem*)>(&FeedsModel::removeItem)); connect(root, &ServiceRoot::itemRemovalRequested, this, static_cast<void (FeedsModel::*)(RootItem*)>(&FeedsModel::removeItem));
connect(root, &ServiceRoot::itemReassignmentRequested, this, &FeedsModel::reassignNodeToNewParent); connect(root, &ServiceRoot::itemReassignmentRequested, this, &FeedsModel::reassignNodeToNewParent);
@ -490,7 +481,6 @@ bool FeedsModel::addServiceAccount(ServiceRoot *root, bool freshly_activated) {
connect(root, &ServiceRoot::reloadMessageListRequested, this, &FeedsModel::reloadMessageListRequested); connect(root, &ServiceRoot::reloadMessageListRequested, this, &FeedsModel::reloadMessageListRequested);
connect(root, &ServiceRoot::itemExpandRequested, this, &FeedsModel::itemExpandRequested); connect(root, &ServiceRoot::itemExpandRequested, this, &FeedsModel::itemExpandRequested);
connect(root, &ServiceRoot::itemExpandStateSaveRequested, this, &FeedsModel::itemExpandStateSaveRequested); connect(root, &ServiceRoot::itemExpandStateSaveRequested, this, &FeedsModel::itemExpandStateSaveRequested);
root->start(freshly_activated); root->start(freshly_activated);
return true; return true;
} }

View File

@ -71,6 +71,7 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex &start, int role, const
result.append(idx); result.append(idx);
} }
} }
// QString based matching. // QString based matching.
else { else {
if (entered_text.isEmpty()) { if (entered_text.isEmpty()) {
@ -84,30 +85,35 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex &start, int role, const
if (QRegExp(entered_text, cs).exactMatch(item_text)) { if (QRegExp(entered_text, cs).exactMatch(item_text)) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchWildcard: case Qt::MatchWildcard:
if (QRegExp(entered_text, cs, QRegExp::Wildcard).exactMatch(item_text)) { if (QRegExp(entered_text, cs, QRegExp::Wildcard).exactMatch(item_text)) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchStartsWith: case Qt::MatchStartsWith:
if (item_text.startsWith(entered_text, cs)) { if (item_text.startsWith(entered_text, cs)) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchEndsWith: case Qt::MatchEndsWith:
if (item_text.endsWith(entered_text, cs)) { if (item_text.endsWith(entered_text, cs)) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchFixedString: case Qt::MatchFixedString:
if (item_text.compare(entered_text, cs) == 0) { if (item_text.compare(entered_text, cs) == 0) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchContains: case Qt::MatchContains:
@ -115,6 +121,7 @@ QModelIndexList FeedsProxyModel::match(const QModelIndex &start, int role, const
if (item_text.contains(entered_text, cs)) { if (item_text.contains(entered_text, cs)) {
result.append(idx); result.append(idx);
} }
break; break;
} }
} }
@ -149,23 +156,28 @@ bool FeedsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right
// User wants to sort according to counts. // User wants to sort according to counts.
return left_item->countOfUnreadMessages() < right_item->countOfUnreadMessages(); return left_item->countOfUnreadMessages() < right_item->countOfUnreadMessages();
} }
else { else {
// In other cases, sort by title. // In other cases, sort by title.
return QString::localeAwareCompare(left_item->title(), right_item->title()) < 0; return QString::localeAwareCompare(left_item->title(), right_item->title()) < 0;
} }
} }
else if (left_item->kind() == RootItemKind::Bin) { else if (left_item->kind() == RootItemKind::Bin) {
// Left item is recycle bin. Make sure it is "biggest" item if we have selected ascending order. // Left item is recycle bin. Make sure it is "biggest" item if we have selected ascending order.
return sortOrder() == Qt::DescendingOrder; return sortOrder() == Qt::DescendingOrder;
} }
else if (right_item->kind() == RootItemKind::Bin) { else if (right_item->kind() == RootItemKind::Bin) {
// Right item is recycle bin. Make sure it is "smallest" item if we have selected descending order. // Right item is recycle bin. Make sure it is "smallest" item if we have selected descending order.
return sortOrder() == Qt::AscendingOrder; return sortOrder() == Qt::AscendingOrder;
} }
else if (left_item->kind() == RootItemKind::Feed) { else if (left_item->kind() == RootItemKind::Feed) {
// Left item is feed, right item is category. // Left item is feed, right item is category.
return false; return false;
} }
else { else {
// Left item is category, right item is feed. // 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" // NOTE: Category is in fact "more" than feed but we consider it to be "less" because it should be "placed"
@ -174,6 +186,7 @@ bool FeedsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right
return true; return true;
} }
} }
else { else {
return false; return false;
} }
@ -184,7 +197,6 @@ bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source
if (should_show && m_hiddenIndices.contains(QPair<int, QModelIndex>(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)); const_cast<FeedsProxyModel*>(this)->m_hiddenIndices.removeAll(QPair<int, QModelIndex>(source_row, source_parent));
// Load status. // Load status.
emit expandAfterFilterIn(m_sourceModel->index(source_row, 0, source_parent)); emit expandAfterFilterIn(m_sourceModel->index(source_row, 0, source_parent));
} }
@ -213,10 +225,12 @@ bool FeedsProxyModel::filterAcceptsRowInternal(int source_row, const QModelIndex
// Recycle bin is always displayed. // Recycle bin is always displayed.
return true; return true;
} }
else if (item->isParentOf(m_selectedItem)/* || item->isChildOf(m_selectedItem)*/ || m_selectedItem == item) { 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. // Currently selected item and all its parents and children must be displayed.
return true; return true;
} }
else { else {
// NOTE: If item has < 0 of unread message it may mean, that the count // 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. // of unread messages is not (yet) known, display that item too.

View File

@ -33,10 +33,10 @@ QList<Enclosure> Enclosures::decodeEnclosuresFromString(const QString &enclosure
if (single_enclosure.contains(ECNLOSURES_INNER_SEPARATOR)) { if (single_enclosure.contains(ECNLOSURES_INNER_SEPARATOR)) {
QStringList mime_url = single_enclosure.split(ECNLOSURES_INNER_SEPARATOR); QStringList mime_url = single_enclosure.split(ECNLOSURES_INNER_SEPARATOR);
enclosure.m_mimeType = QByteArray::fromBase64(mime_url.at(0).toLocal8Bit()); enclosure.m_mimeType = QByteArray::fromBase64(mime_url.at(0).toLocal8Bit());
enclosure.m_url = QByteArray::fromBase64(mime_url.at(1).toLocal8Bit()); enclosure.m_url = QByteArray::fromBase64(mime_url.at(1).toLocal8Bit());
} }
else { else {
enclosure.m_url = QByteArray::fromBase64(single_enclosure.toLocal8Bit()); enclosure.m_url = QByteArray::fromBase64(single_enclosure.toLocal8Bit());
} }
@ -54,6 +54,7 @@ QString Enclosures::encodeEnclosuresToString(const QList<Enclosure> &enclosures)
if (enclosure.m_mimeType.isEmpty()) { if (enclosure.m_mimeType.isEmpty()) {
enclosures_str.append(enclosure.m_url.toLocal8Bit().toBase64()); enclosures_str.append(enclosure.m_url.toLocal8Bit().toBase64());
} }
else { else {
enclosures_str.append(QString(enclosure.m_mimeType.toLocal8Bit().toBase64()) + enclosures_str.append(QString(enclosure.m_mimeType.toLocal8Bit().toBase64()) +
ECNLOSURES_INNER_SEPARATOR + ECNLOSURES_INNER_SEPARATOR +
@ -80,7 +81,6 @@ Message Message::fromSqlRecord(const QSqlRecord &record, bool *result) {
} }
Message message; Message message;
message.m_id = record.value(MSG_DB_ID_INDEX).toInt(); message.m_id = record.value(MSG_DB_ID_INDEX).toInt();
message.m_isRead = record.value(MSG_DB_READ_INDEX).toBool(); message.m_isRead = record.value(MSG_DB_READ_INDEX).toBool();
message.m_isImportant = record.value(MSG_DB_IMPORTANT_INDEX).toBool(); message.m_isImportant = record.value(MSG_DB_IMPORTANT_INDEX).toBool();

View File

@ -37,7 +37,6 @@ MessagesModel::MessagesModel(QObject *parent)
setupIcons(); setupIcons();
setupHeaderData(); setupHeaderData();
updateDateFormat(); updateDateFormat();
loadMessages(nullptr); loadMessages(nullptr);
} }
@ -62,7 +61,6 @@ void MessagesModel::repopulate() {
bool MessagesModel::setData(const QModelIndex& index, const QVariant& value, int role) { bool MessagesModel::setData(const QModelIndex& index, const QVariant& value, int role) {
Q_UNUSED(role) Q_UNUSED(role)
m_cache->setData(index, value, record(index.row())); m_cache->setData(index, value, record(index.row()));
return true; return true;
} }
@ -72,7 +70,6 @@ void MessagesModel::setupFonts() {
m_normalFont = Application::font("MessagesView"); m_normalFont = Application::font("MessagesView");
m_boldFont = m_normalFont; m_boldFont = m_normalFont;
m_boldFont.setBold(true); m_boldFont.setBold(true);
m_normalStrikedFont = m_normalFont; m_normalStrikedFont = m_normalFont;
m_boldStrikedFont = m_boldFont; m_boldStrikedFont = m_boldFont;
m_normalStrikedFont.setStrikeOut(true); m_normalStrikedFont.setStrikeOut(true);
@ -85,6 +82,7 @@ void MessagesModel::loadMessages(RootItem *item) {
if (item == nullptr) { if (item == nullptr) {
setFilter(QSL(DEFAULT_SQL_MESSAGES_FILTER)); setFilter(QSL(DEFAULT_SQL_MESSAGES_FILTER));
} }
else { else {
if (!item->getParentServiceRoot()->loadMessagesForItem(item, this)) { if (!item->getParentServiceRoot()->loadMessagesForItem(item, this)) {
setFilter(QSL("true != true")); setFilter(QSL("true != true"));
@ -140,6 +138,7 @@ void MessagesModel::updateDateFormat() {
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool()) { if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool()) {
m_customDateFormat = qApp->settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString(); m_customDateFormat = qApp->settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString();
} }
else { else {
m_customDateFormat = QString(); m_customDateFormat = QString();
} }
@ -171,7 +170,6 @@ void MessagesModel::setupHeaderData() {
/*: Tooltip for custom ID of message.*/ tr("Custom ID") << /*: Tooltip for custom ID of message.*/ tr("Custom ID") <<
/*: Tooltip for custom hash string of message.*/ tr("Custom hash") << /*: Tooltip for custom hash string of message.*/ tr("Custom hash") <<
/*: Tooltip for custom ID of feed of message.*/ tr("Feed ID");; /*: Tooltip for custom ID of feed of message.*/ tr("Feed ID");;
m_tooltipData << tr("Id of the message.") << tr("Is message read?") << m_tooltipData << tr("Id of the message.") << tr("Is message read?") <<
tr("Is message deleted?") << tr("Is message important?") << tr("Is message deleted?") << tr("Is message important?") <<
tr("Id of feed which this message belongs to.") << tr("Id of feed which this message belongs to.") <<
@ -184,7 +182,6 @@ void MessagesModel::setupHeaderData() {
Qt::ItemFlags MessagesModel::flags(const QModelIndex& index) const { Qt::ItemFlags MessagesModel::flags(const QModelIndex& index) const {
Q_UNUSED(index) Q_UNUSED(index)
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemNeverHasChildren; return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemNeverHasChildren;
} }
@ -205,18 +202,21 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
if (m_customDateFormat.isEmpty()) { if (m_customDateFormat.isEmpty()) {
return dt.toString(Qt::DefaultLocaleShortDate); return dt.toString(Qt::DefaultLocaleShortDate);
} }
else { else {
return dt.toString(m_customDateFormat); return dt.toString(m_customDateFormat);
} }
} }
else if (index_column == MSG_DB_AUTHOR_INDEX) { else if (index_column == MSG_DB_AUTHOR_INDEX) {
const QString author_name = QSqlQueryModel::data(idx, role).toString(); const QString author_name = QSqlQueryModel::data(idx, role).toString();
return author_name.isEmpty() ? QSL("-") : author_name; return author_name.isEmpty() ? QSL("-") : author_name;
} }
else if (index_column != MSG_DB_IMPORTANT_INDEX && index_column != MSG_DB_READ_INDEX) { else if (index_column != MSG_DB_IMPORTANT_INDEX && index_column != MSG_DB_READ_INDEX) {
return QSqlQueryModel::data(idx, role); return QSqlQueryModel::data(idx, role);
} }
else { else {
return QVariant(); return QVariant();
} }
@ -228,7 +228,6 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
case Qt::FontRole: { case Qt::FontRole: {
QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX); QModelIndex idx_read = index(idx.row(), MSG_DB_READ_INDEX);
QVariant data_read = data(idx_read, Qt::EditRole); QVariant data_read = data(idx_read, Qt::EditRole);
const bool is_bin = qobject_cast<RecycleBin*>(loadedItem()) != nullptr; const bool is_bin = qobject_cast<RecycleBin*>(loadedItem()) != nullptr;
bool is_deleted; bool is_deleted;
@ -236,6 +235,7 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
QModelIndex idx_del = index(idx.row(), MSG_DB_PDELETED_INDEX); QModelIndex idx_del = index(idx.row(), MSG_DB_PDELETED_INDEX);
is_deleted = data(idx_del, Qt::EditRole).toBool(); is_deleted = data(idx_del, Qt::EditRole).toBool();
} }
else { else {
QModelIndex idx_del = index(idx.row(), MSG_DB_DELETED_INDEX); QModelIndex idx_del = index(idx.row(), MSG_DB_DELETED_INDEX);
is_deleted = data(idx_del, Qt::EditRole).toBool(); is_deleted = data(idx_del, Qt::EditRole).toBool();
@ -246,6 +246,7 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
if (data_read.toBool()) { if (data_read.toBool()) {
return striked ? m_normalStrikedFont : m_normalFont; return striked ? m_normalStrikedFont : m_normalFont;
} }
else { else {
return striked ? m_boldStrikedFont : m_boldFont; return striked ? m_boldStrikedFont : m_boldFont;
} }
@ -256,14 +257,12 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
case HighlightImportant: { case HighlightImportant: {
QModelIndex idx_important = index(idx.row(), 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); 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(); return dta.toInt() == 1 ? QColor(Qt::blue) : QVariant();
} }
case HighlightUnread: { case HighlightUnread: {
QModelIndex idx_read = index(idx.row(), 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); 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(); return dta.toInt() == 0 ? QColor(Qt::blue) : QVariant();
} }
@ -278,15 +277,15 @@ QVariant MessagesModel::data(const QModelIndex &idx, int role) const {
if (index_column == MSG_DB_READ_INDEX) { if (index_column == MSG_DB_READ_INDEX) {
QModelIndex idx_read = index(idx.row(), 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); 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; return dta.toInt() == 1 ? m_readIcon : m_unreadIcon;
} }
else if (index_column == MSG_DB_IMPORTANT_INDEX) { else if (index_column == MSG_DB_IMPORTANT_INDEX) {
QModelIndex idx_important = index(idx.row(), 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); QVariant dta = m_cache->containsData(idx_important.row()) ? m_cache->data(idx_important) : QSqlQueryModel::data(idx_important);
return dta.toInt() == 1 ? m_favoriteIcon : QVariant(); return dta.toInt() == 1 ? m_favoriteIcon : QVariant();
} }
else { else {
return QVariant(); return QVariant();
} }
@ -323,6 +322,7 @@ bool MessagesModel::setMessageRead(int row_index, RootItem::ReadStatus read) {
if (DatabaseQueries::markMessagesReadUnread(m_db, QStringList() << QString::number(message.m_id), read)) { if (DatabaseQueries::markMessagesReadUnread(m_db, QStringList() << QString::number(message.m_id), read)) {
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList<Message>() << message, read); return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, QList<Message>() << message, read);
} }
else { else {
return false; return false;
} }
@ -371,10 +371,10 @@ bool MessagesModel::switchMessageImportance(int row_index) {
// Commit changes. // Commit changes.
if (DatabaseQueries::markMessageImportant(m_db, message.m_id, next_importance)) { 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); 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, return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem,
QList<QPair<Message, RootItem::Importance>>() << pair); QList<QPair<Message, RootItem::Importance>>() << pair);
} }
else { else {
return false; return false;
} }
@ -388,12 +388,10 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages
foreach (const QModelIndex& message, messages) { foreach (const QModelIndex& message, messages) {
const Message msg = messageAt(message.row()); const Message msg = messageAt(message.row());
RootItem::Importance message_importance = messageImportance((message.row())); RootItem::Importance message_importance = messageImportance((message.row()));
message_states.append(QPair<Message, RootItem::Importance>(msg, message_importance == RootItem::Important ? message_states.append(QPair<Message, RootItem::Importance>(msg, message_importance == RootItem::Important ?
RootItem::NotImportant : RootItem::NotImportant :
RootItem::Important)); RootItem::Important));
message_ids.append(QString::number(msg.m_id)); message_ids.append(QString::number(msg.m_id));
QModelIndex idx_msg_imp = index(message.row(), MSG_DB_IMPORTANT_INDEX); QModelIndex idx_msg_imp = index(message.row(), MSG_DB_IMPORTANT_INDEX);
setData(idx_msg_imp, message_importance == RootItem::Important ? setData(idx_msg_imp, message_importance == RootItem::Important ?
(int) RootItem::NotImportant : (int) RootItem::NotImportant :
@ -409,6 +407,7 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages
if (DatabaseQueries::switchMessagesImportance(m_db, message_ids)) { if (DatabaseQueries::switchMessagesImportance(m_db, message_ids)) {
return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem, message_states); return m_selectedItem->getParentServiceRoot()->onAfterSwitchMessageImportance(m_selectedItem, message_states);
} }
else { else {
return false; return false;
} }
@ -421,13 +420,13 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages) {
// Obtain IDs of all desired messages. // Obtain IDs of all desired messages.
foreach (const QModelIndex& message, messages) { foreach (const QModelIndex& message, messages) {
const Message msg = messageAt(message.row()); const Message msg = messageAt(message.row());
msgs.append(msg); msgs.append(msg);
message_ids.append(QString::number(msg.m_id)); message_ids.append(QString::number(msg.m_id));
if (qobject_cast<RecycleBin*>(m_selectedItem) != nullptr) { if (qobject_cast<RecycleBin*>(m_selectedItem) != nullptr) {
setData(index(message.row(), MSG_DB_PDELETED_INDEX), 1); setData(index(message.row(), MSG_DB_PDELETED_INDEX), 1);
} }
else { else {
setData(index(message.row(), MSG_DB_DELETED_INDEX), 1); setData(index(message.row(), MSG_DB_DELETED_INDEX), 1);
} }
@ -444,6 +443,7 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages) {
if (m_selectedItem->kind() != RootItemKind::Bin) { if (m_selectedItem->kind() != RootItemKind::Bin) {
deleted = DatabaseQueries::deleteOrRestoreMessagesToFromBin(m_db, message_ids, true); deleted = DatabaseQueries::deleteOrRestoreMessagesToFromBin(m_db, message_ids, true);
} }
else { else {
deleted = DatabaseQueries::permanentlyDeleteMessages(m_db, message_ids); deleted = DatabaseQueries::permanentlyDeleteMessages(m_db, message_ids);
} }
@ -451,6 +451,7 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages) {
if (deleted) { if (deleted) {
return m_selectedItem->getParentServiceRoot()->onAfterMessagesDelete(m_selectedItem, msgs); return m_selectedItem->getParentServiceRoot()->onAfterMessagesDelete(m_selectedItem, msgs);
} }
else { else {
return false; return false;
} }
@ -463,10 +464,8 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, RootIt
// Obtain IDs of all desired messages. // Obtain IDs of all desired messages.
foreach (const QModelIndex& message, messages) { foreach (const QModelIndex& message, messages) {
Message msg = messageAt(message.row()); Message msg = messageAt(message.row());
msgs.append(msg); msgs.append(msg);
message_ids.append(QString::number(msg.m_id)); message_ids.append(QString::number(msg.m_id));
setData(index(message.row(), MSG_DB_READ_INDEX), (int) read); setData(index(message.row(), MSG_DB_READ_INDEX), (int) read);
} }
@ -479,6 +478,7 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, RootIt
if (DatabaseQueries::markMessagesReadUnread(m_db, message_ids, read)) { if (DatabaseQueries::markMessagesReadUnread(m_db, message_ids, read)) {
return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, msgs, read); return m_selectedItem->getParentServiceRoot()->onAfterSetMessagesRead(m_selectedItem, msgs, read);
} }
else { else {
return false; return false;
} }
@ -491,10 +491,8 @@ bool MessagesModel::setBatchMessagesRestored(const QModelIndexList &messages) {
// Obtain IDs of all desired messages. // Obtain IDs of all desired messages.
foreach (const QModelIndex& message, messages) { foreach (const QModelIndex& message, messages) {
const Message msg = messageAt(message.row()); const Message msg = messageAt(message.row());
msgs.append(msg); msgs.append(msg);
message_ids.append(QString::number(msg.m_id)); message_ids.append(QString::number(msg.m_id));
setData(index(message.row(), MSG_DB_PDELETED_INDEX), 0); setData(index(message.row(), MSG_DB_PDELETED_INDEX), 0);
setData(index(message.row(), MSG_DB_DELETED_INDEX), 0); setData(index(message.row(), MSG_DB_DELETED_INDEX), 0);
} }
@ -508,6 +506,7 @@ bool MessagesModel::setBatchMessagesRestored(const QModelIndexList &messages) {
if (DatabaseQueries::deleteOrRestoreMessagesToFromBin(m_db, message_ids, false)) { if (DatabaseQueries::deleteOrRestoreMessagesToFromBin(m_db, message_ids, false)) {
return m_selectedItem->getParentServiceRoot()->onAfterMessagesRestoredFromBin(m_selectedItem, msgs); return m_selectedItem->getParentServiceRoot()->onAfterMessagesRestoredFromBin(m_selectedItem, msgs);
} }
else { else {
return false; return false;
} }
@ -518,11 +517,13 @@ QVariant MessagesModel::headerData(int section, Qt::Orientation orientation, int
switch (role) { switch (role) {
case Qt::DisplayRole: case Qt::DisplayRole:
// Display textual headers for all columns except "read" and // Display textual headers for all columns except "read" and
// "important" columns. // "important" columns.
if (section != MSG_DB_READ_INDEX && section != MSG_DB_IMPORTANT_INDEX) { if (section != MSG_DB_READ_INDEX && section != MSG_DB_IMPORTANT_INDEX) {
return m_headerData.at(section); return m_headerData.at(section);
} }
else { else {
return QVariant(); return QVariant();
} }

View File

@ -25,7 +25,6 @@ MessagesModelSqlLayer::MessagesModelSqlLayer()
: m_filter(QSL(DEFAULT_SQL_MESSAGES_FILTER)), m_fieldNames(QMap<int, QString>()), : m_filter(QSL(DEFAULT_SQL_MESSAGES_FILTER)), m_fieldNames(QMap<int, QString>()),
m_sortColumns(QList<int>()), m_sortOrders(QList<Qt::SortOrder>()) { m_sortColumns(QList<int>()), m_sortOrders(QList<Qt::SortOrder>()) {
m_db = qApp->database()->connection(QSL("MessagesModel"), DatabaseFactory::FromSettings); m_db = qApp->database()->connection(QSL("MessagesModel"), DatabaseFactory::FromSettings);
m_fieldNames[MSG_DB_ID_INDEX] = "Messages.id"; m_fieldNames[MSG_DB_ID_INDEX] = "Messages.id";
m_fieldNames[MSG_DB_READ_INDEX] = "Messages.is_read"; m_fieldNames[MSG_DB_READ_INDEX] = "Messages.is_read";
m_fieldNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted"; m_fieldNames[MSG_DB_DELETED_INDEX] = "Messages.is_deleted";
@ -65,6 +64,7 @@ void MessagesModelSqlLayer::addSortState(int column, Qt::SortOrder order) {
m_sortColumns.append(column); m_sortColumns.append(column);
m_sortOrders.append(order); m_sortOrders.append(order);
} }
else { else {
m_sortColumns.prepend(column); m_sortColumns.prepend(column);
m_sortOrders.prepend(order); m_sortOrders.prepend(order);
@ -91,12 +91,12 @@ QString MessagesModelSqlLayer::orderByClause() const {
if (m_sortColumns.isEmpty()) { if (m_sortColumns.isEmpty()) {
return QString(); return QString();
} }
else { else {
QStringList sorts; QStringList sorts;
for (int i = 0; i < m_sortColumns.size(); i++) { for (int i = 0; i < m_sortColumns.size(); i++) {
QString field_name(m_fieldNames[m_sortColumns[i]]); QString field_name(m_fieldNames[m_sortColumns[i]]);
sorts.append(field_name + (m_sortOrders[i] == Qt::AscendingOrder ? QSL(" ASC") : QSL(" DESC"))); sorts.append(field_name + (m_sortOrders[i] == Qt::AscendingOrder ? QSL(" ASC") : QSL(" DESC")));
} }

View File

@ -22,7 +22,6 @@
MessagesProxyModel::MessagesProxyModel(MessagesModel* source_model, QObject* parent) MessagesProxyModel::MessagesProxyModel(MessagesModel* source_model, QObject* parent)
: QSortFilterProxyModel(parent), m_sourceModel(source_model) { : QSortFilterProxyModel(parent), m_sourceModel(source_model) {
setObjectName(QSL("MessagesProxyModel")); setObjectName(QSL("MessagesProxyModel"));
setSortRole(Qt::EditRole); setSortRole(Qt::EditRole);
setSortCaseSensitivity(Qt::CaseInsensitive); setSortCaseSensitivity(Qt::CaseInsensitive);
@ -60,6 +59,7 @@ QModelIndex MessagesProxyModel::getNextUnreadItemIndex(int default_row, int max_
// We found unread message, mark it. // We found unread message, mark it.
return proxy_index; return proxy_index;
} }
else { else {
default_row++; default_row++;
} }
@ -71,7 +71,6 @@ QModelIndex MessagesProxyModel::getNextUnreadItemIndex(int default_row, int max_
bool MessagesProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const { bool MessagesProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const {
Q_UNUSED(left) Q_UNUSED(left)
Q_UNUSED(right) Q_UNUSED(right)
// NOTE: Comparisons are done by SQL servers itself, not client-side. // NOTE: Comparisons are done by SQL servers itself, not client-side.
return false; return false;
} }
@ -84,6 +83,7 @@ QModelIndexList MessagesProxyModel::mapListFromSource(const QModelIndexList &ind
// Construct new source index. // Construct new source index.
mapped_indexes << mapFromSource(m_sourceModel->index(index.row(), index.column())); mapped_indexes << mapFromSource(m_sourceModel->index(index.row(), index.column()));
} }
else { else {
mapped_indexes << mapFromSource(index); mapped_indexes << mapFromSource(index);
} }
@ -119,6 +119,7 @@ QModelIndexList MessagesProxyModel::match(const QModelIndex &start, int role,
result.append(idx); result.append(idx);
} }
} }
// QString based matching. // QString based matching.
else { else {
if (entered_text.isEmpty()) { if (entered_text.isEmpty()) {
@ -132,30 +133,35 @@ QModelIndexList MessagesProxyModel::match(const QModelIndex &start, int role,
if (QRegExp(entered_text, case_sensitivity).exactMatch(item_text)) { if (QRegExp(entered_text, case_sensitivity).exactMatch(item_text)) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchWildcard: case Qt::MatchWildcard:
if (QRegExp(entered_text, case_sensitivity, QRegExp::Wildcard).exactMatch(item_text)) { if (QRegExp(entered_text, case_sensitivity, QRegExp::Wildcard).exactMatch(item_text)) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchStartsWith: case Qt::MatchStartsWith:
if (item_text.startsWith(entered_text, case_sensitivity)) { if (item_text.startsWith(entered_text, case_sensitivity)) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchEndsWith: case Qt::MatchEndsWith:
if (item_text.endsWith(entered_text, case_sensitivity)) { if (item_text.endsWith(entered_text, case_sensitivity)) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchFixedString: case Qt::MatchFixedString:
if (item_text.compare(entered_text, case_sensitivity) == 0) { if (item_text.compare(entered_text, case_sensitivity) == 0) {
result.append(idx); result.append(idx);
} }
break; break;
case Qt::MatchContains: case Qt::MatchContains:
@ -163,6 +169,7 @@ QModelIndexList MessagesProxyModel::match(const QModelIndex &start, int role,
if (item_text.contains(entered_text, case_sensitivity)) { if (item_text.contains(entered_text, case_sensitivity)) {
result.append(idx); result.append(idx);
} }
break; break;
} }
} }

View File

@ -30,7 +30,6 @@ DynamicShortcutsWidget::DynamicShortcutsWidget(QWidget *parent) : QWidget(parent
// Create layout for this control and set is as active. // Create layout for this control and set is as active.
m_layout = new QGridLayout(this); m_layout = new QGridLayout(this);
m_layout->setMargin(0); m_layout->setMargin(0);
setLayout(m_layout); setLayout(m_layout);
} }
@ -49,6 +48,7 @@ bool DynamicShortcutsWidget::areShortcutsUnique() const {
// Problem, two identical non-empty shortcuts found. // Problem, two identical non-empty shortcuts found.
return false; return false;
} }
else { else {
all_shortcuts.append(binding.second->shortcut()); all_shortcuts.append(binding.second->shortcut());
} }
@ -66,7 +66,6 @@ void DynamicShortcutsWidget::updateShortcuts() {
void DynamicShortcutsWidget::populate(QList<QAction*> actions) { void DynamicShortcutsWidget::populate(QList<QAction*> actions) {
m_actionBindings.clear(); m_actionBindings.clear();
qSort(actions.begin(), actions.end(), DynamicShortcutsWidget::lessThan); 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. // FIXME: Maybe separate actions into "categories". Each category will start with label.
@ -80,31 +79,24 @@ void DynamicShortcutsWidget::populate(QList<QAction*> actions) {
// Create shortcut catcher for this action and set default shortcut. // Create shortcut catcher for this action and set default shortcut.
ShortcutCatcher* catcher = new ShortcutCatcher(this); ShortcutCatcher* catcher = new ShortcutCatcher(this);
catcher->setDefaultShortcut(action->shortcut()); catcher->setDefaultShortcut(action->shortcut());
// Store information for re-initialization of shortcuts // Store information for re-initialization of shortcuts
// of actions when widget gets "confirmed". // of actions when widget gets "confirmed".
QPair<QAction*, ShortcutCatcher*> new_binding; QPair<QAction*, ShortcutCatcher*> new_binding;
new_binding.first = action; new_binding.first = action;
new_binding.second = catcher; new_binding.second = catcher;
m_actionBindings << new_binding; m_actionBindings << new_binding;
// Add new catcher to our control. // Add new catcher to our control.
QLabel* action_label = new QLabel(this); QLabel* action_label = new QLabel(this);
action_label->setText(action->text().remove(QSL("&"))); action_label->setText(action->text().remove(QSL("&")));
action_label->setToolTip(action->toolTip()); action_label->setToolTip(action->toolTip());
action_label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); action_label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
QLabel* action_icon = new QLabel(this); QLabel* action_icon = new QLabel(this);
action_icon->setPixmap(action->icon().pixmap(ICON_SIZE_SETTINGS, ICON_SIZE_SETTINGS)); action_icon->setPixmap(action->icon().pixmap(ICON_SIZE_SETTINGS, ICON_SIZE_SETTINGS));
action_icon->setToolTip(action->toolTip()); action_icon->setToolTip(action->toolTip());
m_layout->addWidget(action_icon, row_id, 0); m_layout->addWidget(action_icon, row_id, 0);
m_layout->addWidget(action_label, row_id, 1); m_layout->addWidget(action_label, row_id, 1);
m_layout->addWidget(catcher, row_id, 2); m_layout->addWidget(catcher, row_id, 2);
row_id++; row_id++;
connect(catcher, &ShortcutCatcher::shortcutChanged, this, &DynamicShortcutsWidget::setupChanged); connect(catcher, &ShortcutCatcher::shortcutChanged, this, &DynamicShortcutsWidget::setupChanged);
} }

View File

@ -93,11 +93,13 @@ void ShortcutButton::keyPressEvent(QKeyEvent *event) {
break; break;
default: default:
// We now have a valid key press. // We now have a valid key press.
if (pressed_key) { if (pressed_key) {
if ((pressed_key == Qt::Key_Backtab) && (m_catcher->m_modifierKeys & Qt::SHIFT)) { if ((pressed_key == Qt::Key_Backtab) && (m_catcher->m_modifierKeys & Qt::SHIFT)) {
pressed_key = Qt::Key_Tab | m_catcher->m_modifierKeys; pressed_key = Qt::Key_Tab | m_catcher->m_modifierKeys;
} }
else { else {
pressed_key |= m_catcher->m_modifierKeys; pressed_key |= m_catcher->m_modifierKeys;
} }
@ -130,7 +132,6 @@ void ShortcutButton::keyReleaseEvent(QKeyEvent *event) {
} }
event->accept(); event->accept();
const Qt::KeyboardModifiers new_modifiers = event->modifiers() & const Qt::KeyboardModifiers new_modifiers = event->modifiers() &
(Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META); (Qt::SHIFT | Qt::CTRL | Qt::ALT | Qt::META);

View File

@ -58,34 +58,28 @@ ShortcutCatcher::ShortcutCatcher(QWidget *parent)
m_layout = new QHBoxLayout(this); m_layout = new QHBoxLayout(this);
m_layout->setMargin(0); m_layout->setMargin(0);
m_layout->setSpacing(1); m_layout->setSpacing(1);
// Create reset button. // Create reset button.
m_btnReset = new PlainToolButton(this); m_btnReset = new PlainToolButton(this);
m_btnReset->setIcon(qApp->icons()->fromTheme(QSL("document-revert"))); m_btnReset->setIcon(qApp->icons()->fromTheme(QSL("document-revert")));
m_btnReset->setFocusPolicy(Qt::NoFocus); m_btnReset->setFocusPolicy(Qt::NoFocus);
m_btnReset->setToolTip(tr("Reset to original shortcut.")); m_btnReset->setToolTip(tr("Reset to original shortcut."));
// Create clear button. // Create clear button.
m_btnClear = new PlainToolButton(this); m_btnClear = new PlainToolButton(this);
m_btnClear->setIcon(qApp->icons()->fromTheme(QSL("list-remove"))); m_btnClear->setIcon(qApp->icons()->fromTheme(QSL("list-remove")));
m_btnClear->setFocusPolicy(Qt::NoFocus); m_btnClear->setFocusPolicy(Qt::NoFocus);
m_btnClear->setToolTip(tr("Clear current shortcut.")); m_btnClear->setToolTip(tr("Clear current shortcut."));
// Clear main shortcut catching button. // Clear main shortcut catching button.
m_btnChange = new ShortcutButton(this); m_btnChange = new ShortcutButton(this);
m_btnChange->setFocusPolicy(Qt::StrongFocus); m_btnChange->setFocusPolicy(Qt::StrongFocus);
m_btnChange->setToolTip(tr("Click and hit new shortcut.")); m_btnChange->setToolTip(tr("Click and hit new shortcut."));
// Add both buttons to the layout. // Add both buttons to the layout.
m_layout->addWidget(m_btnChange); m_layout->addWidget(m_btnChange);
m_layout->addWidget(m_btnReset); m_layout->addWidget(m_btnReset);
m_layout->addWidget(m_btnClear); m_layout->addWidget(m_btnClear);
// Establish needed connections. // Establish needed connections.
connect(m_btnReset, &QToolButton::clicked, this, &ShortcutCatcher::resetShortcut); connect(m_btnReset, &QToolButton::clicked, this, &ShortcutCatcher::resetShortcut);
connect(m_btnClear, &QToolButton::clicked, this, &ShortcutCatcher::clearShortcut); connect(m_btnClear, &QToolButton::clicked, this, &ShortcutCatcher::clearShortcut);
connect(m_btnChange, &QToolButton::clicked, this, &ShortcutCatcher::startRecording); connect(m_btnChange, &QToolButton::clicked, this, &ShortcutCatcher::startRecording);
// Prepare initial state of the control. // Prepare initial state of the control.
updateDisplayShortcut(); updateDisplayShortcut();
} }
@ -104,7 +98,6 @@ void ShortcutCatcher::startRecording() {
m_isRecording = true; m_isRecording = true;
m_btnChange->setDown(true); m_btnChange->setDown(true);
m_btnChange->grabKeyboard(); m_btnChange->grabKeyboard();
updateDisplayShortcut(); updateDisplayShortcut();
} }
@ -112,9 +105,7 @@ void ShortcutCatcher::doneRecording() {
m_isRecording = false; m_isRecording = false;
m_btnChange->releaseKeyboard(); m_btnChange->releaseKeyboard();
m_btnChange->setDown(false); m_btnChange->setDown(false);
updateDisplayShortcut(); updateDisplayShortcut();
emit shortcutChanged(m_currentSequence); emit shortcutChanged(m_currentSequence);
} }
@ -133,15 +124,19 @@ void ShortcutCatcher::updateDisplayShortcut() {
if (!str.isEmpty()) { if (!str.isEmpty()) {
str.append(QSL(",")); str.append(QSL(","));
} }
if (m_modifierKeys & Qt::META) { if (m_modifierKeys & Qt::META) {
str += QL1S("Meta + "); str += QL1S("Meta + ");
} }
if (m_modifierKeys & Qt::CTRL) { if (m_modifierKeys & Qt::CTRL) {
str += QL1S("Ctrl + "); str += QL1S("Ctrl + ");
} }
if (m_modifierKeys & Qt::ALT) { if (m_modifierKeys & Qt::ALT) {
str += QL1S("Alt + "); str += QL1S("Alt + ");
} }
if (m_modifierKeys & Qt::SHIFT) { if (m_modifierKeys & Qt::SHIFT) {
str += QL1S("Shift + "); str += QL1S("Shift + ");
} }

View File

@ -48,7 +48,6 @@ void ClickableLabel::setFallbackIcon(const QIcon &fallbackIcon) {
void ClickableLabel::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()) { if (!icon.isNull()) {
@ -72,13 +71,16 @@ void ClickableLabel::mouseReleaseEvent(QMouseEvent* ev) {
if (ev->modifiers() == Qt::ControlModifier) { if (ev->modifiers() == Qt::ControlModifier) {
emit middleClicked(ev->globalPos()); emit middleClicked(ev->globalPos());
} }
else { else {
emit clicked(ev->globalPos()); emit clicked(ev->globalPos());
} }
} }
else if (ev->button() == Qt::MiddleButton && rect().contains(ev->pos())) { else if (ev->button() == Qt::MiddleButton && rect().contains(ev->pos())) {
emit middleClicked(ev->globalPos()); emit middleClicked(ev->globalPos());
} }
else { else {
QLabel::mouseReleaseEvent(ev); QLabel::mouseReleaseEvent(ev);
} }

View File

@ -34,7 +34,6 @@ QColor ColorLabel::color() const {
void ColorLabel::setColor(const QColor& color) { void ColorLabel::setColor(const QColor& color) {
m_color = color; m_color = color;
repaint(); repaint();
} }

View File

@ -25,11 +25,9 @@
ComboBoxWithStatus::ComboBoxWithStatus(QWidget* parent) ComboBoxWithStatus::ComboBoxWithStatus(QWidget* parent)
: WidgetWithStatus(parent) { : WidgetWithStatus(parent) {
m_wdgInput = new QComboBox(this); m_wdgInput = new QComboBox(this);
// Set correct size for the tool button. // Set correct size for the tool button.
const int txt_input_height = m_wdgInput->sizeHint().height(); const int txt_input_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(txt_input_height, txt_input_height); m_btnStatus->setFixedSize(txt_input_height, txt_input_height);
// Compose the layout. // Compose the layout.
m_layout->addWidget(m_wdgInput); m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus); m_layout->addWidget(m_btnStatus);

View File

@ -27,19 +27,14 @@
FormAbout::FormAbout(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormAbout()) { FormAbout::FormAbout(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormAbout()) {
m_ui->setupUi(this); m_ui->setupUi(this);
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about"))); setWindowIcon(qApp->icons()->fromTheme(QSL("help-about")));
//: About RSS Guard dialog title. //: About RSS Guard dialog title.
setWindowTitle(tr("About %1").arg(APP_NAME)); setWindowTitle(tr("About %1").arg(APP_NAME));
m_ui->m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH)); m_ui->m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH));
// Load information from embedded text files. // Load information from embedded text files.
loadLicenseAndInformation(); loadLicenseAndInformation();
// Load additional paths information. // Load additional paths information.
loadSettingsAndPaths(); loadSettingsAndPaths();
} }
@ -52,6 +47,7 @@ void FormAbout::loadSettingsAndPaths() {
if (qApp->settings()->type() == SettingsProperties::Portable) { if (qApp->settings()->type() == SettingsProperties::Portable) {
m_ui->m_txtPathsSettingsType->setText(tr("FULLY portable")); m_ui->m_txtPathsSettingsType->setText(tr("FULLY portable"));
} }
else { else {
m_ui->m_txtPathsSettingsType->setText(tr("NOT portable")); m_ui->m_txtPathsSettingsType->setText(tr("NOT portable"));
} }
@ -65,34 +61,39 @@ void FormAbout::loadSettingsAndPaths() {
void FormAbout::loadLicenseAndInformation() { void FormAbout::loadLicenseAndInformation() {
QFile file; QFile file;
file.setFileName(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")); file.setFileName(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtLicenseGnu->setText(QString::fromUtf8(file.readAll())); m_ui->m_txtLicenseGnu->setText(QString::fromUtf8(file.readAll()));
} }
else { else {
m_ui->m_txtLicenseGnu->setText(tr("License not found.")); m_ui->m_txtLicenseGnu->setText(tr("License not found."));
} }
file.close();
file.close();
file.setFileName(APP_INFO_PATH + QL1S("/COPYING_BSD")); file.setFileName(APP_INFO_PATH + QL1S("/COPYING_BSD"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtLicenseBsd->setText(QString::fromUtf8(file.readAll())); m_ui->m_txtLicenseBsd->setText(QString::fromUtf8(file.readAll()));
} }
else { else {
m_ui->m_txtLicenseBsd->setText(tr("License not found.")); m_ui->m_txtLicenseBsd->setText(tr("License not found."));
} }
file.close();
file.close();
file.setFileName(APP_INFO_PATH + QL1S("/CHANGELOG")); file.setFileName(APP_INFO_PATH + QL1S("/CHANGELOG"));
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_ui->m_txtChangelog->setText(QString::fromUtf8(file.readAll())); m_ui->m_txtChangelog->setText(QString::fromUtf8(file.readAll()));
} }
else { else {
m_ui->m_txtChangelog->setText(tr("Changelog not found.")); m_ui->m_txtChangelog->setText(tr("Changelog not found."));
} }
file.close();
file.close();
// Set other informative texts. // Set other informative texts.
m_ui->m_lblDesc->setText(tr("<b>%8</b><br>" m_ui->m_lblDesc->setText(tr("<b>%8</b><br>"
"<b>Version:</b> %1 (built on %2/%3)<br>" "<b>Version:</b> %1 (built on %2/%3)<br>"
@ -107,7 +108,6 @@ void FormAbout::loadLicenseAndInformation() {
qVersion(), qVersion(),
QT_VERSION_STR, QT_VERSION_STR,
APP_NAME)); APP_NAME));
m_ui->m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader." 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>This software is distributed under the terms of GNU General Public License, version 3."
"<br><br>Contacts:" "<br><br>Contacts:"

View File

@ -29,11 +29,9 @@
FormAddAccount::FormAddAccount(const QList<ServiceEntryPoint*>& entry_points, FeedsModel* model, QWidget* parent) 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) { : QDialog(parent), m_ui(new Ui::FormAddAccount), m_model(model), m_entryPoints(entry_points) {
m_ui->setupUi(this); m_ui->setupUi(this);
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("document-new"))); setWindowIcon(qApp->icons()->fromTheme(QSL("document-new")));
connect(m_ui->m_listEntryPoints, &QListWidget::itemDoubleClicked, this, &FormAddAccount::addSelectedAccount); connect(m_ui->m_listEntryPoints, &QListWidget::itemDoubleClicked, this, &FormAddAccount::addSelectedAccount);
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormAddAccount::addSelectedAccount); connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormAddAccount::addSelectedAccount);
connect(m_ui->m_listEntryPoints, &QListWidget::itemSelectionChanged, this, &FormAddAccount::displayActiveEntryPointDetails); connect(m_ui->m_listEntryPoints, &QListWidget::itemSelectionChanged, this, &FormAddAccount::displayActiveEntryPointDetails);
@ -46,13 +44,13 @@ FormAddAccount::~FormAddAccount() {
void FormAddAccount::addSelectedAccount() { void FormAddAccount::addSelectedAccount() {
accept(); accept();
ServiceEntryPoint* point = selectedEntryPoint(); ServiceEntryPoint* point = selectedEntryPoint();
ServiceRoot* new_root = point->createNewRoot(); ServiceRoot* new_root = point->createNewRoot();
if (new_root != nullptr) { if (new_root != nullptr) {
m_model->addServiceAccount(new_root, true); m_model->addServiceAccount(new_root, true);
} }
else { else {
qCritical("Cannot create new account."); qCritical("Cannot create new account.");
} }
@ -60,7 +58,6 @@ void FormAddAccount::addSelectedAccount() {
void FormAddAccount::displayActiveEntryPointDetails() { void FormAddAccount::displayActiveEntryPointDetails() {
const ServiceEntryPoint* point = selectedEntryPoint(); const ServiceEntryPoint* point = selectedEntryPoint();
m_ui->m_txtAuthor->setText(point->author()); m_ui->m_txtAuthor->setText(point->author());
m_ui->m_txtDescription->setText(point->description()); m_ui->m_txtDescription->setText(point->description());
m_ui->m_txtName->setText(point->name()); m_ui->m_txtName->setText(point->name());

View File

@ -31,17 +31,14 @@
FormBackupDatabaseSettings::FormBackupDatabaseSettings(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormBackupDatabaseSettings) { FormBackupDatabaseSettings::FormBackupDatabaseSettings(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormBackupDatabaseSettings) {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->m_txtBackupName->lineEdit()->setPlaceholderText(tr("Common name for backup files")); m_ui->m_txtBackupName->lineEdit()->setPlaceholderText(tr("Common name for backup files"));
setWindowIcon(qApp->icons()->fromTheme(QSL("document-export"))); setWindowIcon(qApp->icons()->fromTheme(QSL("document-export")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
connect(m_ui->m_checkBackupDatabase, &QCheckBox::toggled, this, &FormBackupDatabaseSettings::checkOkButton); connect(m_ui->m_checkBackupDatabase, &QCheckBox::toggled, this, &FormBackupDatabaseSettings::checkOkButton);
connect(m_ui->m_checkBackupSettings, &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_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::checkBackupNames);
connect(m_ui->m_txtBackupName->lineEdit(), &BaseLineEdit::textChanged, this, &FormBackupDatabaseSettings::checkOkButton); connect(m_ui->m_txtBackupName->lineEdit(), &BaseLineEdit::textChanged, this, &FormBackupDatabaseSettings::checkOkButton);
connect(m_ui->m_btnSelectFolder, &QPushButton::clicked, this, &FormBackupDatabaseSettings::selectFolderInitial); connect(m_ui->m_btnSelectFolder, &QPushButton::clicked, this, &FormBackupDatabaseSettings::selectFolderInitial);
selectFolder(qApp->getDocumentsFolderPath()); selectFolder(qApp->getDocumentsFolderPath());
m_ui->m_txtBackupName->lineEdit()->setText(QString(APP_LOW_NAME) + QL1S("_") + QDateTime::currentDateTime().toString(QSL("yyyyMMddHHmm"))); 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.")); m_ui->m_lblResult->setStatus(WidgetWithStatus::Warning, tr("No operation executed yet."), tr("No operation executed yet."));
@ -64,6 +61,7 @@ void FormBackupDatabaseSettings::performBackup() {
tr("Backup was created successfully and stored in target directory."), tr("Backup was created successfully and stored in target directory."),
tr("Backup was created successfully.")); tr("Backup was created successfully."));
} }
catch (const ApplicationException& ex) { catch (const ApplicationException& ex) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(), tr("Backup failed.")); m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(), tr("Backup failed."));
} }
@ -88,6 +86,7 @@ void FormBackupDatabaseSettings::checkBackupNames(const QString &name) {
if (name.simplified().isEmpty()) { if (name.simplified().isEmpty()) {
m_ui->m_txtBackupName->setStatus(WidgetWithStatus::Error, tr("Backup name cannot be empty.")); m_ui->m_txtBackupName->setStatus(WidgetWithStatus::Error, tr("Backup name cannot be empty."));
} }
else { else {
m_ui->m_txtBackupName->setStatus(WidgetWithStatus::Ok, tr("Backup name looks okay.")); m_ui->m_txtBackupName->setStatus(WidgetWithStatus::Ok, tr("Backup name looks okay."));
} }

View File

@ -28,11 +28,9 @@
FormDatabaseCleanup::FormDatabaseCleanup(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormDatabaseCleanup), m_cleaner(nullptr) { FormDatabaseCleanup::FormDatabaseCleanup(QWidget* parent) : QDialog(parent), m_ui(new Ui::FormDatabaseCleanup), m_cleaner(nullptr) {
m_ui->setupUi(this); m_ui->setupUi(this);
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("edit-clear"))); setWindowIcon(qApp->icons()->fromTheme(QSL("edit-clear")));
connect(m_ui->m_spinDays, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &FormDatabaseCleanup::updateDaysSuffix); 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_spinDays->setValue(DEFAULT_DAYS_TO_DELETE_MSG);
m_ui->m_lblResult->setStatus(WidgetWithStatus::Information, tr("I am ready."), tr("I am ready.")); m_ui->m_lblResult->setStatus(WidgetWithStatus::Information, tr("I am ready."), tr("I am ready."));
@ -50,7 +48,6 @@ void FormDatabaseCleanup::setCleaner(DatabaseCleaner *cleaner) {
} }
m_cleaner = cleaner; m_cleaner = cleaner;
connect(m_ui->m_btnBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormDatabaseCleanup::startPurging); connect(m_ui->m_btnBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &FormDatabaseCleanup::startPurging);
connect(this, &FormDatabaseCleanup::purgeRequested, m_cleaner, &DatabaseCleaner::purgeDatabaseData); connect(this, &FormDatabaseCleanup::purgeRequested, m_cleaner, &DatabaseCleaner::purgeDatabaseData);
connect(m_cleaner, &DatabaseCleaner::purgeStarted, this, &FormDatabaseCleanup::onPurgeStarted); connect(m_cleaner, &DatabaseCleaner::purgeStarted, this, &FormDatabaseCleanup::onPurgeStarted);
@ -62,6 +59,7 @@ void FormDatabaseCleanup::closeEvent(QCloseEvent *event) {
if (m_ui->m_progressBar->isEnabled()) { if (m_ui->m_progressBar->isEnabled()) {
event->ignore(); event->ignore();
} }
else { else {
QDialog::closeEvent(event); QDialog::closeEvent(event);
} }
@ -71,6 +69,7 @@ void FormDatabaseCleanup::keyPressEvent(QKeyEvent *event) {
if (m_ui->m_progressBar->isEnabled()) { if (m_ui->m_progressBar->isEnabled()) {
event->ignore(); event->ignore();
} }
else { else {
QDialog::keyPressEvent(event); QDialog::keyPressEvent(event);
} }
@ -82,14 +81,12 @@ void FormDatabaseCleanup::updateDaysSuffix(int number) {
void FormDatabaseCleanup::startPurging() { void FormDatabaseCleanup::startPurging() {
CleanerOrders orders; CleanerOrders orders;
orders.m_removeRecycleBin = m_ui->m_checkRemoveRecycleBin->isChecked(); orders.m_removeRecycleBin = m_ui->m_checkRemoveRecycleBin->isChecked();
orders.m_removeOldMessages = m_ui->m_checkRemoveOldMessages->isChecked(); orders.m_removeOldMessages = m_ui->m_checkRemoveOldMessages->isChecked();
orders.m_barrierForRemovingOldMessagesInDays = m_ui->m_spinDays->value(); orders.m_barrierForRemovingOldMessagesInDays = m_ui->m_spinDays->value();
orders.m_removeReadMessages = m_ui->m_checkRemoveReadMessages->isChecked(); orders.m_removeReadMessages = m_ui->m_checkRemoveReadMessages->isChecked();
orders.m_shrinkDatabase = m_ui->m_checkShrink->isEnabled() && m_ui->m_checkShrink->isChecked(); orders.m_shrinkDatabase = m_ui->m_checkShrink->isEnabled() && m_ui->m_checkShrink->isChecked();
orders.m_removeStarredMessages = m_ui->m_checkRemoveStarredMessages->isChecked(); orders.m_removeStarredMessages = m_ui->m_checkRemoveStarredMessages->isChecked();
emit purgeRequested(orders); emit purgeRequested(orders);
} }
@ -113,6 +110,7 @@ void FormDatabaseCleanup::onPurgeFinished(bool finished) {
if (finished) { if (finished) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Database cleanup is completed."), tr("Database cleanup is completed.")); m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Database cleanup is completed."), tr("Database cleanup is completed."));
} }
else { else {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, tr("Database cleanup failed."), tr("Database cleanup failed.")); m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, tr("Database cleanup failed."), tr("Database cleanup failed."));
} }
@ -123,10 +121,8 @@ void FormDatabaseCleanup::onPurgeFinished(bool finished) {
void FormDatabaseCleanup::loadDatabaseInfo() { void FormDatabaseCleanup::loadDatabaseInfo() {
qint64 file_size = qApp->database()->getDatabaseFileSize(); qint64 file_size = qApp->database()->getDatabaseFileSize();
qint64 data_size = qApp->database()->getDatabaseDataSize(); qint64 data_size = qApp->database()->getDatabaseDataSize();
QString file_size_str = file_size > 0 ? QString::number(file_size / 1000000.0) + QL1S(" MB") : tr("unknown"); 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"); 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_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_txtDatabaseType->setText(qApp->database()->humanDriverName(qApp->database()->activeDatabaseDriver()));
m_ui->m_checkShrink->setEnabled(qApp->database()->activeDatabaseDriver() == DatabaseFactory::SQLITE || m_ui->m_checkShrink->setEnabled(qApp->database()->activeDatabaseDriver() == DatabaseFactory::SQLITE ||

View File

@ -63,47 +63,35 @@
FormMain::FormMain(QWidget* parent, Qt::WindowFlags f) FormMain::FormMain(QWidget* parent, Qt::WindowFlags f)
: QMainWindow(parent, f), m_ui(new Ui::FormMain) { : QMainWindow(parent, f), m_ui(new Ui::FormMain) {
m_ui->setupUi(this); m_ui->setupUi(this);
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
m_adblockIcon = new AdBlockIcon(this); m_adblockIcon = new AdBlockIcon(this);
m_adblockIconAction = m_adblockIcon->menuAction(); m_adblockIconAction = m_adblockIcon->menuAction();
m_adblockIconAction->setObjectName(QSL("m_adblockIconAction")); m_adblockIconAction->setObjectName(QSL("m_adblockIconAction"));
m_ui->m_menuTools->addAction(m_adblockIconAction); m_ui->m_menuTools->addAction(m_adblockIconAction);
#endif #endif
qApp->setMainForm(this); qApp->setMainForm(this);
// Add these actions to the list of actions of the main window. // Add these actions to the list of actions of the main window.
// This allows to use actions via shortcuts // This allows to use actions via shortcuts
// even if main menu is not visible. // even if main menu is not visible.
addActions(allActions()); addActions(allActions());
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
addAction(m_adblockIconAction); addAction(m_adblockIconAction);
#endif #endif
m_statusBar = new StatusBar(this); m_statusBar = new StatusBar(this);
setStatusBar(m_statusBar); setStatusBar(m_statusBar);
// Prepare main window and tabs. // Prepare main window and tabs.
prepareMenus(); prepareMenus();
// Prepare tabs. // Prepare tabs.
//m_ui->m_tabWidget->initializeTabs(); //m_ui->m_tabWidget->initializeTabs();
tabWidget()->feedMessageViewer()->feedsToolBar()->loadSavedActions(); tabWidget()->feedMessageViewer()->feedsToolBar()->loadSavedActions();
tabWidget()->feedMessageViewer()->messagesToolBar()->loadSavedActions(); tabWidget()->feedMessageViewer()->messagesToolBar()->loadSavedActions();
// Establish connections. // Establish connections.
createConnections(); createConnections();
updateMessageButtonsAvailability(); updateMessageButtonsAvailability();
updateFeedButtonsAvailability(); updateFeedButtonsAvailability();
// Setup some appearance of the window. // Setup some appearance of the window.
setupIcons(); setupIcons();
loadSize(); loadSize();
m_statusBar->loadSavedActions(); m_statusBar->loadSavedActions();
} }
@ -128,12 +116,11 @@ void FormMain::showDbCleanupAssistant() {
QScopedPointer<FormDatabaseCleanup> form_pointer(new FormDatabaseCleanup(this)); QScopedPointer<FormDatabaseCleanup> form_pointer(new FormDatabaseCleanup(this));
form_pointer.data()->setCleaner(qApp->feedReader()->databaseCleaner()); form_pointer.data()->setCleaner(qApp->feedReader()->databaseCleaner());
form_pointer.data()->exec(); form_pointer.data()->exec();
qApp->feedUpdateLock()->unlock(); qApp->feedUpdateLock()->unlock();
tabWidget()->feedMessageViewer()->messagesView()->reloadSelections(); tabWidget()->feedMessageViewer()->messagesView()->reloadSelections();
qApp->feedReader()->feedsModel()->reloadCountsOfWholeModel(); qApp->feedReader()->feedsModel()->reloadCountsOfWholeModel();
} }
else { else {
qApp->showGuiMessage(tr("Cannot cleanup database"), qApp->showGuiMessage(tr("Cannot cleanup database"),
tr("Cannot cleanup database, because another critical action is running."), tr("Cannot cleanup database, because another critical action is running."),
@ -143,7 +130,6 @@ void FormMain::showDbCleanupAssistant() {
QList<QAction*> FormMain::allActions() const { QList<QAction*> FormMain::allActions() const {
QList<QAction*> actions; QList<QAction*> actions;
// Add basic actions. // Add basic actions.
actions << m_ui->m_actionSettings; actions << m_ui->m_actionSettings;
actions << m_ui->m_actionDownloadManager; actions << m_ui->m_actionDownloadManager;
@ -164,7 +150,6 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionSwitchListHeaders; actions << m_ui->m_actionSwitchListHeaders;
actions << m_ui->m_actionSwitchStatusBar; actions << m_ui->m_actionSwitchStatusBar;
actions << m_ui->m_actionSwitchMessageListOrientation; actions << m_ui->m_actionSwitchMessageListOrientation;
// Add feeds/messages actions. // Add feeds/messages actions.
actions << m_ui->m_actionOpenSelectedSourceArticlesExternally; actions << m_ui->m_actionOpenSelectedSourceArticlesExternally;
actions << m_ui->m_actionOpenSelectedMessagesInternally; actions << m_ui->m_actionOpenSelectedMessagesInternally;
@ -196,15 +181,12 @@ QList<QAction*> FormMain::allActions() const {
actions << m_ui->m_actionSelectPreviousMessage; actions << m_ui->m_actionSelectPreviousMessage;
actions << m_ui->m_actionSelectNextUnreadMessage; actions << m_ui->m_actionSelectNextUnreadMessage;
actions << m_ui->m_actionExpandCollapseItem; actions << m_ui->m_actionExpandCollapseItem;
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
actions << m_ui->m_actionTabNewWebBrowser; actions << m_ui->m_actionTabNewWebBrowser;
actions << m_adblockIconAction; actions << m_adblockIconAction;
#endif #endif
actions << m_ui->m_actionTabsCloseAll; actions << m_ui->m_actionTabsCloseAll;
actions << m_ui->m_actionTabsCloseAllExceptCurrent; actions << m_ui->m_actionTabsCloseAllExceptCurrent;
return actions; return actions;
} }
@ -216,7 +198,6 @@ void FormMain::prepareMenus() {
#else #else
m_trayMenu = new QMenu(QSL(APP_NAME), this); m_trayMenu = new QMenu(QSL(APP_NAME), this);
#endif #endif
// Add needed items to the menu. // Add needed items to the menu.
m_trayMenu->addAction(m_ui->m_actionSwitchMainWindow); m_trayMenu->addAction(m_ui->m_actionSwitchMainWindow);
m_trayMenu->addSeparator(); m_trayMenu->addSeparator();
@ -225,7 +206,6 @@ void FormMain::prepareMenus() {
m_trayMenu->addSeparator(); m_trayMenu->addSeparator();
m_trayMenu->addAction(m_ui->m_actionSettings); m_trayMenu->addAction(m_ui->m_actionSettings);
m_trayMenu->addAction(m_ui->m_actionQuit); m_trayMenu->addAction(m_ui->m_actionQuit);
qDebug("Creating tray icon menu."); qDebug("Creating tray icon menu.");
} }
@ -233,7 +213,6 @@ void FormMain::prepareMenus() {
m_ui->m_menuWebBrowserTabs->removeAction(m_ui->m_actionTabNewWebBrowser); m_ui->m_menuWebBrowserTabs->removeAction(m_ui->m_actionTabNewWebBrowser);
m_ui->m_menuWebBrowserTabs->setTitle(tr("Tabs")); m_ui->m_menuWebBrowserTabs->setTitle(tr("Tabs"));
#endif #endif
#if defined(Q_OS_MAC) #if defined(Q_OS_MAC)
m_ui->m_actionSwitchMainMenu->setVisible(false); m_ui->m_actionSwitchMainMenu->setVisible(false);
m_ui->m_actionFullscreen->setVisible(false); m_ui->m_actionFullscreen->setVisible(false);
@ -245,10 +224,12 @@ void FormMain::switchFullscreenMode() {
qApp->settings()->setValue(GROUP(GUI), GUI::IsMainWindowMaximizedBeforeFullscreen, isMaximized()); qApp->settings()->setValue(GROUP(GUI), GUI::IsMainWindowMaximizedBeforeFullscreen, isMaximized());
showFullScreen(); showFullScreen();
} }
else { else {
if (qApp->settings()->value(GROUP(GUI), SETTING(GUI::IsMainWindowMaximizedBeforeFullscreen)).toBool()) { if (qApp->settings()->value(GROUP(GUI), SETTING(GUI::IsMainWindowMaximizedBeforeFullscreen)).toBool()) {
setWindowState((windowState() & ~Qt::WindowFullScreen) | Qt::WindowMaximized); setWindowState((windowState() & ~Qt::WindowFullScreen) | Qt::WindowMaximized);
} }
else { else {
showNormal(); showNormal();
} }
@ -263,7 +244,6 @@ void FormMain::updateAddItemMenu() {
QMenu* root_menu = new QMenu(activated_root->title(), m_ui->m_menuAddItem); QMenu* root_menu = new QMenu(activated_root->title(), m_ui->m_menuAddItem);
root_menu->setIcon(activated_root->icon()); root_menu->setIcon(activated_root->icon());
root_menu->setToolTip(activated_root->description()); root_menu->setToolTip(activated_root->description());
QList<QAction*> specific_root_actions = activated_root->addItemMenu(); QList<QAction*> specific_root_actions = activated_root->addItemMenu();
if (activated_root->supportsCategoryAdding()) { if (activated_root->supportsCategoryAdding()) {
@ -299,6 +279,7 @@ void FormMain::updateAddItemMenu() {
m_ui->m_menuAddItem->addAction(m_ui->m_actionAddCategoryIntoSelectedAccount); m_ui->m_menuAddItem->addAction(m_ui->m_actionAddCategoryIntoSelectedAccount);
m_ui->m_menuAddItem->addAction(m_ui->m_actionAddFeedIntoSelectedAccount); m_ui->m_menuAddItem->addAction(m_ui->m_actionAddFeedIntoSelectedAccount);
} }
else { else {
m_ui->m_menuAddItem->addAction(m_ui->m_actionNoActions); m_ui->m_menuAddItem->addAction(m_ui->m_actionNoActions);
} }
@ -311,7 +292,6 @@ void FormMain::updateRecycleBinMenu() {
QMenu* root_menu = new QMenu(activated_root->title(), m_ui->m_menuRecycleBin); QMenu* root_menu = new QMenu(activated_root->title(), m_ui->m_menuRecycleBin);
root_menu->setIcon(activated_root->icon()); root_menu->setIcon(activated_root->icon());
root_menu->setToolTip(activated_root->description()); root_menu->setToolTip(activated_root->description());
RecycleBin* bin = activated_root->recycleBin(); RecycleBin* bin = activated_root->recycleBin();
QList<QAction*> context_menu; QList<QAction*> context_menu;
@ -322,6 +302,7 @@ void FormMain::updateRecycleBinMenu() {
no_action->setEnabled(false); no_action->setEnabled(false);
root_menu->addAction(no_action); root_menu->addAction(no_action);
} }
else if ((context_menu = bin->contextMenu()).isEmpty()) { else if ((context_menu = bin->contextMenu()).isEmpty()) {
QAction* no_action = new QAction(qApp->icons()->fromTheme(QSL("dialog-error")), QAction* no_action = new QAction(qApp->icons()->fromTheme(QSL("dialog-error")),
tr("No actions possible"), tr("No actions possible"),
@ -329,6 +310,7 @@ void FormMain::updateRecycleBinMenu() {
no_action->setEnabled(false); no_action->setEnabled(false);
root_menu->addAction(no_action); root_menu->addAction(no_action);
} }
else { else {
root_menu->addActions(context_menu); root_menu->addActions(context_menu);
} }
@ -351,7 +333,6 @@ void FormMain::updateAccountsMenu() {
QMenu* root_menu = new QMenu(activated_root->title(), m_ui->m_menuAccounts); QMenu* root_menu = new QMenu(activated_root->title(), m_ui->m_menuAccounts);
root_menu->setIcon(activated_root->icon()); root_menu->setIcon(activated_root->icon());
root_menu->setToolTip(activated_root->description()); root_menu->setToolTip(activated_root->description());
QList<QAction*> root_actions = activated_root->serviceMenu(); QList<QAction*> root_actions = activated_root->serviceMenu();
if (root_actions.isEmpty()) { if (root_actions.isEmpty()) {
@ -361,6 +342,7 @@ void FormMain::updateAccountsMenu() {
no_action->setEnabled(false); no_action->setEnabled(false);
root_menu->addAction(no_action); root_menu->addAction(no_action);
} }
else { else {
root_menu->addActions(root_actions); root_menu->addActions(root_actions);
} }
@ -379,7 +361,6 @@ void FormMain::updateAccountsMenu() {
void FormMain::onFeedUpdatesFinished(const FeedDownloadResults& results) { void FormMain::onFeedUpdatesFinished(const FeedDownloadResults& results) {
Q_UNUSED(results) Q_UNUSED(results)
statusBar()->clearProgressFeeds(); statusBar()->clearProgressFeeds();
tabWidget()->feedMessageViewer()->messagesView()->reloadSelections(); tabWidget()->feedMessageViewer()->messagesView()->reloadSelections();
} }
@ -398,8 +379,8 @@ void FormMain::onFeedUpdatesProgress(const Feed *feed, int current, int total) {
void FormMain::updateMessageButtonsAvailability() { void FormMain::updateMessageButtonsAvailability() {
const bool one_message_selected = tabWidget()->feedMessageViewer()->messagesView()->selectionModel()->selectedRows().size() == 1; const bool one_message_selected = tabWidget()->feedMessageViewer()->messagesView()->selectionModel()->selectedRows().size() == 1;
const bool atleast_one_message_selected = !tabWidget()->feedMessageViewer()->messagesView()->selectionModel()->selectedRows().isEmpty(); const bool atleast_one_message_selected = !tabWidget()->feedMessageViewer()->messagesView()->selectionModel()->selectedRows().isEmpty();
const bool bin_loaded = tabWidget()->feedMessageViewer()->messagesView()->sourceModel()->loadedItem() != nullptr && tabWidget()->feedMessageViewer()->messagesView()->sourceModel()->loadedItem()->kind() == RootItemKind::Bin; const bool bin_loaded = tabWidget()->feedMessageViewer()->messagesView()->sourceModel()->loadedItem() != nullptr
&& tabWidget()->feedMessageViewer()->messagesView()->sourceModel()->loadedItem()->kind() == RootItemKind::Bin;
m_ui->m_actionDeleteSelectedMessages->setEnabled(atleast_one_message_selected); m_ui->m_actionDeleteSelectedMessages->setEnabled(atleast_one_message_selected);
m_ui->m_actionRestoreSelectedMessages->setEnabled(atleast_one_message_selected && bin_loaded); m_ui->m_actionRestoreSelectedMessages->setEnabled(atleast_one_message_selected && bin_loaded);
m_ui->m_actionMarkSelectedMessagesAsRead->setEnabled(atleast_one_message_selected); m_ui->m_actionMarkSelectedMessagesAsRead->setEnabled(atleast_one_message_selected);
@ -418,7 +399,6 @@ void FormMain::updateFeedButtonsAvailability() {
const bool feed_selected = anything_selected && selected_item->kind() == RootItemKind::Feed; const bool feed_selected = anything_selected && selected_item->kind() == RootItemKind::Feed;
const bool category_selected = anything_selected && selected_item->kind() == RootItemKind::Category; const bool category_selected = anything_selected && selected_item->kind() == RootItemKind::Category;
const bool service_selected = anything_selected && selected_item->kind() == RootItemKind::ServiceRoot; const bool service_selected = anything_selected && selected_item->kind() == RootItemKind::ServiceRoot;
m_ui->m_actionStopRunningItemsUpdate->setEnabled(is_update_running); m_ui->m_actionStopRunningItemsUpdate->setEnabled(is_update_running);
m_ui->m_actionBackupDatabaseSettings->setEnabled(!critical_action_running); m_ui->m_actionBackupDatabaseSettings->setEnabled(!critical_action_running);
m_ui->m_actionCleanupDatabase->setEnabled(!critical_action_running); m_ui->m_actionCleanupDatabase->setEnabled(!critical_action_running);
@ -431,12 +411,10 @@ void FormMain::updateFeedButtonsAvailability() {
m_ui->m_actionUpdateSelectedItems->setEnabled(!critical_action_running && (feed_selected || category_selected || service_selected)); m_ui->m_actionUpdateSelectedItems->setEnabled(!critical_action_running && (feed_selected || category_selected || service_selected));
m_ui->m_actionViewSelectedItemsNewspaperMode->setEnabled(anything_selected); m_ui->m_actionViewSelectedItemsNewspaperMode->setEnabled(anything_selected);
m_ui->m_actionExpandCollapseItem->setEnabled(anything_selected); m_ui->m_actionExpandCollapseItem->setEnabled(anything_selected);
m_ui->m_actionServiceDelete->setEnabled(service_selected); m_ui->m_actionServiceDelete->setEnabled(service_selected);
m_ui->m_actionServiceEdit->setEnabled(service_selected); m_ui->m_actionServiceEdit->setEnabled(service_selected);
m_ui->m_actionAddFeedIntoSelectedAccount->setEnabled(anything_selected); m_ui->m_actionAddFeedIntoSelectedAccount->setEnabled(anything_selected);
m_ui->m_actionAddCategoryIntoSelectedAccount->setEnabled(anything_selected); m_ui->m_actionAddCategoryIntoSelectedAccount->setEnabled(anything_selected);
m_ui->m_menuAddItem->setEnabled(!critical_action_running); m_ui->m_menuAddItem->setEnabled(!critical_action_running);
m_ui->m_menuAccounts->setEnabled(!critical_action_running); m_ui->m_menuAccounts->setEnabled(!critical_action_running);
m_ui->m_menuRecycleBin->setEnabled(!critical_action_running); m_ui->m_menuRecycleBin->setEnabled(!critical_action_running);
@ -447,11 +425,13 @@ void FormMain::switchVisibility(bool force_hide) {
if (SystemTrayIcon::isSystemTrayActivated()) { if (SystemTrayIcon::isSystemTrayActivated()) {
hide(); hide();
} }
else { else {
// Window gets minimized in single-window mode. // Window gets minimized in single-window mode.
showMinimized(); showMinimized();
} }
} }
else { else {
display(); display();
} }
@ -460,19 +440,16 @@ void FormMain::switchVisibility(bool force_hide) {
void FormMain::display() { void FormMain::display() {
// Make sure window is not minimized. // Make sure window is not minimized.
setWindowState(windowState() & ~Qt::WindowMinimized); setWindowState(windowState() & ~Qt::WindowMinimized);
// Display the window and make sure it is raised on top. // Display the window and make sure it is raised on top.
show(); show();
activateWindow(); activateWindow();
raise(); raise();
// Raise alert event. Check the documentation for more info on this. // Raise alert event. Check the documentation for more info on this.
Application::alert(this); Application::alert(this);
} }
void FormMain::setupIcons() { void FormMain::setupIcons() {
IconFactory* icon_theme_factory = qApp->icons(); IconFactory* icon_theme_factory = qApp->icons();
// Setup icons of this main window. // Setup icons of this main window.
m_ui->m_actionDownloadManager->setIcon(icon_theme_factory->fromTheme(QSL("emblem-downloads"))); m_ui->m_actionDownloadManager->setIcon(icon_theme_factory->fromTheme(QSL("emblem-downloads")));
m_ui->m_actionSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-properties"))); m_ui->m_actionSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-properties")));
@ -486,7 +463,6 @@ void FormMain::setupIcons() {
m_ui->m_actionRestoreDatabaseSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-import"))); m_ui->m_actionRestoreDatabaseSettings->setIcon(icon_theme_factory->fromTheme(QSL("document-import")));
m_ui->m_actionDonate->setIcon(icon_theme_factory->fromTheme(QSL("applications-office"))); m_ui->m_actionDonate->setIcon(icon_theme_factory->fromTheme(QSL("applications-office")));
m_ui->m_actionDisplayWiki->setIcon(icon_theme_factory->fromTheme(QSL("applications-science"))); m_ui->m_actionDisplayWiki->setIcon(icon_theme_factory->fromTheme(QSL("applications-science")));
// View. // View.
m_ui->m_actionSwitchMainWindow->setIcon(icon_theme_factory->fromTheme(QSL("window-close"))); m_ui->m_actionSwitchMainWindow->setIcon(icon_theme_factory->fromTheme(QSL("window-close")));
m_ui->m_actionFullscreen->setIcon(icon_theme_factory->fromTheme(QSL("view-fullscreen"))); m_ui->m_actionFullscreen->setIcon(icon_theme_factory->fromTheme(QSL("view-fullscreen")));
@ -497,7 +473,6 @@ void FormMain::setupIcons() {
m_ui->m_actionSwitchStatusBar->setIcon(icon_theme_factory->fromTheme(QSL("dialog-information"))); m_ui->m_actionSwitchStatusBar->setIcon(icon_theme_factory->fromTheme(QSL("dialog-information")));
m_ui->m_actionSwitchMessageListOrientation->setIcon(icon_theme_factory->fromTheme(QSL("view-restore"))); m_ui->m_actionSwitchMessageListOrientation->setIcon(icon_theme_factory->fromTheme(QSL("view-restore")));
m_ui->m_menuShowHide->setIcon(icon_theme_factory->fromTheme(QSL("view-restore"))); m_ui->m_menuShowHide->setIcon(icon_theme_factory->fromTheme(QSL("view-restore")));
// Feeds/messages. // Feeds/messages.
m_ui->m_menuAddItem->setIcon(icon_theme_factory->fromTheme(QSL("list-add"))); m_ui->m_menuAddItem->setIcon(icon_theme_factory->fromTheme(QSL("list-add")));
m_ui->m_actionStopRunningItemsUpdate->setIcon(icon_theme_factory->fromTheme(QSL("process-stop"))); m_ui->m_actionStopRunningItemsUpdate->setIcon(icon_theme_factory->fromTheme(QSL("process-stop")));
@ -533,12 +508,10 @@ void FormMain::setupIcons() {
m_ui->m_actionServiceDelete->setIcon(icon_theme_factory->fromTheme(QSL("list-remove"))); m_ui->m_actionServiceDelete->setIcon(icon_theme_factory->fromTheme(QSL("list-remove")));
m_ui->m_actionAddFeedIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("application-rss+xml"))); m_ui->m_actionAddFeedIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("application-rss+xml")));
m_ui->m_actionAddCategoryIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("folder"))); m_ui->m_actionAddCategoryIntoSelectedAccount->setIcon(icon_theme_factory->fromTheme(QSL("folder")));
// Tabs & web browser. // Tabs & web browser.
m_ui->m_actionTabNewWebBrowser->setIcon(icon_theme_factory->fromTheme(QSL("tab-new"))); m_ui->m_actionTabNewWebBrowser->setIcon(icon_theme_factory->fromTheme(QSL("tab-new")));
m_ui->m_actionTabsCloseAll->setIcon(icon_theme_factory->fromTheme(QSL("window-close"))); m_ui->m_actionTabsCloseAll->setIcon(icon_theme_factory->fromTheme(QSL("window-close")));
m_ui->m_actionTabsCloseAllExceptCurrent->setIcon(icon_theme_factory->fromTheme(QSL("window-close"))); m_ui->m_actionTabsCloseAllExceptCurrent->setIcon(icon_theme_factory->fromTheme(QSL("window-close")));
// Setup icons on TabWidget too. // Setup icons on TabWidget too.
m_ui->m_tabWidget->setupIcons(); m_ui->m_tabWidget->setupIcons();
} }
@ -546,14 +519,12 @@ void FormMain::setupIcons() {
void FormMain::loadSize() { void FormMain::loadSize() {
const QRect screen = qApp->desktop()->screenGeometry(); const QRect screen = qApp->desktop()->screenGeometry();
const Settings* settings = qApp->settings(); const Settings* settings = qApp->settings();
// Reload main window size & position. // Reload main window size & position.
resize(settings->value(GROUP(GUI), GUI::MainWindowInitialSize, size()).toSize()); resize(settings->value(GROUP(GUI), GUI::MainWindowInitialSize, size()).toSize());
move(settings->value(GROUP(GUI), GUI::MainWindowInitialPosition, screen.center() - rect().center()).toPoint()); move(settings->value(GROUP(GUI), GUI::MainWindowInitialPosition, screen.center() - rect().center()).toPoint());
if (settings->value(GROUP(GUI), SETTING(GUI::MainWindowStartsMaximized)).toBool()) { if (settings->value(GROUP(GUI), SETTING(GUI::MainWindowStartsMaximized)).toBool()) {
setWindowState(windowState() | Qt::WindowMaximized); setWindowState(windowState() | Qt::WindowMaximized);
// We process events so that window is really maximized fast. // We process events so that window is really maximized fast.
qApp->processEvents(); qApp->processEvents();
} }
@ -566,13 +537,11 @@ void FormMain::loadSize() {
// Hide the main menu if user wants it. // Hide the main menu if user wants it.
m_ui->m_actionSwitchMainMenu->setChecked(settings->value(GROUP(GUI), SETTING(GUI::MainMenuVisible)).toBool()); m_ui->m_actionSwitchMainMenu->setChecked(settings->value(GROUP(GUI), SETTING(GUI::MainMenuVisible)).toBool());
// Adjust dimensions of "feeds & messages" widget. // Adjust dimensions of "feeds & messages" widget.
m_ui->m_tabWidget->feedMessageViewer()->loadSize(); m_ui->m_tabWidget->feedMessageViewer()->loadSize();
m_ui->m_actionSwitchToolBars->setChecked(settings->value(GROUP(GUI), SETTING(GUI::ToolbarsVisible)).toBool()); m_ui->m_actionSwitchToolBars->setChecked(settings->value(GROUP(GUI), SETTING(GUI::ToolbarsVisible)).toBool());
m_ui->m_actionSwitchListHeaders->setChecked(settings->value(GROUP(GUI), SETTING(GUI::ListHeadersVisible)).toBool()); m_ui->m_actionSwitchListHeaders->setChecked(settings->value(GROUP(GUI), SETTING(GUI::ListHeadersVisible)).toBool());
m_ui->m_actionSwitchStatusBar->setChecked(settings->value(GROUP(GUI), SETTING(GUI::StatusBarVisible)).toBool()); m_ui->m_actionSwitchStatusBar->setChecked(settings->value(GROUP(GUI), SETTING(GUI::StatusBarVisible)).toBool());
// Make sure that only unread feeds are shown if user has that feature set on. // Make sure that only unread feeds are shown if user has that feature set on.
m_ui->m_actionShowOnlyUnreadItems->setChecked(settings->value(GROUP(Feeds), SETTING(Feeds::ShowOnlyUnreadFeeds)).toBool()); m_ui->m_actionShowOnlyUnreadItems->setChecked(settings->value(GROUP(Feeds), SETTING(Feeds::ShowOnlyUnreadFeeds)).toBool());
} }
@ -584,18 +553,15 @@ void FormMain::saveSize() {
if (is_fullscreen) { if (is_fullscreen) {
m_ui->m_actionFullscreen->setChecked(false); m_ui->m_actionFullscreen->setChecked(false);
// We (process events to really) un-fullscreen, so that we can determine if window is really maximized. // We (process events to really) un-fullscreen, so that we can determine if window is really maximized.
qApp->processEvents(); qApp->processEvents();
} }
if (isMaximized()) { if (isMaximized()) {
is_maximized = true; is_maximized = true;
// Window is maximized, we store that fact to settings and unmaximize. // Window is maximized, we store that fact to settings and unmaximize.
qApp->settings()->setValue(GROUP(GUI), GUI::IsMainWindowMaximizedBeforeFullscreen, isMaximized()); qApp->settings()->setValue(GROUP(GUI), GUI::IsMainWindowMaximizedBeforeFullscreen, isMaximized());
setWindowState((windowState() & ~Qt::WindowMaximized) | Qt::WindowActive); setWindowState((windowState() & ~Qt::WindowMaximized) | Qt::WindowActive);
// We process events to really have window un-maximized. // We process events to really have window un-maximized.
qApp->processEvents(); qApp->processEvents();
} }
@ -606,7 +572,6 @@ void FormMain::saveSize() {
settings->setValue(GROUP(GUI), GUI::MainWindowStartsMaximized, is_maximized); settings->setValue(GROUP(GUI), GUI::MainWindowStartsMaximized, is_maximized);
settings->setValue(GROUP(GUI), GUI::MainWindowStartsFullscreen, is_fullscreen); settings->setValue(GROUP(GUI), GUI::MainWindowStartsFullscreen, is_fullscreen);
settings->setValue(GROUP(GUI), GUI::StatusBarVisible, m_ui->m_actionSwitchStatusBar->isChecked()); settings->setValue(GROUP(GUI), GUI::StatusBarVisible, m_ui->m_actionSwitchStatusBar->isChecked());
m_ui->m_tabWidget->feedMessageViewer()->saveSize(); m_ui->m_tabWidget->feedMessageViewer()->saveSize();
} }
@ -615,53 +580,43 @@ void FormMain::createConnections() {
connect(m_ui->m_menuAddItem, &QMenu::aboutToShow, this, &FormMain::updateAddItemMenu); connect(m_ui->m_menuAddItem, &QMenu::aboutToShow, this, &FormMain::updateAddItemMenu);
connect(m_ui->m_menuRecycleBin, &QMenu::aboutToShow, this, &FormMain::updateRecycleBinMenu); connect(m_ui->m_menuRecycleBin, &QMenu::aboutToShow, this, &FormMain::updateRecycleBinMenu);
connect(m_ui->m_menuAccounts, &QMenu::aboutToShow, this, &FormMain::updateAccountsMenu); connect(m_ui->m_menuAccounts, &QMenu::aboutToShow, this, &FormMain::updateAccountsMenu);
connect(m_ui->m_actionServiceDelete, &QAction::triggered, m_ui->m_actionDeleteSelectedItem, &QAction::triggered); connect(m_ui->m_actionServiceDelete, &QAction::triggered, m_ui->m_actionDeleteSelectedItem, &QAction::triggered);
connect(m_ui->m_actionServiceEdit, &QAction::triggered, m_ui->m_actionEditSelectedItem, &QAction::triggered); connect(m_ui->m_actionServiceEdit, &QAction::triggered, m_ui->m_actionEditSelectedItem, &QAction::triggered);
// Menu "File" connections. // Menu "File" connections.
connect(m_ui->m_actionBackupDatabaseSettings, &QAction::triggered, this, &FormMain::backupDatabaseSettings); connect(m_ui->m_actionBackupDatabaseSettings, &QAction::triggered, this, &FormMain::backupDatabaseSettings);
connect(m_ui->m_actionRestoreDatabaseSettings, &QAction::triggered, this, &FormMain::restoreDatabaseSettings); connect(m_ui->m_actionRestoreDatabaseSettings, &QAction::triggered, this, &FormMain::restoreDatabaseSettings);
connect(m_ui->m_actionQuit, &QAction::triggered, qApp, &Application::quit); connect(m_ui->m_actionQuit, &QAction::triggered, qApp, &Application::quit);
connect(m_ui->m_actionServiceAdd, &QAction::triggered, this, &FormMain::showAddAccountDialog); connect(m_ui->m_actionServiceAdd, &QAction::triggered, this, &FormMain::showAddAccountDialog);
connect(m_ui->m_actionRestart, &QAction::triggered, qApp, &Application::restart); connect(m_ui->m_actionRestart, &QAction::triggered, qApp, &Application::restart);
// Menu "View" connections. // Menu "View" connections.
connect(m_ui->m_actionFullscreen, &QAction::toggled, this, &FormMain::switchFullscreenMode); connect(m_ui->m_actionFullscreen, &QAction::toggled, this, &FormMain::switchFullscreenMode);
connect(m_ui->m_actionSwitchMainMenu, &QAction::toggled, m_ui->m_menuBar, &QMenuBar::setVisible); connect(m_ui->m_actionSwitchMainMenu, &QAction::toggled, m_ui->m_menuBar, &QMenuBar::setVisible);
connect(m_ui->m_actionSwitchMainWindow, &QAction::triggered, this, &FormMain::switchVisibility); connect(m_ui->m_actionSwitchMainWindow, &QAction::triggered, this, &FormMain::switchVisibility);
connect(m_ui->m_actionSwitchStatusBar, &QAction::toggled, statusBar(), &StatusBar::setVisible); connect(m_ui->m_actionSwitchStatusBar, &QAction::toggled, statusBar(), &StatusBar::setVisible);
// Menu "Tools" connections. // Menu "Tools" connections.
connect(m_ui->m_actionSettings, &QAction::triggered, this, &FormMain::showSettings); connect(m_ui->m_actionSettings, &QAction::triggered, this, &FormMain::showSettings);
connect(m_ui->m_actionDownloadManager, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::showDownloadManager); connect(m_ui->m_actionDownloadManager, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::showDownloadManager);
connect(m_ui->m_actionCleanupDatabase, &QAction::triggered, this, &FormMain::showDbCleanupAssistant); connect(m_ui->m_actionCleanupDatabase, &QAction::triggered, this, &FormMain::showDbCleanupAssistant);
// Menu "Help" connections. // Menu "Help" connections.
connect(m_ui->m_actionAboutGuard, &QAction::triggered, this, &FormMain::showAbout); connect(m_ui->m_actionAboutGuard, &QAction::triggered, this, &FormMain::showAbout);
connect(m_ui->m_actionCheckForUpdates, &QAction::triggered, this, &FormMain::showUpdates); connect(m_ui->m_actionCheckForUpdates, &QAction::triggered, this, &FormMain::showUpdates);
connect(m_ui->m_actionReportBug, &QAction::triggered, this, &FormMain::reportABug); connect(m_ui->m_actionReportBug, &QAction::triggered, this, &FormMain::reportABug);
connect(m_ui->m_actionDonate, &QAction::triggered, this, &FormMain::donate); connect(m_ui->m_actionDonate, &QAction::triggered, this, &FormMain::donate);
connect(m_ui->m_actionDisplayWiki, &QAction::triggered, this, &FormMain::showWiki); connect(m_ui->m_actionDisplayWiki, &QAction::triggered, this, &FormMain::showWiki);
// Tab widget connections. // Tab widget connections.
connect(m_ui->m_actionTabsCloseAllExceptCurrent, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabsExceptCurrent); connect(m_ui->m_actionTabsCloseAllExceptCurrent, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabsExceptCurrent);
connect(m_ui->m_actionTabsCloseAll, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabs); connect(m_ui->m_actionTabsCloseAll, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::closeAllTabs);
connect(m_ui->m_actionTabNewWebBrowser, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::addEmptyBrowser); connect(m_ui->m_actionTabNewWebBrowser, &QAction::triggered, m_ui->m_tabWidget, &TabWidget::addEmptyBrowser);
connect(tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::itemSelected, this, &FormMain::updateFeedButtonsAvailability); connect(tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::itemSelected, this, &FormMain::updateFeedButtonsAvailability);
connect(qApp->feedUpdateLock(), &Mutex::locked, this, &FormMain::updateFeedButtonsAvailability); connect(qApp->feedUpdateLock(), &Mutex::locked, this, &FormMain::updateFeedButtonsAvailability);
connect(qApp->feedUpdateLock(), &Mutex::unlocked, this, &FormMain::updateFeedButtonsAvailability); connect(qApp->feedUpdateLock(), &Mutex::unlocked, this, &FormMain::updateFeedButtonsAvailability);
connect(tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::currentMessageRemoved, connect(tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::currentMessageRemoved,
this, &FormMain::updateMessageButtonsAvailability); this, &FormMain::updateMessageButtonsAvailability);
connect(tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::currentMessageChanged, connect(tabWidget()->feedMessageViewer()->messagesView(), &MessagesView::currentMessageChanged,
this, &FormMain::updateMessageButtonsAvailability); this, &FormMain::updateMessageButtonsAvailability);
connect(qApp->feedReader(), &FeedReader::feedUpdatesStarted, this, &FormMain::onFeedUpdatesStarted); connect(qApp->feedReader(), &FeedReader::feedUpdatesStarted, this, &FormMain::onFeedUpdatesStarted);
connect(qApp->feedReader(), &FeedReader::feedUpdatesProgress, this, &FormMain::onFeedUpdatesProgress); connect(qApp->feedReader(), &FeedReader::feedUpdatesProgress, this, &FormMain::onFeedUpdatesProgress);
connect(qApp->feedReader(), &FeedReader::feedUpdatesFinished, this, &FormMain::onFeedUpdatesFinished); connect(qApp->feedReader(), &FeedReader::feedUpdatesFinished, this, &FormMain::onFeedUpdatesFinished);
// Toolbar forwardings. // Toolbar forwardings.
connect(m_ui->m_actionAddFeedIntoSelectedAccount, &QAction::triggered, connect(m_ui->m_actionAddFeedIntoSelectedAccount, &QAction::triggered,
tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::addFeedIntoSelectedAccount); tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::addFeedIntoSelectedAccount);

View File

@ -28,13 +28,10 @@
FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget* parent) FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget* parent)
: QDialog(parent), m_ui(new Ui::FormRestoreDatabaseSettings), m_shouldRestart(false) { : QDialog(parent), m_ui(new Ui::FormRestoreDatabaseSettings), m_shouldRestart(false) {
m_ui->setupUi(this); m_ui->setupUi(this);
m_btnRestart = m_ui->m_buttonBox->addButton(tr("Restart"), QDialogButtonBox::ActionRole); 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.")); m_ui->m_lblResult->setStatus(WidgetWithStatus::Warning, tr("No operation executed yet."), tr("No operation executed yet."));
setWindowIcon(qApp->icons()->fromTheme(QSL("document-import"))); setWindowIcon(qApp->icons()->fromTheme(QSL("document-import")));
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
connect(m_btnRestart, &QPushButton::clicked, this, [ = ]() { connect(m_btnRestart, &QPushButton::clicked, this, [ = ]() {
m_shouldRestart = true; m_shouldRestart = true;
close(); close();
@ -43,7 +40,6 @@ FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget *parent)
connect(m_ui->m_groupDatabase, SIGNAL(toggled(bool)), this, SLOT(checkOkButton())); 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_groupSettings, SIGNAL(toggled(bool)), this, SLOT(checkOkButton()));
connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(performRestoration())); connect(m_ui->m_buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(performRestoration()));
selectFolder(qApp->getDocumentsFolderPath()); selectFolder(qApp->getDocumentsFolderPath());
} }
@ -67,6 +63,7 @@ void FormRestoreDatabaseSettings::performRestoration() {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Restoration was initiated. Restart to proceed."), 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.")); tr("You need to restart application for restoration process to finish."));
} }
catch (const ApplicationException& ex) { catch (const ApplicationException& ex) {
m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(), m_ui->m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(),
tr("Database and/or settings were not copied to restoration directory successully.")); tr("Database and/or settings were not copied to restoration directory successully."));
@ -95,6 +92,7 @@ void FormRestoreDatabaseSettings::selectFolder(QString folder) {
m_ui->m_lblSelectFolder->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(folder), m_ui->m_lblSelectFolder->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(folder),
tr("Good source directory is specified.")); tr("Good source directory is specified."));
} }
else { else {
return; return;
} }
@ -110,7 +108,6 @@ void FormRestoreDatabaseSettings::selectFolder(QString folder) {
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable | QDir::Files | QDir::NoDotAndDotDot | QDir::Readable |
QDir::CaseSensitive | QDir::NoSymLinks, QDir::CaseSensitive | QDir::NoSymLinks,
QDir::Name); QDir::Name);
m_ui->m_listDatabase->clear(); m_ui->m_listDatabase->clear();
m_ui->m_listSettings->clear(); m_ui->m_listSettings->clear();

View File

@ -35,19 +35,15 @@
FormSettings::FormSettings(QWidget* parent) : QDialog(parent), m_panels(QList<SettingsPanel*>()), m_ui(new Ui::FormSettings), m_settings(qApp->settings()) { FormSettings::FormSettings(QWidget* parent) : QDialog(parent), m_panels(QList<SettingsPanel*>()), m_ui(new Ui::FormSettings), m_settings(qApp->settings()) {
m_ui->setupUi(this); m_ui->setupUi(this);
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("emblem-system"))); setWindowIcon(qApp->icons()->fromTheme(QSL("emblem-system")));
m_btnApply = m_ui->m_buttonBox->button(QDialogButtonBox::Apply); m_btnApply = m_ui->m_buttonBox->button(QDialogButtonBox::Apply);
m_btnApply->setEnabled(false); m_btnApply->setEnabled(false);
// Establish needed connections. // Establish needed connections.
connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormSettings::saveSettings); connect(m_ui->m_buttonBox, &QDialogButtonBox::accepted, this, &FormSettings::saveSettings);
connect(m_ui->m_buttonBox, &QDialogButtonBox::rejected, this, &FormSettings::cancelSettings); connect(m_ui->m_buttonBox, &QDialogButtonBox::rejected, this, &FormSettings::cancelSettings);
connect(m_btnApply, &QPushButton::clicked, this, &FormSettings::applySettings); connect(m_btnApply, &QPushButton::clicked, this, &FormSettings::applySettings);
addSettingsPanel(new SettingsGeneral(m_settings, this)); addSettingsPanel(new SettingsGeneral(m_settings, this));
addSettingsPanel(new SettingsDatabase(m_settings, this)); addSettingsPanel(new SettingsDatabase(m_settings, this));
addSettingsPanel(new SettingsGui(m_settings, this)); addSettingsPanel(new SettingsGui(m_settings, this));
@ -56,7 +52,6 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_panels(QList<Se
addSettingsPanel(new SettingsBrowserMail(m_settings, this)); addSettingsPanel(new SettingsBrowserMail(m_settings, this));
addSettingsPanel(new SettingsDownloads(m_settings, this)); addSettingsPanel(new SettingsDownloads(m_settings, this));
addSettingsPanel(new SettingsFeedsMessages(m_settings, this)); addSettingsPanel(new SettingsFeedsMessages(m_settings, this));
m_ui->m_listSettings->setCurrentRow(0); m_ui->m_listSettings->setCurrentRow(0);
} }
@ -72,7 +67,6 @@ void FormSettings::saveSettings() {
void FormSettings::applySettings() { void FormSettings::applySettings() {
// Save all settings. // Save all settings.
m_settings->checkSettings(); m_settings->checkSettings();
QStringList panels_for_restart; QStringList panels_for_restart;
foreach (SettingsPanel* panel, m_panels) { foreach (SettingsPanel* panel, m_panels) {
@ -88,7 +82,6 @@ void FormSettings::applySettings() {
if (!panels_for_restart.isEmpty()) { if (!panels_for_restart.isEmpty()) {
const QStringList changed_settings_description = panels_for_restart.replaceInStrings(QRegExp(QSL("^")), QString::fromUtf8("")); const QStringList changed_settings_description = panels_for_restart.replaceInStrings(QRegExp(QSL("^")), QString::fromUtf8(""));
const QMessageBox::StandardButton clicked_button = MessageBox::show(this, const QMessageBox::StandardButton clicked_button = MessageBox::show(this,
QMessageBox::Question, QMessageBox::Question,
tr("Critical settings were changed"), tr("Critical settings were changed"),
@ -118,6 +111,7 @@ void FormSettings::cancelSettings() {
if (changed_panels.isEmpty()) { if (changed_panels.isEmpty()) {
reject(); reject();
} }
else { else {
const QStringList changed_settings_description = changed_panels.replaceInStrings(QRegExp(QSL("^")), QString::fromUtf8("")); const QStringList changed_settings_description = changed_panels.replaceInStrings(QRegExp(QSL("^")), QString::fromUtf8(""));
@ -139,7 +133,6 @@ void FormSettings::addSettingsPanel(SettingsPanel *panel) {
m_panels.append(panel); m_panels.append(panel);
m_ui->m_stackedSettings->addWidget(panel); m_ui->m_stackedSettings->addWidget(panel);
panel->loadSettings(); panel->loadSettings();
connect(panel, &SettingsPanel::settingsChanged, [this]() { connect(panel, &SettingsPanel::settingsChanged, [this]() {
m_btnApply->setEnabled(true); m_btnApply->setEnabled(true);
}); });

View File

@ -38,7 +38,6 @@ FormUpdate::FormUpdate(QWidget *parent)
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->m_lblCurrentRelease->setText(APP_VERSION); m_ui->m_lblCurrentRelease->setText(APP_VERSION);
m_ui->m_tabInfo->removeTab(1); m_ui->m_tabInfo->removeTab(1);
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint);
setWindowIcon(qApp->icons()->fromTheme(QSL("help-about"))); setWindowIcon(qApp->icons()->fromTheme(QSL("help-about")));
@ -47,6 +46,7 @@ FormUpdate::FormUpdate(QWidget *parent)
m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Download selected update"), QDialogButtonBox::ActionRole); m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Download selected update"), QDialogButtonBox::ActionRole);
m_btnUpdate->setToolTip(tr("Download new installation files.")); m_btnUpdate->setToolTip(tr("Download new installation files."));
} }
else { else {
m_btnUpdate = m_ui->m_buttonBox->addButton(tr("Go to application website"), QDialogButtonBox::ActionRole); 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->setToolTip(tr("Go to application website to get update packages manually."));
@ -74,7 +74,6 @@ void FormUpdate::checkForUpdates() {
if (update.second != QNetworkReply::NoError) { if (update.second != QNetworkReply::NoError) {
m_updateInfo = UpdateInfo(); m_updateInfo = UpdateInfo();
m_ui->m_tabInfo->setEnabled(false); m_ui->m_tabInfo->setEnabled(false);
//: Unknown release. //: Unknown release.
m_ui->m_lblAvailableRelease->setText(tr("unknown")); m_ui->m_lblAvailableRelease->setText(tr("unknown"));
m_ui->m_txtChanges->clear(); m_ui->m_txtChanges->clear();
@ -82,9 +81,9 @@ void FormUpdate::checkForUpdates() {
tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)), tr("Error: '%1'.").arg(NetworkFactory::networkErrorText(update.second)),
tr("List with updates was not\ndownloaded successfully.")); tr("List with updates was not\ndownloaded successfully."));
} }
else { else {
const bool self_update_supported = isSelfUpdateSupported(); const bool self_update_supported = isSelfUpdateSupported();
m_updateInfo = update.first.at(0); m_updateInfo = update.first.at(0);
m_ui->m_tabInfo->setEnabled(true); m_ui->m_tabInfo->setEnabled(true);
m_ui->m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion); m_ui->m_lblAvailableRelease->setText(m_updateInfo.m_availableVersion);
@ -100,6 +99,7 @@ void FormUpdate::checkForUpdates() {
loadAvailableFiles(); loadAvailableFiles();
} }
} }
else { else {
m_ui->m_lblStatus->setStatus(WidgetWithStatus::Warning, m_ui->m_lblStatus->setStatus(WidgetWithStatus::Warning,
tr("No new release available."), tr("No new release available."),
@ -119,7 +119,6 @@ void FormUpdate::updateProgress(qint64 bytes_received, qint64 bytes_total) {
2)), 2)),
tr("Downloading update...")); tr("Downloading update..."));
m_ui->m_lblStatus->repaint(); m_ui->m_lblStatus->repaint();
m_lastDownloadedBytes = bytes_received; m_lastDownloadedBytes = bytes_received;
} }
} }
@ -135,21 +134,20 @@ void FormUpdate::saveUpdateFile(const QByteArray &file_contents) {
if (output_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { if (output_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qDebug("Storing update file to temporary location '%s'.", qDebug("Storing update file to temporary location '%s'.",
qPrintable(QDir::toNativeSeparators(output_file.fileName()))); qPrintable(QDir::toNativeSeparators(output_file.fileName())));
output_file.write(file_contents); output_file.write(file_contents);
output_file.flush(); output_file.flush();
output_file.close(); output_file.close();
qDebug("Update file contents was successfuly saved."); qDebug("Update file contents was successfuly saved.");
m_updateFilePath = output_file.fileName(); m_updateFilePath = output_file.fileName();
m_readyToInstall = true; m_readyToInstall = true;
} }
else { else {
qDebug("Cannot save downloaded update file because target temporary file '%s' cannot be " qDebug("Cannot save downloaded update file because target temporary file '%s' cannot be "
"opened for writing.", qPrintable(output_file_name)); "opened for writing.", qPrintable(output_file_name));
} }
} }
else { else {
qDebug("Cannot save downloaded update file because no TEMP directory is available."); qDebug("Cannot save downloaded update file because no TEMP directory is available.");
} }
@ -168,6 +166,7 @@ void FormUpdate::loadAvailableFiles() {
if (m_ui->m_listFiles->count() > 0) { if (m_ui->m_listFiles->count() > 0) {
m_ui->m_listFiles->setCurrentRow(0); m_ui->m_listFiles->setCurrentRow(0);
} }
else { else {
m_btnUpdate->setEnabled(false); m_btnUpdate->setEnabled(false);
} }
@ -202,6 +201,7 @@ void FormUpdate::startUpdate() {
url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString(); url_file = m_ui->m_listFiles->currentItem()->data(Qt::UserRole).toString();
m_ui->m_listFiles->setEnabled(false); m_ui->m_listFiles->setEnabled(false);
} }
else { else {
url_file = APP_URL; url_file = APP_URL;
} }
@ -209,7 +209,6 @@ void FormUpdate::startUpdate() {
if (m_readyToInstall) { if (m_readyToInstall) {
close(); close();
qDebug("Preparing to launch external installer '%s'.", qPrintable(QDir::toNativeSeparators(m_updateFilePath))); qDebug("Preparing to launch external installer '%s'.", qPrintable(QDir::toNativeSeparators(m_updateFilePath)));
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
HINSTANCE exec_result = ShellExecute(nullptr, HINSTANCE exec_result = ShellExecute(nullptr,
nullptr, nullptr,
@ -220,24 +219,24 @@ void FormUpdate::startUpdate() {
if (((int)exec_result) <= 32) { if (((int)exec_result) <= 32) {
qDebug("External updater was not launched due to error."); qDebug("External updater was not launched due to error.");
qApp->showGuiMessage(tr("Cannot update application"), qApp->showGuiMessage(tr("Cannot update application"),
tr("Cannot launch external updater. Update application manually."), tr("Cannot launch external updater. Update application manually."),
QSystemTrayIcon::Warning, this); QSystemTrayIcon::Warning, this);
} }
else { else {
qApp->quit(); qApp->quit();
} }
#endif #endif
} }
else if (update_for_this_system) { else if (update_for_this_system) {
// Nothing is downloaded yet, but update for this system // Nothing is downloaded yet, but update for this system
// is available and self-update feature is present. // is available and self-update feature is present.
if (m_downloader == nullptr) { if (m_downloader == nullptr) {
// Initialie downloader. // Initialie downloader.
m_downloader = new Downloader(this); m_downloader = new Downloader(this);
connect(m_downloader, &Downloader::progress, this, &FormUpdate::updateProgress); connect(m_downloader, &Downloader::progress, this, &FormUpdate::updateProgress);
connect(m_downloader, &Downloader::completed, this, &FormUpdate::updateCompleted); connect(m_downloader, &Downloader::completed, this, &FormUpdate::updateCompleted);
updateProgress(0, 100); updateProgress(0, 100);
@ -247,6 +246,7 @@ void FormUpdate::startUpdate() {
m_btnUpdate->setEnabled(false); m_btnUpdate->setEnabled(false);
m_downloader->downloadFile(url_file); m_downloader->downloadFile(url_file);
} }
else { else {
// Self-update and package are not available. // Self-update and package are not available.
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) { if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {

View File

@ -67,6 +67,7 @@ void DiscoverFeedsButton::linkTriggered(QAction *action) {
if (root->supportsFeedAdding()) { if (root->supportsFeedAdding()) {
root->addNewFeed(url); root->addNewFeed(url);
} }
else { else {
qApp->showGuiMessage(tr("Not supported"), qApp->showGuiMessage(tr("Not supported"),
tr("Given account does not support adding feeds."), tr("Given account does not support adding feeds."),
@ -84,7 +85,6 @@ void DiscoverFeedsButton::fillMenu() {
foreach (const QString& url, m_addresses) { foreach (const QString& url, m_addresses) {
if (root->supportsFeedAdding()) { if (root->supportsFeedAdding()) {
QAction* url_action = root_menu->addAction(root->icon(), url); QAction* url_action = root_menu->addAction(root->icon(), url);
url_action->setProperty("url", url); url_action->setProperty("url", url);
url_action->setProperty("root", QVariant::fromValue((void*) root)); url_action->setProperty("root", QVariant::fromValue((void*) root));
} }

View File

@ -28,6 +28,7 @@ void EditTableView::keyPressEvent(QKeyEvent *event) {
removeSelected(); removeSelected();
event->accept(); event->accept();
} }
else { else {
QAbstractItemView::keyPressEvent(event); QAbstractItemView::keyPressEvent(event);
} }

View File

@ -110,15 +110,11 @@ FeedsToolBar *FeedMessageViewer::feedsToolBar() const {
void FeedMessageViewer::saveSize() { void FeedMessageViewer::saveSize() {
Settings* settings = qApp->settings(); Settings* settings = qApp->settings();
m_feedsView->saveAllExpandStates(); m_feedsView->saveAllExpandStates();
// Store offsets of splitters. // Store offsets of splitters.
settings->setValue(GROUP(GUI), GUI::SplitterFeeds, QString(m_feedSplitter->saveState().toBase64())); 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::SplitterMessages, QString(m_messageSplitter->saveState().toBase64()));
settings->setValue(GROUP(GUI), GUI::MessageViewState, QString(m_messagesView->header()->saveState().toBase64())); settings->setValue(GROUP(GUI), GUI::MessageViewState, QString(m_messagesView->header()->saveState().toBase64()));
// Store "visibility" of toolbars and list headers. // Store "visibility" of toolbars and list headers.
settings->setValue(GROUP(GUI), GUI::ToolbarsVisible, m_toolBarsEnabled); settings->setValue(GROUP(GUI), GUI::ToolbarsVisible, m_toolBarsEnabled);
settings->setValue(GROUP(GUI), GUI::ListHeadersVisible, m_listHeadersEnabled); settings->setValue(GROUP(GUI), GUI::ListHeadersVisible, m_listHeadersEnabled);
@ -126,11 +122,9 @@ void FeedMessageViewer::saveSize() {
void FeedMessageViewer::loadSize() { void FeedMessageViewer::loadSize() {
const Settings* settings = qApp->settings(); const Settings* settings = qApp->settings();
// Restore offsets of splitters. // Restore offsets of splitters.
m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::SplitterFeeds)).toString().toLocal8Bit())); 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_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())); m_messagesView->header()->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::MessageViewState)).toString().toLocal8Bit()));
} }
@ -150,6 +144,7 @@ void FeedMessageViewer::switchMessageSplitterOrientation() {
if (m_messageSplitter->orientation() == Qt::Vertical) { if (m_messageSplitter->orientation() == Qt::Vertical) {
m_messageSplitter->setOrientation(Qt::Horizontal); m_messageSplitter->setOrientation(Qt::Horizontal);
} }
else { else {
m_messageSplitter->setOrientation(Qt::Vertical); m_messageSplitter->setOrientation(Qt::Vertical);
} }
@ -173,6 +168,7 @@ void FeedMessageViewer::switchFeedComponentVisibility() {
if (sen != nullptr) { if (sen != nullptr) {
m_feedsWidget->setVisible(sen->isChecked()); m_feedsWidget->setVisible(sen->isChecked());
} }
else { else {
m_feedsWidget->setVisible(!m_feedsWidget->isVisible()); m_feedsWidget->setVisible(!m_feedsWidget->isVisible());
} }
@ -184,6 +180,7 @@ void FeedMessageViewer::toggleShowOnlyUnreadFeeds() {
if (origin == nullptr) { if (origin == nullptr) {
m_feedsView->model()->invalidateReadFeedsFilter(true, false); m_feedsView->model()->invalidateReadFeedsFilter(true, false);
} }
else { else {
m_feedsView->model()->invalidateReadFeedsFilter(true, origin->isChecked()); m_feedsView->model()->invalidateReadFeedsFilter(true, origin->isChecked());
} }
@ -193,7 +190,6 @@ void FeedMessageViewer::createConnections() {
// Filtering & searching. // Filtering & searching.
connect(m_toolBarMessages, &MessagesToolBar::messageSearchPatternChanged, m_messagesView, &MessagesView::searchMessages); connect(m_toolBarMessages, &MessagesToolBar::messageSearchPatternChanged, m_messagesView, &MessagesView::searchMessages);
connect(m_toolBarMessages, &MessagesToolBar::messageFilterChanged, m_messagesView, &MessagesView::filterMessages); connect(m_toolBarMessages, &MessagesToolBar::messageFilterChanged, m_messagesView, &MessagesView::filterMessages);
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
connect(m_messagesView, &MessagesView::currentMessageRemoved, m_messagesBrowser, &WebBrowser::clear); connect(m_messagesView, &MessagesView::currentMessageRemoved, m_messagesBrowser, &WebBrowser::clear);
connect(m_messagesView, &MessagesView::currentMessageChanged, m_messagesBrowser, &WebBrowser::loadMessage); connect(m_messagesView, &MessagesView::currentMessageChanged, m_messagesBrowser, &WebBrowser::loadMessage);
@ -209,10 +205,8 @@ void FeedMessageViewer::createConnections() {
connect(m_messagesBrowser, &MessagePreviewer::markMessageImportant, connect(m_messagesBrowser, &MessagePreviewer::markMessageImportant,
m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById); m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById);
#endif #endif
// If user selects feeds, load their messages. // If user selects feeds, load their messages.
connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem); connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem);
// State of many messages is changed, then we need // State of many messages is changed, then we need
// to reload selections. // to reload selections.
connect(m_feedsView->sourceModel(), &FeedsModel::reloadMessageListRequested, connect(m_feedsView->sourceModel(), &FeedsModel::reloadMessageListRequested,
@ -224,16 +218,12 @@ void FeedMessageViewer::initialize() {
m_toolBarFeeds->setFloatable(false); m_toolBarFeeds->setFloatable(false);
m_toolBarFeeds->setMovable(false); m_toolBarFeeds->setMovable(false);
m_toolBarFeeds->setAllowedAreas(Qt::TopToolBarArea); m_toolBarFeeds->setAllowedAreas(Qt::TopToolBarArea);
m_toolBarMessages->setFloatable(false); m_toolBarMessages->setFloatable(false);
m_toolBarMessages->setMovable(false); m_toolBarMessages->setMovable(false);
m_toolBarMessages->setAllowedAreas(Qt::TopToolBarArea); m_toolBarMessages->setAllowedAreas(Qt::TopToolBarArea);
m_toolBarFeeds->loadSavedActions(); m_toolBarFeeds->loadSavedActions();
m_toolBarMessages->loadSavedActions(); m_toolBarMessages->loadSavedActions();
m_messagesBrowser->clear(); m_messagesBrowser->clear();
// Now refresh visual setup. // Now refresh visual setup.
refreshVisualProperties(); refreshVisualProperties();
} }
@ -243,12 +233,10 @@ void FeedMessageViewer::initializeViews() {
m_messagesWidget = new QWidget(this); m_messagesWidget = new QWidget(this);
m_feedSplitter = new QSplitter(Qt::Horizontal, this); m_feedSplitter = new QSplitter(Qt::Horizontal, this);
m_messageSplitter = new QSplitter(Qt::Vertical, this); m_messageSplitter = new QSplitter(Qt::Vertical, this);
// Instantiate needed components. // Instantiate needed components.
QVBoxLayout* central_layout = new QVBoxLayout(this); QVBoxLayout* central_layout = new QVBoxLayout(this);
QVBoxLayout* feed_layout = new QVBoxLayout(m_feedsWidget); QVBoxLayout* feed_layout = new QVBoxLayout(m_feedsWidget);
QVBoxLayout* message_layout = new QVBoxLayout(m_messagesWidget); QVBoxLayout* message_layout = new QVBoxLayout(m_messagesWidget);
// Set layout properties. // Set layout properties.
central_layout->setMargin(0); central_layout->setMargin(0);
central_layout->setSpacing(0); central_layout->setSpacing(0);
@ -256,11 +244,9 @@ void FeedMessageViewer::initializeViews() {
feed_layout->setSpacing(0); feed_layout->setSpacing(0);
message_layout->setMargin(0); message_layout->setMargin(0);
message_layout->setSpacing(0); message_layout->setSpacing(0);
// Set views. // Set views.
m_feedsView->setFrameStyle(QFrame::NoFrame); m_feedsView->setFrameStyle(QFrame::NoFrame);
m_messagesView->setFrameStyle(QFrame::NoFrame); m_messagesView->setFrameStyle(QFrame::NoFrame);
// Setup message splitter. // Setup message splitter.
m_messageSplitter->setObjectName(QSL("MessageSplitter")); m_messageSplitter->setObjectName(QSL("MessageSplitter"));
m_messageSplitter->setHandleWidth(1); m_messageSplitter->setHandleWidth(1);
@ -268,25 +254,20 @@ void FeedMessageViewer::initializeViews() {
m_messageSplitter->setChildrenCollapsible(false); m_messageSplitter->setChildrenCollapsible(false);
m_messageSplitter->addWidget(m_messagesView); m_messageSplitter->addWidget(m_messagesView);
m_messageSplitter->addWidget(m_messagesBrowser); m_messageSplitter->addWidget(m_messagesBrowser);
// Assemble message-related components to single widget. // Assemble message-related components to single widget.
message_layout->addWidget(m_toolBarMessages); message_layout->addWidget(m_toolBarMessages);
message_layout->addWidget(m_messageSplitter); message_layout->addWidget(m_messageSplitter);
// Assemble feed-related components to another widget. // Assemble feed-related components to another widget.
feed_layout->addWidget(m_toolBarFeeds); feed_layout->addWidget(m_toolBarFeeds);
feed_layout->addWidget(m_feedsView); feed_layout->addWidget(m_feedsView);
// Assembler everything together. // Assembler everything together.
m_feedSplitter->setHandleWidth(1); m_feedSplitter->setHandleWidth(1);
m_feedSplitter->setOpaqueResize(false); m_feedSplitter->setOpaqueResize(false);
m_feedSplitter->setChildrenCollapsible(false); m_feedSplitter->setChildrenCollapsible(false);
m_feedSplitter->addWidget(m_feedsWidget); m_feedSplitter->addWidget(m_feedsWidget);
m_feedSplitter->addWidget(m_messagesWidget); m_feedSplitter->addWidget(m_messagesWidget);
// Add toolbar and main feeds/messages widget to main layout. // Add toolbar and main feeds/messages widget to main layout.
central_layout->addWidget(m_feedSplitter); central_layout->addWidget(m_feedSplitter);
setTabOrder(m_feedsView, m_messagesView); setTabOrder(m_feedsView, m_messagesView);
setTabOrder(m_messagesView, m_toolBarFeeds); setTabOrder(m_messagesView, m_toolBarFeeds);
setTabOrder(m_toolBarFeeds, m_toolBarMessages); setTabOrder(m_toolBarFeeds, m_toolBarMessages);
@ -296,7 +277,6 @@ void FeedMessageViewer::initializeViews() {
void FeedMessageViewer::refreshVisualProperties() { void FeedMessageViewer::refreshVisualProperties() {
const Qt::ToolButtonStyle button_style = static_cast<Qt::ToolButtonStyle>(qApp->settings()->value(GROUP(GUI), const Qt::ToolButtonStyle button_style = static_cast<Qt::ToolButtonStyle>(qApp->settings()->value(GROUP(GUI),
SETTING(GUI::ToolbarStyle)).toInt()); SETTING(GUI::ToolbarStyle)).toInt());
m_toolBarFeeds->setToolButtonStyle(button_style); m_toolBarFeeds->setToolButtonStyle(button_style);
m_toolBarMessages->setToolButtonStyle(button_style); m_toolBarMessages->setToolButtonStyle(button_style);
} }

View File

@ -59,25 +59,23 @@ QList<QAction*> FeedsToolBar::getSpecificActions(const QStringList &actions) {
// Add existing standard action. // Add existing standard action.
spec_actions.append(matching_action); spec_actions.append(matching_action);
} }
else if (action_name == SEPARATOR_ACTION_NAME) { else if (action_name == SEPARATOR_ACTION_NAME) {
// Add new separator. // Add new separator.
QAction* act = new QAction(this); QAction* act = new QAction(this);
act->setSeparator(true); act->setSeparator(true);
spec_actions.append(act); spec_actions.append(act);
} }
else if (action_name == SPACER_ACTION_NAME) { else if (action_name == SPACER_ACTION_NAME) {
// Add new spacer. // Add new spacer.
QWidget* spacer = new QWidget(this); QWidget* spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QWidgetAction* action = new QWidgetAction(this); QWidgetAction* action = new QWidgetAction(this);
action->setDefaultWidget(spacer); action->setDefaultWidget(spacer);
action->setIcon(qApp->icons()->fromTheme(QSL("system-search"))); action->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
action->setProperty("type", SPACER_ACTION_NAME); action->setProperty("type", SPACER_ACTION_NAME);
action->setProperty("name", tr("Toolbar spacer")); action->setProperty("name", tr("Toolbar spacer"));
spec_actions.append(action); spec_actions.append(action);
} }
} }
@ -101,5 +99,4 @@ QStringList FeedsToolBar::defaultActions() const {
QStringList FeedsToolBar::savedActions() const { QStringList FeedsToolBar::savedActions() const {
return qApp->settings()->value(GROUP(GUI), SETTING(GUI::FeedsToolbarActions)).toString().split(',', return qApp->settings()->value(GROUP(GUI), SETTING(GUI::FeedsToolbarActions)).toString().split(',',
QString::SkipEmptyParts); QString::SkipEmptyParts);
} }

View File

@ -49,18 +49,15 @@ FeedsView::FeedsView(QWidget *parent)
m_contextMenuEmptySpace(nullptr), m_contextMenuEmptySpace(nullptr),
m_contextMenuOtherItems(nullptr) { m_contextMenuOtherItems(nullptr) {
setObjectName(QSL("FeedsView")); setObjectName(QSL("FeedsView"));
// Allocate models. // Allocate models.
m_sourceModel = qApp->feedReader()->feedsModel(); m_sourceModel = qApp->feedReader()->feedsModel();
m_proxyModel = qApp->feedReader()->feedsProxyModel(); m_proxyModel = qApp->feedReader()->feedsProxyModel();
// Connections. // Connections.
connect(m_sourceModel, &FeedsModel::requireItemValidationAfterDragDrop, this, &FeedsView::validateItemAfterDragDrop); connect(m_sourceModel, &FeedsModel::requireItemValidationAfterDragDrop, this, &FeedsView::validateItemAfterDragDrop);
connect(m_sourceModel, &FeedsModel::itemExpandRequested, this, &FeedsView::onItemExpandRequested); connect(m_sourceModel, &FeedsModel::itemExpandRequested, this, &FeedsView::onItemExpandRequested);
connect(m_sourceModel, &FeedsModel::itemExpandStateSaveRequested, this, &FeedsView::onItemExpandStateSaveRequested); connect(m_sourceModel, &FeedsModel::itemExpandStateSaveRequested, this, &FeedsView::onItemExpandStateSaveRequested);
connect(header(), &QHeaderView::sortIndicatorChanged, this, &FeedsView::saveSortState); connect(header(), &QHeaderView::sortIndicatorChanged, this, &FeedsView::saveSortState);
connect(m_proxyModel, &FeedsProxyModel::expandAfterFilterIn, this, &FeedsView::expandItemDelayed); connect(m_proxyModel, &FeedsProxyModel::expandAfterFilterIn, this, &FeedsView::expandItemDelayed);
setModel(m_proxyModel); setModel(m_proxyModel);
setupAppearance(); setupAppearance();
} }
@ -81,6 +78,7 @@ QList<Feed*> FeedsView::selectedFeeds() const {
if (current_index.isValid()) { if (current_index.isValid()) {
return m_sourceModel->feedsForIndex(m_proxyModel->mapToSource(current_index)); return m_sourceModel->feedsForIndex(m_proxyModel->mapToSource(current_index));
} }
else { else {
return QList<Feed*>(); return QList<Feed*>();
} }
@ -92,6 +90,7 @@ RootItem *FeedsView::selectedItem() const {
if (selected_rows.isEmpty()) { if (selected_rows.isEmpty()) {
return nullptr; return nullptr;
} }
else { else {
RootItem* selected_item = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(selected_rows.at(0))); RootItem* selected_item = m_sourceModel->itemForIndex(m_proxyModel->mapToSource(selected_rows.at(0)));
return selected_item == m_sourceModel->rootItem() ? nullptr : selected_item; return selected_item == m_sourceModel->rootItem() ? nullptr : selected_item;
@ -113,10 +112,8 @@ void FeedsView::saveExpandStates(RootItem *item) {
// Iterate all categories and save their expand statuses. // Iterate all categories and save their expand statuses.
foreach (const RootItem* item, items) { foreach (const RootItem* item, items) {
const QString setting_name = item->hashCode(); const QString setting_name = item->hashCode();
QModelIndex source_index = sourceModel()->indexForItem(item); QModelIndex source_index = sourceModel()->indexForItem(item);
QModelIndex visible_index = model()->mapFromSource(source_index); QModelIndex visible_index = model()->mapFromSource(source_index);
settings->setValue(GROUP(CategoriesExpandStates), settings->setValue(GROUP(CategoriesExpandStates),
setting_name, setting_name,
isExpanded(visible_index)); isExpanded(visible_index));
@ -126,13 +123,11 @@ void FeedsView::saveExpandStates(RootItem *item) {
void FeedsView::loadAllExpandStates() { void FeedsView::loadAllExpandStates() {
const Settings* settings = qApp->settings(); const Settings* settings = qApp->settings();
QList<RootItem*> expandable_items; QList<RootItem*> expandable_items;
expandable_items.append(sourceModel()->rootItem()->getSubTree(RootItemKind::Category | RootItemKind::ServiceRoot)); expandable_items.append(sourceModel()->rootItem()->getSubTree(RootItemKind::Category | RootItemKind::ServiceRoot));
// Iterate all categories and save their expand statuses. // Iterate all categories and save their expand statuses.
foreach (const RootItem* item, expandable_items) { foreach (const RootItem* item, expandable_items) {
const QString setting_name = item->hashCode(); const QString setting_name = item->hashCode();
setExpanded(model()->mapFromSource(sourceModel()->indexForItem(item)), setExpanded(model()->mapFromSource(sourceModel()->indexForItem(item)),
settings->value(GROUP(CategoriesExpandStates), setting_name, item->childCount() > 0).toBool()); settings->value(GROUP(CategoriesExpandStates), setting_name, item->childCount() > 0).toBool());
} }
@ -148,6 +143,7 @@ void FeedsView::sortByColumn(int column, Qt::SortOrder order) {
if (column == old_column && order == old_order) { if (column == old_column && order == old_order) {
m_proxyModel->sort(column, order); m_proxyModel->sort(column, order);
} }
else { else {
QTreeView::sortByColumn(column, order); QTreeView::sortByColumn(column, order);
} }
@ -162,6 +158,7 @@ void FeedsView::addFeedIntoSelectedAccount() {
if (root->supportsFeedAdding()) { if (root->supportsFeedAdding()) {
root->addNewFeed(); root->addNewFeed();
} }
else { else {
qApp->showGuiMessage(tr("Not supported"), qApp->showGuiMessage(tr("Not supported"),
tr("Selected account does not support adding of new feeds."), tr("Selected account does not support adding of new feeds."),
@ -180,6 +177,7 @@ void FeedsView::addCategoryIntoSelectedAccount() {
if (root->supportsCategoryAdding()) { if (root->supportsCategoryAdding()) {
root->addNewCategory(); root->addNewCategory();
} }
else { else {
qApp->showGuiMessage(tr("Not supported"), qApp->showGuiMessage(tr("Not supported"),
tr("Selected account does not support adding of new categories."), tr("Selected account does not support adding of new categories."),
@ -229,6 +227,7 @@ void FeedsView::editSelectedItem() {
if (selectedItem()->canBeEdited()) { if (selectedItem()->canBeEdited()) {
selectedItem()->editViaGui(); selectedItem()->editViaGui();
} }
else { else {
qApp->showGuiMessage(tr("Cannot edit item"), qApp->showGuiMessage(tr("Cannot edit item"),
tr("Selected item cannot be edited, this is not (yet?) supported."), tr("Selected item cannot be edited, this is not (yet?) supported."),
@ -249,7 +248,6 @@ void FeedsView::deleteSelectedItem() {
qApp->showGuiMessage(tr("Cannot delete item"), qApp->showGuiMessage(tr("Cannot delete item"),
tr("Selected item cannot be deleted because another critical operation is ongoing."), tr("Selected item cannot be deleted because another critical operation is ongoing."),
QSystemTrayIcon::Warning, qApp->mainFormWidget(), true); QSystemTrayIcon::Warning, qApp->mainFormWidget(), true);
// Thus, cannot delete and quit the method. // Thus, cannot delete and quit the method.
return; return;
} }
@ -285,6 +283,7 @@ void FeedsView::deleteSelectedItem() {
true); true);
} }
} }
else { else {
qApp->showGuiMessage(tr("Cannot delete \"%1\"").arg(selected_item->title()), qApp->showGuiMessage(tr("Cannot delete \"%1\"").arg(selected_item->title()),
tr("This item cannot be deleted, because it does not support it\nor this functionality is not implemented yet."), tr("This item cannot be deleted, because it does not support it\nor this functionality is not implemented yet."),
@ -372,12 +371,12 @@ QMenu *FeedsView::initializeContextMenuCategories(RootItem *clicked_item) {
if (m_contextMenuCategories == nullptr) { if (m_contextMenuCategories == nullptr) {
m_contextMenuCategories = new QMenu(tr("Context menu for categories"), this); m_contextMenuCategories = new QMenu(tr("Context menu for categories"), this);
} }
else { else {
m_contextMenuCategories->clear(); m_contextMenuCategories->clear();
} }
QList<QAction*> specific_actions = clicked_item->contextMenu(); QList<QAction*> specific_actions = clicked_item->contextMenu();
m_contextMenuCategories->addActions(QList<QAction*>() << m_contextMenuCategories->addActions(QList<QAction*>() <<
qApp->mainForm()->m_ui->m_actionUpdateSelectedItems << qApp->mainForm()->m_ui->m_actionUpdateSelectedItems <<
qApp->mainForm()->m_ui->m_actionEditSelectedItem << qApp->mainForm()->m_ui->m_actionEditSelectedItem <<
@ -398,12 +397,12 @@ QMenu *FeedsView::initializeContextMenuFeeds(RootItem *clicked_item) {
if (m_contextMenuFeeds == nullptr) { if (m_contextMenuFeeds == nullptr) {
m_contextMenuFeeds = new QMenu(tr("Context menu for categories"), this); m_contextMenuFeeds = new QMenu(tr("Context menu for categories"), this);
} }
else { else {
m_contextMenuFeeds->clear(); m_contextMenuFeeds->clear();
} }
QList<QAction*> specific_actions = clicked_item->contextMenu(); QList<QAction*> specific_actions = clicked_item->contextMenu();
m_contextMenuFeeds->addActions(QList<QAction*>() << m_contextMenuFeeds->addActions(QList<QAction*>() <<
qApp->mainForm()->m_ui->m_actionUpdateSelectedItems << qApp->mainForm()->m_ui->m_actionUpdateSelectedItems <<
qApp->mainForm()->m_ui->m_actionEditSelectedItem << qApp->mainForm()->m_ui->m_actionEditSelectedItem <<
@ -434,6 +433,7 @@ QMenu *FeedsView::initializeContextMenuOtherItem(RootItem *clicked_item) {
if (m_contextMenuOtherItems == nullptr) { if (m_contextMenuOtherItems == nullptr) {
m_contextMenuOtherItems = new QMenu(tr("Context menu for other items"), this); m_contextMenuOtherItems = new QMenu(tr("Context menu for other items"), this);
} }
else { else {
m_contextMenuOtherItems->clear(); m_contextMenuOtherItems->clear();
} }
@ -444,6 +444,7 @@ QMenu *FeedsView::initializeContextMenuOtherItem(RootItem *clicked_item) {
m_contextMenuOtherItems->addSeparator(); m_contextMenuOtherItems->addSeparator();
m_contextMenuOtherItems->addActions(specific_actions); m_contextMenuOtherItems->addActions(specific_actions);
} }
else { else {
m_contextMenuOtherItems->addAction(qApp->mainForm()->m_ui->m_actionNoActions); m_contextMenuOtherItems->addAction(qApp->mainForm()->m_ui->m_actionNoActions);
} }
@ -455,7 +456,6 @@ void FeedsView::setupAppearance() {
// Setup column resize strategies. // Setup column resize strategies.
header()->setSectionResizeMode(FDS_MODEL_TITLE_INDEX, QHeaderView::Stretch); header()->setSectionResizeMode(FDS_MODEL_TITLE_INDEX, QHeaderView::Stretch);
header()->setSectionResizeMode(FDS_MODEL_COUNTS_INDEX, QHeaderView::ResizeToContents); header()->setSectionResizeMode(FDS_MODEL_COUNTS_INDEX, QHeaderView::ResizeToContents);
setUniformRowHeights(true); setUniformRowHeights(true);
setAnimated(true); setAnimated(true);
setSortingEnabled(true); setSortingEnabled(true);
@ -477,7 +477,6 @@ void FeedsView::setupAppearance() {
void FeedsView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { void FeedsView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) {
RootItem* selected_item = selectedItem(); RootItem* selected_item = selectedItem();
m_proxyModel->setSelectedItem(selected_item); m_proxyModel->setSelectedItem(selected_item);
QTreeView::selectionChanged(selected, deselected); QTreeView::selectionChanged(selected, deselected);
emit itemSelected(selected_item); emit itemSelected(selected_item);
@ -503,14 +502,17 @@ void FeedsView::contextMenuEvent(QContextMenuEvent *event) {
// Display context menu for categories. // Display context menu for categories.
initializeContextMenuCategories(clicked_item)->exec(event->globalPos()); initializeContextMenuCategories(clicked_item)->exec(event->globalPos());
} }
else if (clicked_item->kind() == RootItemKind::Feed) { else if (clicked_item->kind() == RootItemKind::Feed) {
// Display context menu for feeds. // Display context menu for feeds.
initializeContextMenuFeeds(clicked_item)->exec(event->globalPos()); initializeContextMenuFeeds(clicked_item)->exec(event->globalPos());
} }
else { else {
initializeContextMenuOtherItem(clicked_item)->exec(event->globalPos()); initializeContextMenuOtherItem(clicked_item)->exec(event->globalPos());
} }
} }
else { else {
// Display menu for empty space. // Display menu for empty space.
initializeContextMenuEmptySpace()->exec(event->globalPos()); initializeContextMenuEmptySpace()->exec(event->globalPos());
@ -553,7 +555,6 @@ void FeedsView::onItemExpandRequested(const QList<RootItem*> &items, bool exp) {
foreach (const RootItem* item, items) { foreach (const RootItem* item, items) {
QModelIndex source_index = m_sourceModel->indexForItem(item); QModelIndex source_index = m_sourceModel->indexForItem(item);
QModelIndex proxy_index = m_proxyModel->mapFromSource(source_index); QModelIndex proxy_index = m_proxyModel->mapFromSource(source_index);
//setExpanded(proxy_index, !exp); //setExpanded(proxy_index, !exp);
setExpanded(proxy_index, exp); setExpanded(proxy_index, exp);
} }

View File

@ -28,6 +28,7 @@ void GuiUtilities::setLabelAsNotice(QLabel *label, bool is_warning) {
if (is_warning) { if (is_warning) {
label->setStyleSheet(QSL("font-weight: bold; font-style: italic; color: red")); label->setStyleSheet(QSL("font-weight: bold; font-style: italic; color: red"));
} }
else { else {
label->setStyleSheet(QSL("font-style: italic;")); label->setStyleSheet(QSL("font-style: italic;"));
} }

View File

@ -25,11 +25,9 @@
LabelWithStatus::LabelWithStatus(QWidget* parent) LabelWithStatus::LabelWithStatus(QWidget* parent)
: WidgetWithStatus(parent) { : WidgetWithStatus(parent) {
m_wdgInput = new QLabel(this); m_wdgInput = new QLabel(this);
// Set correct size for the tool button. // Set correct size for the tool button.
int label_height = m_wdgInput->sizeHint().height(); int label_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(label_height, label_height); m_btnStatus->setFixedSize(label_height, label_height);
// Compose the layout. // Compose the layout.
m_layout->addWidget(m_wdgInput); m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus); m_layout->addWidget(m_btnStatus);

View File

@ -26,13 +26,10 @@
LineEditWithStatus::LineEditWithStatus(QWidget* parent) LineEditWithStatus::LineEditWithStatus(QWidget* parent)
: WidgetWithStatus(parent) { : WidgetWithStatus(parent) {
m_wdgInput = new BaseLineEdit(this); m_wdgInput = new BaseLineEdit(this);
setFocusProxy(m_wdgInput); setFocusProxy(m_wdgInput);
// Set correct size for the tool button. // Set correct size for the tool button.
const int txt_input_height = m_wdgInput->sizeHint().height(); const int txt_input_height = m_wdgInput->sizeHint().height();
m_btnStatus->setFixedSize(txt_input_height, txt_input_height); m_btnStatus->setFixedSize(txt_input_height, txt_input_height);
// Compose the layout. // Compose the layout.
m_layout->addWidget(m_wdgInput); m_layout->addWidget(m_wdgInput);
m_layout->addWidget(m_btnStatus); m_layout->addWidget(m_btnStatus);

View File

@ -33,7 +33,6 @@ LocationLineEdit::~LocationLineEdit() {
void LocationLineEdit::focusOutEvent(QFocusEvent* event) { void LocationLineEdit::focusOutEvent(QFocusEvent* event) {
BaseLineEdit::focusOutEvent(event); BaseLineEdit::focusOutEvent(event);
// User now left text box, when he enters it again and clicks, // User now left text box, when he enters it again and clicks,
// then all text should be selected. // then all text should be selected.
m_mouseSelectsAllText = true; m_mouseSelectsAllText = true;
@ -43,10 +42,10 @@ void LocationLineEdit::mousePressEvent(QMouseEvent *event) {
if (m_mouseSelectsAllText) { if (m_mouseSelectsAllText) {
event->ignore(); event->ignore();
selectAll(); selectAll();
// User clicked and all text was selected. // User clicked and all text was selected.
m_mouseSelectsAllText = false; m_mouseSelectsAllText = false;
} }
else { else {
BaseLineEdit::mousePressEvent(event); BaseLineEdit::mousePressEvent(event);
} }

View File

@ -37,7 +37,6 @@ MessageBox::~MessageBox() {
void MessageBox::setIcon(QMessageBox::Icon icon) { void MessageBox::setIcon(QMessageBox::Icon icon) {
// Determine correct status icon size. // Determine correct status icon size.
const int icon_size = qApp->style()->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this); const int icon_size = qApp->style()->pixelMetric(QStyle::PM_MessageBoxIconSize, 0, this);
// Setup status icon. // Setup status icon.
setIconPixmap(iconForStatus(icon).pixmap(icon_size, icon_size)); setIconPixmap(iconForStatus(icon).pixmap(icon_size, icon_size));
} }
@ -45,13 +44,11 @@ void MessageBox::setIcon(QMessageBox::Icon icon) {
void MessageBox::setCheckBox(QMessageBox* msg_box, const QString& text, bool* data) { void MessageBox::setCheckBox(QMessageBox* msg_box, const QString& text, bool* data) {
// Add "don't show this again checkbox. // Add "don't show this again checkbox.
QCheckBox* check_box = new QCheckBox(msg_box); QCheckBox* check_box = new QCheckBox(msg_box);
check_box->setChecked(*data); check_box->setChecked(*data);
check_box->setText(text); check_box->setText(text);
connect(check_box, &QCheckBox::toggled, [ = ](bool checked) { connect(check_box, &QCheckBox::toggled, [ = ](bool checked) {
*data = checked; *data = checked;
}); });
msg_box->setCheckBox(check_box); msg_box->setCheckBox(check_box);
} }
@ -86,7 +83,6 @@ QMessageBox::StandardButton MessageBox::show(QWidget *parent,
bool* dont_show_again) { bool* dont_show_again) {
// Create and find needed components. // Create and find needed components.
MessageBox msg_box(parent); MessageBox msg_box(parent);
// Initialize message box properties. // Initialize message box properties.
msg_box.setWindowTitle(title); msg_box.setWindowTitle(title);
msg_box.setText(text); msg_box.setText(text);
@ -104,6 +100,7 @@ QMessageBox::StandardButton MessageBox::show(QWidget *parent,
if (msg_box.exec() == -1) { if (msg_box.exec() == -1) {
return QMessageBox::Cancel; return QMessageBox::Cancel;
} }
else { else {
return msg_box.standardButton(msg_box.clickedButton()); return msg_box.standardButton(msg_box.clickedButton());
} }

View File

@ -38,20 +38,18 @@ void MessagePreviewer::createConnections() {
if (open_externally_now) { if (open_externally_now) {
WebFactory::instance()->openUrlInExternalBrowser(url.toString()); WebFactory::instance()->openUrlInExternalBrowser(url.toString());
} }
else { else {
// User clicked some URL. Open it in external browser or download? // User clicked some URL. Open it in external browser or download?
MessageBox box(qApp->mainForm()); 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.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.setInformativeText(tr("What action do you want to take?"));
box.setDetailedText(url.toString()); box.setDetailedText(url.toString());
QAbstractButton* btn_open = box.addButton(tr("Open in external browser"), QMessageBox::ActionRole); QAbstractButton* btn_open = box.addButton(tr("Open in external browser"), QMessageBox::ActionRole);
QAbstractButton* btn_download = box.addButton(tr("Download"), QMessageBox::ActionRole); QAbstractButton* btn_download = box.addButton(tr("Download"), QMessageBox::ActionRole);
QAbstractButton* btn_cancel = box.addButton(QMessageBox::Cancel); QAbstractButton* btn_cancel = box.addButton(QMessageBox::Cancel);
bool always; bool always;
MessageBox::setCheckBox(&box, tr("Always open links in external browser."), &always); MessageBox::setCheckBox(&box, tr("Always open links in external browser."), &always);
box.setDefaultButton(QMessageBox::Cancel); box.setDefaultButton(QMessageBox::Cancel);
box.exec(); box.exec();
@ -63,6 +61,7 @@ void MessagePreviewer::createConnections() {
if (box.clickedButton() == btn_open) { if (box.clickedButton() == btn_open) {
WebFactory::instance()->openUrlInExternalBrowser(url.toString()); WebFactory::instance()->openUrlInExternalBrowser(url.toString());
} }
else if (box.clickedButton() == btn_download) { else if (box.clickedButton() == btn_download) {
qApp->downloadManager()->download(url); qApp->downloadManager()->download(url);
} }
@ -72,6 +71,7 @@ void MessagePreviewer::createConnections() {
btn_cancel->deleteLater(); btn_cancel->deleteLater();
} }
} }
else { else {
MessageBox::show(qApp->mainForm(), QMessageBox::Warning, tr("Incorrect link"), MessageBox::show(qApp->mainForm(), QMessageBox::Warning, tr("Incorrect link"),
tr("Selected hyperlink is invalid.")); tr("Selected hyperlink is invalid."));
@ -93,7 +93,6 @@ void MessagePreviewer::createConnections() {
static_cast<void (QTextBrowser::*)(const QString&)>(&QTextBrowser::highlighted), static_cast<void (QTextBrowser::*)(const QString&)>(&QTextBrowser::highlighted),
[ = ](const QString & text) { [ = ](const QString & text) {
Q_UNUSED(text) Q_UNUSED(text)
QToolTip::showText(QCursor::pos(), tr("Click this link to download it or open it with external browser."), this); QToolTip::showText(QCursor::pos(), tr("Click this link to download it or open it with external browser."), this);
}); });
} }
@ -105,11 +104,8 @@ MessagePreviewer::MessagePreviewer(QWidget *parent) : QWidget(parent),
m_toolBar = new QToolBar(this); m_toolBar = new QToolBar(this);
m_toolBar->setOrientation(Qt::Vertical); m_toolBar->setOrientation(Qt::Vertical);
m_ui->m_layout->addWidget(m_toolBar, 0, 0, -1, 1); m_ui->m_layout->addWidget(m_toolBar, 0, 0, -1, 1);
createConnections(); createConnections();
m_actionSwitchImportance->setCheckable(true); m_actionSwitchImportance->setCheckable(true);
reloadFontSettings(); reloadFontSettings();
clear(); clear();
} }
@ -120,10 +116,8 @@ MessagePreviewer::~MessagePreviewer() {
void MessagePreviewer::reloadFontSettings() { void MessagePreviewer::reloadFontSettings() {
const Settings* settings = qApp->settings(); const Settings* settings = qApp->settings();
QFont fon; QFont fon;
fon.fromString(settings->value(GROUP(Messages), fon.fromString(settings->value(GROUP(Messages),
SETTING(Messages::PreviewerFontStandard)).toString()); SETTING(Messages::PreviewerFontStandard)).toString());
m_ui->m_txtMessage->setFont(fon); m_ui->m_txtMessage->setFont(fon);
} }
@ -144,10 +138,8 @@ void MessagePreviewer::loadMessage(const Message &message, RootItem *root) {
if (!m_root.isNull()) { if (!m_root.isNull()) {
m_actionSwitchImportance->setChecked(m_message.m_isImportant); m_actionSwitchImportance->setChecked(m_message.m_isImportant);
m_ui->m_txtMessage->setHtml(prepareHtmlForMessage(m_message)); m_ui->m_txtMessage->setHtml(prepareHtmlForMessage(m_message));
updateButtons(); updateButtons();
show(); show();
m_ui->m_txtMessage->verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum); m_ui->m_txtMessage->verticalScrollBar()->triggerAction(QScrollBar::SliderToMinimum);
} }
} }
@ -172,7 +164,6 @@ void MessagePreviewer::markMessageAsReadUnread(RootItem::ReadStatus read) {
QList<Message>() << m_message, QList<Message>() << m_message,
read); read);
m_message.m_isRead = read == RootItem::Read; m_message.m_isRead = read == RootItem::Read;
emit markMessageRead(m_message.m_id, read); emit markMessageRead(m_message.m_id, read);
updateButtons(); updateButtons();
} }
@ -188,13 +179,11 @@ void MessagePreviewer::switchMessageImportance(bool checked) {
RootItem::Important))) { RootItem::Important))) {
DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings), DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(m_message.m_id)); QStringList() << QString::number(m_message.m_id));
m_root->getParentServiceRoot()->onAfterSwitchMessageImportance(m_root.data(), m_root->getParentServiceRoot()->onAfterSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(m_message, QList<ImportanceChange>() << ImportanceChange(m_message,
m_message.m_isImportant ? m_message.m_isImportant ?
RootItem::NotImportant : RootItem::NotImportant :
RootItem::Important)); RootItem::Important));
emit markMessageImportant(m_message.m_id, checked ? RootItem::Important : RootItem::NotImportant); emit markMessageImportant(m_message.m_id, checked ? RootItem::Important : RootItem::NotImportant);
m_message.m_isImportant = checked; m_message.m_isImportant = checked;
} }
@ -208,7 +197,6 @@ void MessagePreviewer::updateButtons() {
QString MessagePreviewer::prepareHtmlForMessage(const Message& message) { QString MessagePreviewer::prepareHtmlForMessage(const Message& message) {
QString html = QString("<h2 align=\"center\">%1</h2>").arg(message.m_title); 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); html += QString("[url] <a href=\"%1\">%1</a><br/>").arg(message.m_url);
foreach (const Enclosure& enc, message.m_enclosures) { foreach (const Enclosure& enc, message.m_enclosures) {
@ -217,18 +205,15 @@ QString MessagePreviewer::prepareHtmlForMessage(const Message &message) {
int offset = 0; int offset = 0;
QRegExp imgTagRegex("\\<img[^\\>]*src\\s*=\\s*\"([^\"]*)\"[^\\>]*\\>", Qt::CaseInsensitive); QRegExp imgTagRegex("\\<img[^\\>]*src\\s*=\\s*\"([^\"]*)\"[^\\>]*\\>", Qt::CaseInsensitive);
imgTagRegex.setMinimal(true); imgTagRegex.setMinimal(true);
while ((offset = imgTagRegex.indexIn(message.m_contents, offset)) != -1) { while ((offset = imgTagRegex.indexIn(message.m_contents, offset)) != -1) {
m_pictures.append(imgTagRegex.cap(1)); m_pictures.append(imgTagRegex.cap(1));
offset += imgTagRegex.matchedLength(); offset += imgTagRegex.matchedLength();
html += QString("[%2] <a href=\"%1\">%1</a><br/>").arg(imgTagRegex.cap(1), tr("image")); html += QString("[%2] <a href=\"%1\">%1</a><br/>").arg(imgTagRegex.cap(1), tr("image"));
} }
html += "<br/>"; html += "<br/>";
html += message.m_contents; html += message.m_contents;
return html; return html;
} }

View File

@ -39,10 +39,8 @@ MessagesToolBar::~MessagesToolBar() {
QList<QAction*> MessagesToolBar::availableActions() const { QList<QAction*> MessagesToolBar::availableActions() const {
QList<QAction*> available_actions = qApp->userActions(); QList<QAction*> available_actions = qApp->userActions();
available_actions.append(m_actionSearchMessages); available_actions.append(m_actionSearchMessages);
available_actions.append(m_actionMessageHighlighter); available_actions.append(m_actionMessageHighlighter);
return available_actions; return available_actions;
} }
@ -72,33 +70,33 @@ QList<QAction*> MessagesToolBar::getSpecificActions(const QStringList &actions)
// Add existing standard action. // Add existing standard action.
spec_actions.append(matching_action); spec_actions.append(matching_action);
} }
else if (action_name == SEPARATOR_ACTION_NAME) { else if (action_name == SEPARATOR_ACTION_NAME) {
// Add new separator. // Add new separator.
QAction* act = new QAction(this); QAction* act = new QAction(this);
act->setSeparator(true); act->setSeparator(true);
spec_actions.append(act); spec_actions.append(act);
} }
else if (action_name == SEACRH_MESSAGES_ACTION_NAME) { else if (action_name == SEACRH_MESSAGES_ACTION_NAME) {
// Add search box. // Add search box.
spec_actions.append(m_actionSearchMessages); spec_actions.append(m_actionSearchMessages);
} }
else if (action_name == HIGHLIGHTER_ACTION_NAME) { else if (action_name == HIGHLIGHTER_ACTION_NAME) {
// Add filter button. // Add filter button.
spec_actions.append(m_actionMessageHighlighter); spec_actions.append(m_actionMessageHighlighter);
} }
else if (action_name == SPACER_ACTION_NAME) { else if (action_name == SPACER_ACTION_NAME) {
// Add new spacer. // Add new spacer.
QWidget* spacer = new QWidget(this); QWidget* spacer = new QWidget(this);
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QWidgetAction* action = new QWidgetAction(this); QWidgetAction* action = new QWidgetAction(this);
action->setDefaultWidget(spacer); action->setDefaultWidget(spacer);
action->setIcon(qApp->icons()->fromTheme(QSL("go-jump"))); action->setIcon(qApp->icons()->fromTheme(QSL("go-jump")));
action->setProperty("type", SPACER_ACTION_NAME); action->setProperty("type", SPACER_ACTION_NAME);
action->setProperty("name", tr("Toolbar spacer")); action->setProperty("name", tr("Toolbar spacer"));
spec_actions.append(action); spec_actions.append(action);
} }
} }
@ -117,7 +115,6 @@ void MessagesToolBar::loadSpecificActions(const QList<QAction*> &actions) {
void MessagesToolBar::handleMessageHighlighterChange(QAction* action) { void MessagesToolBar::handleMessageHighlighterChange(QAction* action) {
m_btnMessageHighlighter->setIcon(action->icon()); m_btnMessageHighlighter->setIcon(action->icon());
m_btnMessageHighlighter->setToolTip(action->text()); m_btnMessageHighlighter->setToolTip(action->text());
emit messageFilterChanged(action->data().value<MessagesModel::MessageHighlighter>()); emit messageFilterChanged(action->data().value<MessagesModel::MessageHighlighter>());
} }
@ -125,14 +122,12 @@ void MessagesToolBar::initializeSearchBox() {
m_txtSearchMessages = new MessagesSearchLineEdit(this); m_txtSearchMessages = new MessagesSearchLineEdit(this);
m_txtSearchMessages->setFixedWidth(FILTER_WIDTH); m_txtSearchMessages->setFixedWidth(FILTER_WIDTH);
m_txtSearchMessages->setPlaceholderText(tr("Search messages")); m_txtSearchMessages->setPlaceholderText(tr("Search messages"));
// Setup wrapping action for search box. // Setup wrapping action for search box.
m_actionSearchMessages = new QWidgetAction(this); m_actionSearchMessages = new QWidgetAction(this);
m_actionSearchMessages->setDefaultWidget(m_txtSearchMessages); m_actionSearchMessages->setDefaultWidget(m_txtSearchMessages);
m_actionSearchMessages->setIcon(qApp->icons()->fromTheme(QSL("system-search"))); m_actionSearchMessages->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
m_actionSearchMessages->setProperty("type", SEACRH_MESSAGES_ACTION_NAME); m_actionSearchMessages->setProperty("type", SEACRH_MESSAGES_ACTION_NAME);
m_actionSearchMessages->setProperty("name", tr("Message search box")); m_actionSearchMessages->setProperty("name", tr("Message search box"));
connect(m_txtSearchMessages, &MessagesSearchLineEdit::textChanged, this, &MessagesToolBar::messageSearchPatternChanged); connect(m_txtSearchMessages, &MessagesSearchLineEdit::textChanged, this, &MessagesToolBar::messageSearchPatternChanged);
} }
@ -144,19 +139,16 @@ void MessagesToolBar::initializeHighlighter() {
tr("Highlight unread messages"))->setData(QVariant::fromValue(MessagesModel::HighlightUnread)); tr("Highlight unread messages"))->setData(QVariant::fromValue(MessagesModel::HighlightUnread));
m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme(QSL("mail-mark-important")), m_menuMessageHighlighter->addAction(qApp->icons()->fromTheme(QSL("mail-mark-important")),
tr("Highlight important messages"))->setData(QVariant::fromValue(MessagesModel::HighlightImportant)); tr("Highlight important messages"))->setData(QVariant::fromValue(MessagesModel::HighlightImportant));
m_btnMessageHighlighter = new QToolButton(this); m_btnMessageHighlighter = new QToolButton(this);
m_btnMessageHighlighter->setToolTip(tr("Display all messages")); m_btnMessageHighlighter->setToolTip(tr("Display all messages"));
m_btnMessageHighlighter->setMenu(m_menuMessageHighlighter); m_btnMessageHighlighter->setMenu(m_menuMessageHighlighter);
m_btnMessageHighlighter->setPopupMode(QToolButton::MenuButtonPopup); m_btnMessageHighlighter->setPopupMode(QToolButton::MenuButtonPopup);
m_btnMessageHighlighter->setIcon(qApp->icons()->fromTheme(QSL("mail-mark-read"))); m_btnMessageHighlighter->setIcon(qApp->icons()->fromTheme(QSL("mail-mark-read")));
m_actionMessageHighlighter = new QWidgetAction(this); m_actionMessageHighlighter = new QWidgetAction(this);
m_actionMessageHighlighter->setDefaultWidget(m_btnMessageHighlighter); m_actionMessageHighlighter->setDefaultWidget(m_btnMessageHighlighter);
m_actionMessageHighlighter->setIcon(m_btnMessageHighlighter->icon()); m_actionMessageHighlighter->setIcon(m_btnMessageHighlighter->icon());
m_actionMessageHighlighter->setProperty("type", HIGHLIGHTER_ACTION_NAME); m_actionMessageHighlighter->setProperty("type", HIGHLIGHTER_ACTION_NAME);
m_actionMessageHighlighter->setProperty("name", tr("Message highlighter")); m_actionMessageHighlighter->setProperty("name", tr("Message highlighter"));
connect(m_menuMessageHighlighter, SIGNAL(triggered(QAction*)), connect(m_menuMessageHighlighter, SIGNAL(triggered(QAction*)),
this, SLOT(handleMessageHighlighterChange(QAction*))); this, SLOT(handleMessageHighlighterChange(QAction*)));
} }

View File

@ -38,12 +38,10 @@ MessagesView::MessagesView(QWidget *parent)
: QTreeView(parent), m_contextMenu(nullptr), m_columnsAdjusted(false) { : QTreeView(parent), m_contextMenu(nullptr), m_columnsAdjusted(false) {
m_sourceModel = qApp->feedReader()->messagesModel(); m_sourceModel = qApp->feedReader()->messagesModel();
m_proxyModel = qApp->feedReader()->messagesProxyModel(); m_proxyModel = qApp->feedReader()->messagesProxyModel();
// Forward count changes to the view. // Forward count changes to the view.
createConnections(); createConnections();
setModel(m_proxyModel); setModel(m_proxyModel);
setupAppearance(); setupAppearance();
header()->setContextMenuPolicy(Qt::CustomContextMenu); header()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(header(), &QHeaderView::customContextMenuRequested, [ = ](const QPoint & point) { connect(header(), &QHeaderView::customContextMenuRequested, [ = ](const QPoint & point) {
TreeViewColumnsMenu mm(header()); TreeViewColumnsMenu mm(header());
@ -74,7 +72,6 @@ void MessagesView::sort(int column, Qt::SortOrder order, bool repopulate_data, b
void MessagesView::createConnections() { void MessagesView::createConnections() {
connect(this, &MessagesView::doubleClicked, this, &MessagesView::openSelectedSourceMessagesExternally); connect(this, &MessagesView::doubleClicked, this, &MessagesView::openSelectedSourceMessagesExternally);
// Adjust columns when layout gets changed. // Adjust columns when layout gets changed.
connect(header(), &QHeaderView::geometriesChanged, this, &MessagesView::adjustColumns); connect(header(), &QHeaderView::geometriesChanged, this, &MessagesView::adjustColumns);
connect(header(), &QHeaderView::sortIndicatorChanged, this, &MessagesView::onSortIndicatorChanged); connect(header(), &QHeaderView::sortIndicatorChanged, this, &MessagesView::onSortIndicatorChanged);
@ -90,13 +87,11 @@ void MessagesView::keyboardSearch(const QString &search) {
void MessagesView::reloadSelections() { void MessagesView::reloadSelections() {
const QDateTime dt1 = QDateTime::currentDateTime(); const QDateTime dt1 = QDateTime::currentDateTime();
QModelIndex current_index = selectionModel()->currentIndex(); QModelIndex current_index = selectionModel()->currentIndex();
const QModelIndex mapped_current_index = m_proxyModel->mapToSource(current_index); const QModelIndex mapped_current_index = m_proxyModel->mapToSource(current_index);
const Message selected_message = m_sourceModel->messageAt(mapped_current_index.row()); const Message selected_message = m_sourceModel->messageAt(mapped_current_index.row());
const int col = header()->sortIndicatorSection(); const int col = header()->sortIndicatorSection();
const Qt::SortOrder ord = header()->sortIndicatorOrder(); const Qt::SortOrder ord = header()->sortIndicatorOrder();
// Reload the model now. // Reload the model now.
sort(col, ord, true, false, false); sort(col, ord, true, false, false);
@ -105,6 +100,7 @@ void MessagesView::reloadSelections() {
if (m_proxyModel->rowCount() == 0) { if (m_proxyModel->rowCount() == 0) {
current_index = QModelIndex(); current_index = QModelIndex();
} }
else { else {
for (int i = 0; i < m_proxyModel->rowCount(); i++) { for (int i = 0; i < m_proxyModel->rowCount(); i++) {
QModelIndex msg_idx = m_proxyModel->index(i, MSG_DB_TITLE_INDEX); QModelIndex msg_idx = m_proxyModel->index(i, MSG_DB_TITLE_INDEX);
@ -127,6 +123,7 @@ void MessagesView::reloadSelections() {
setCurrentIndex(current_index); setCurrentIndex(current_index);
reselectIndexes(QModelIndexList() << current_index); reselectIndexes(QModelIndexList() << current_index);
} }
else { else {
// Messages were probably removed from the model, nothing can // Messages were probably removed from the model, nothing can
// be selected and no message can be displayed. // be selected and no message can be displayed.
@ -134,7 +131,6 @@ void MessagesView::reloadSelections() {
} }
const QDateTime dt2 = QDateTime::currentDateTime(); const QDateTime dt2 = QDateTime::currentDateTime();
qDebug("Reloading of msg selections took %lld miliseconds.", dt1.msecsTo(dt2)); qDebug("Reloading of msg selections took %lld miliseconds.", dt1.msecsTo(dt2));
} }
@ -151,7 +147,6 @@ void MessagesView::setupAppearance() {
setAllColumnsShowFocus(false); setAllColumnsShowFocus(false);
setSelectionMode(QAbstractItemView::ExtendedSelection); setSelectionMode(QAbstractItemView::ExtendedSelection);
setItemDelegate(new StyledItemDelegateWithoutFocus(this)); setItemDelegate(new StyledItemDelegateWithoutFocus(this));
header()->setDefaultSectionSize(MESSAGES_VIEW_DEFAULT_COL); header()->setDefaultSectionSize(MESSAGES_VIEW_DEFAULT_COL);
header()->setMinimumSectionSize(MESSAGES_VIEW_MINIMUM_COL); header()->setMinimumSectionSize(MESSAGES_VIEW_MINIMUM_COL);
header()->setCascadingSectionResizes(false); header()->setCascadingSectionResizes(false);
@ -174,10 +169,10 @@ void MessagesView::contextMenuEvent(QContextMenuEvent *event) {
TreeViewColumnsMenu menu(header()); TreeViewColumnsMenu menu(header());
menu.exec(event->globalPos()); menu.exec(event->globalPos());
} }
else { else {
// Context menu is not initialized, initialize. // Context menu is not initialized, initialize.
initializeContextMenu(); initializeContextMenu();
m_contextMenu->exec(event->globalPos()); m_contextMenu->exec(event->globalPos());
} }
} }
@ -238,7 +233,6 @@ void MessagesView::mousePressEvent(QMouseEvent *event) {
} }
} }
break; break;
} }
@ -251,21 +245,19 @@ void MessagesView::selectionChanged(const QItemSelection &selected, const QItemS
const QModelIndexList selected_rows = selectionModel()->selectedRows(); const QModelIndexList selected_rows = selectionModel()->selectedRows();
const QModelIndex current_index = currentIndex(); const QModelIndex current_index = currentIndex();
const QModelIndex mapped_current_index = m_proxyModel->mapToSource(current_index); const QModelIndex mapped_current_index = m_proxyModel->mapToSource(current_index);
qDebug("Current row changed - row [%d,%d] source [%d, %d].", qDebug("Current row changed - row [%d,%d] source [%d, %d].",
current_index.row(), current_index.column(), current_index.row(), current_index.column(),
mapped_current_index.row(), mapped_current_index.column()); mapped_current_index.row(), mapped_current_index.column());
if (mapped_current_index.isValid() && selected_rows.count() > 0) { if (mapped_current_index.isValid() && selected_rows.count() > 0) {
Message message = m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()); Message message = m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row());
// Set this message as read only if current item // Set this message as read only if current item
// wasn't changed by "mark selected messages unread" action. // wasn't changed by "mark selected messages unread" action.
m_sourceModel->setMessageRead(mapped_current_index.row(), RootItem::Read); m_sourceModel->setMessageRead(mapped_current_index.row(), RootItem::Read);
message.m_isRead = true; message.m_isRead = true;
emit currentMessageChanged(message, m_sourceModel->loadedItem()); emit currentMessageChanged(message, m_sourceModel->loadedItem());
} }
else { else {
emit currentMessageRemoved(); emit currentMessageRemoved();
} }
@ -280,11 +272,9 @@ void MessagesView::selectionChanged(const QItemSelection &selected, const QItemS
void MessagesView::loadItem(RootItem* item) { void MessagesView::loadItem(RootItem* item) {
const int col = header()->sortIndicatorSection(); const int col = header()->sortIndicatorSection();
const Qt::SortOrder ord = header()->sortIndicatorOrder(); const Qt::SortOrder ord = header()->sortIndicatorOrder();
scrollToTop(); scrollToTop();
sort(col, ord, false, true, false); sort(col, ord, false, true, false);
m_sourceModel->loadMessages(item); m_sourceModel->loadMessages(item);
// Messages are loaded, make sure that previously // Messages are loaded, make sure that previously
// active message is not shown in browser. // active message is not shown in browser.
// BUG: Qt 5 is probably bugged here. Selections // BUG: Qt 5 is probably bugged here. Selections
@ -352,13 +342,13 @@ void MessagesView::setSelectedMessagesReadStatus(RootItem::ReadStatus read) {
QModelIndexList selected_indexes = selectionModel()->selectedRows(); QModelIndexList selected_indexes = selectionModel()->selectedRows();
const QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes); const QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes);
m_sourceModel->setBatchMessagesRead(mapped_indexes, read); m_sourceModel->setBatchMessagesRead(mapped_indexes, read);
current_index = m_proxyModel->index(current_index.row(), current_index.column()); current_index = m_proxyModel->index(current_index.row(), current_index.column());
if (current_index.isValid()) { if (current_index.isValid()) {
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem()); emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
} }
else { else {
emit currentMessageRemoved(); emit currentMessageRemoved();
} }
@ -373,7 +363,6 @@ void MessagesView::deleteSelectedMessages() {
const QModelIndexList selected_indexes = selectionModel()->selectedRows(); const QModelIndexList selected_indexes = selectionModel()->selectedRows();
const QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes); const QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes);
m_sourceModel->setBatchMessagesDeleted(mapped_indexes); m_sourceModel->setBatchMessagesDeleted(mapped_indexes);
current_index = moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier); current_index = moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier);
@ -381,6 +370,7 @@ void MessagesView::deleteSelectedMessages() {
setCurrentIndex(current_index); setCurrentIndex(current_index);
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem()); emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
} }
else { else {
emit currentMessageRemoved(); emit currentMessageRemoved();
} }
@ -395,14 +385,13 @@ void MessagesView::restoreSelectedMessages() {
const QModelIndexList selected_indexes = selectionModel()->selectedRows(); const QModelIndexList selected_indexes = selectionModel()->selectedRows();
const QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes); const QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes);
m_sourceModel->setBatchMessagesRestored(mapped_indexes); m_sourceModel->setBatchMessagesRestored(mapped_indexes);
current_index = m_proxyModel->index(current_index.row(), current_index.column()); current_index = m_proxyModel->index(current_index.row(), current_index.column());
if (current_index.isValid()) { if (current_index.isValid()) {
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem()); emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
} }
else { else {
emit currentMessageRemoved(); emit currentMessageRemoved();
} }
@ -417,13 +406,13 @@ void MessagesView::switchSelectedMessagesImportance() {
QModelIndexList selected_indexes = selectionModel()->selectedRows(); QModelIndexList selected_indexes = selectionModel()->selectedRows();
const QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes); const QModelIndexList mapped_indexes = m_proxyModel->mapListToSource(selected_indexes);
m_sourceModel->switchBatchMessageImportance(mapped_indexes); m_sourceModel->switchBatchMessageImportance(mapped_indexes);
current_index = m_proxyModel->index(current_index.row(), current_index.column()); current_index = m_proxyModel->index(current_index.row(), current_index.column());
if (current_index.isValid()) { if (current_index.isValid()) {
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem()); emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
} }
else { else {
// Messages were probably removed from the model, nothing can // Messages were probably removed from the model, nothing can
// be selected and no message can be displayed. // be selected and no message can be displayed.
@ -465,7 +454,6 @@ void MessagesView::selectPreviousItem() {
void MessagesView::selectNextUnreadItem() { void MessagesView::selectNextUnreadItem() {
// FIXME: Use this to solve #112. // FIXME: Use this to solve #112.
const QModelIndexList selected_rows = selectionModel()->selectedRows(); const QModelIndexList selected_rows = selectionModel()->selectedRows();
int active_row; int active_row;
@ -473,6 +461,7 @@ void MessagesView::selectNextUnreadItem() {
// Okay, something is selected, start from it. // Okay, something is selected, start from it.
active_row = selected_rows.at(0).row(); active_row = selected_rows.at(0).row();
} }
else { else {
active_row = 0; active_row = 0;
} }
@ -493,6 +482,7 @@ void MessagesView::searchMessages(const QString &pattern) {
if (selectionModel()->selectedRows().size() == 0) { if (selectionModel()->selectedRows().size() == 0) {
emit currentMessageRemoved(); emit currentMessageRemoved();
} }
else { else {
// Scroll to selected message, it could become scrolled out due to filter change. // Scroll to selected message, it could become scrolled out due to filter change.
scrollTo(selectionModel()->selectedRows().at(0)); scrollTo(selectionModel()->selectedRows().at(0));
@ -506,7 +496,6 @@ void MessagesView::filterMessages(MessagesModel::MessageHighlighter filter) {
void MessagesView::adjustColumns() { void MessagesView::adjustColumns() {
if (header()->count() > 0 && !m_columnsAdjusted) { if (header()->count() > 0 && !m_columnsAdjusted) {
m_columnsAdjusted = true; m_columnsAdjusted = true;
// Setup column resize strategies. // Setup column resize strategies.
header()->setSectionResizeMode(MSG_DB_ID_INDEX, QHeaderView::Interactive); header()->setSectionResizeMode(MSG_DB_ID_INDEX, QHeaderView::Interactive);
header()->setSectionResizeMode(MSG_DB_READ_INDEX, QHeaderView::ResizeToContents); header()->setSectionResizeMode(MSG_DB_READ_INDEX, QHeaderView::ResizeToContents);
@ -519,10 +508,8 @@ void MessagesView::adjustColumns() {
header()->setSectionResizeMode(MSG_DB_DCREATED_INDEX, QHeaderView::Interactive); header()->setSectionResizeMode(MSG_DB_DCREATED_INDEX, QHeaderView::Interactive);
header()->setSectionResizeMode(MSG_DB_CONTENTS_INDEX, QHeaderView::Interactive); header()->setSectionResizeMode(MSG_DB_CONTENTS_INDEX, QHeaderView::Interactive);
header()->setSectionResizeMode(MSG_DB_PDELETED_INDEX, QHeaderView::Interactive); header()->setSectionResizeMode(MSG_DB_PDELETED_INDEX, QHeaderView::Interactive);
//header()->resizeSection(MSG_DB_READ_INDEX, MESSAGES_VIEW_MINIMUM_COL); //header()->resizeSection(MSG_DB_READ_INDEX, MESSAGES_VIEW_MINIMUM_COL);
//header()->resizeSection(MSG_DB_IMPORTANT_INDEX, MESSAGES_VIEW_MINIMUM_COL); //header()->resizeSection(MSG_DB_IMPORTANT_INDEX, MESSAGES_VIEW_MINIMUM_COL);
// Hide columns. // Hide columns.
hideColumn(MSG_DB_ID_INDEX); hideColumn(MSG_DB_ID_INDEX);
hideColumn(MSG_DB_DELETED_INDEX); hideColumn(MSG_DB_DELETED_INDEX);
@ -534,7 +521,6 @@ void MessagesView::adjustColumns() {
hideColumn(MSG_DB_CUSTOM_ID_INDEX); hideColumn(MSG_DB_CUSTOM_ID_INDEX);
hideColumn(MSG_DB_CUSTOM_HASH_INDEX); hideColumn(MSG_DB_CUSTOM_HASH_INDEX);
hideColumn(MSG_DB_FEED_CUSTOM_ID_INDEX); hideColumn(MSG_DB_FEED_CUSTOM_ID_INDEX);
qDebug("Adjusting column resize modes for MessagesView."); qDebug("Adjusting column resize modes for MessagesView.");
} }
} }

View File

@ -42,9 +42,7 @@ void NewspaperPreviewer::showMoreMessages() {
Message msg = m_messages.takeFirst(); Message msg = m_messages.takeFirst();
MessagePreviewer* prev = new MessagePreviewer(this); MessagePreviewer* prev = new MessagePreviewer(this);
QMargins margins = prev->layout()->contentsMargins(); QMargins margins = prev->layout()->contentsMargins();
connect(prev, &MessagePreviewer::requestMessageListReload, this, &NewspaperPreviewer::requestMessageListReload); connect(prev, &MessagePreviewer::requestMessageListReload, this, &NewspaperPreviewer::requestMessageListReload);
margins.setRight(0); margins.setRight(0);
prev->layout()->setContentsMargins(margins); prev->layout()->setContentsMargins(margins);
prev->setFixedHeight(300); prev->setFixedHeight(300);
@ -56,6 +54,7 @@ void NewspaperPreviewer::showMoreMessages() {
m_ui->m_btnShowMoreMessages->setEnabled(!m_messages.isEmpty()); m_ui->m_btnShowMoreMessages->setEnabled(!m_messages.isEmpty());
m_ui->scrollArea->verticalScrollBar()->setValue(current_scroll); m_ui->scrollArea->verticalScrollBar()->setValue(current_scroll);
} }
else { else {
qApp->showGuiMessage(tr("Cannot show more messages"), qApp->showGuiMessage(tr("Cannot show more messages"),
tr("Cannot show more messages because parent feed was removed."), tr("Cannot show more messages because parent feed was removed."),

View File

@ -33,10 +33,8 @@ PlainToolButton::~PlainToolButton() {
void PlainToolButton::paintEvent(QPaintEvent* e) { void PlainToolButton::paintEvent(QPaintEvent* e) {
Q_UNUSED(e) Q_UNUSED(e)
QPainter p(this); QPainter p(this);
QRect rect(QPoint(0, 0), size()); QRect rect(QPoint(0, 0), size());
// Set padding. // Set padding.
rect.adjust(m_padding, m_padding, -m_padding, -m_padding); rect.adjust(m_padding, m_padding, -m_padding, -m_padding);
@ -45,6 +43,7 @@ void PlainToolButton::paintEvent(QPaintEvent *e) {
p.setOpacity(0.7); p.setOpacity(0.7);
} }
} }
else { else {
p.setOpacity(0.3); p.setOpacity(0.3);
} }

View File

@ -29,17 +29,14 @@
SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent) SettingsBrowserMail::SettingsBrowserMail(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsBrowserMail) {
m_ui->setupUi(this); m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(m_ui->label, false); GuiUtilities::setLabelAsNotice(m_ui->label, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblExternalEmailInfo, false); GuiUtilities::setLabelAsNotice(m_ui->m_lblExternalEmailInfo, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblProxyInfo, false); GuiUtilities::setLabelAsNotice(m_ui->m_lblProxyInfo, false);
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
m_ui->m_checkOpenLinksInExternal->setVisible(false); m_ui->m_checkOpenLinksInExternal->setVisible(false);
#else #else
connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings); connect(m_ui->m_checkOpenLinksInExternal, &QCheckBox::stateChanged, this, &SettingsBrowserMail::dirtifySettings);
#endif #endif
connect(m_ui->m_cmbProxyType, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::dirtifySettings); 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_txtProxyHost, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtProxyPassword, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings); connect(m_ui->m_txtProxyPassword, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
@ -51,7 +48,6 @@ SettingsBrowserMail::SettingsBrowserMail(Settings *settings, QWidget *parent)
connect(m_ui->m_txtExternalBrowserExecutable, &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_txtExternalEmailArguments, &QLineEdit::textChanged, this, &SettingsBrowserMail::dirtifySettings);
connect(m_ui->m_txtExternalEmailExecutable, &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_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_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_cmbExternalBrowserPreset, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsBrowserMail::changeDefaultBrowserArguments);
@ -91,6 +87,7 @@ void SettingsBrowserMail::displayProxyPassword(int state) {
if (state == Qt::Checked) { if (state == Qt::Checked) {
m_ui->m_txtProxyPassword->setEchoMode(QLineEdit::Normal); m_ui->m_txtProxyPassword->setEchoMode(QLineEdit::Normal);
} }
else { else {
m_ui->m_txtProxyPassword->setEchoMode(QLineEdit::PasswordEchoOnEdit); m_ui->m_txtProxyPassword->setEchoMode(QLineEdit::PasswordEchoOnEdit);
} }
@ -99,7 +96,6 @@ void SettingsBrowserMail::displayProxyPassword(int state) {
void SettingsBrowserMail::onProxyTypeChanged(int index) { void SettingsBrowserMail::onProxyTypeChanged(int index) {
const QNetworkProxy::ProxyType selected_type = static_cast<QNetworkProxy::ProxyType>(m_ui->m_cmbProxyType->itemData(index).toInt()); 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; const bool is_proxy_selected = selected_type != QNetworkProxy::NoProxy && selected_type != QNetworkProxy::DefaultProxy;
m_ui->m_txtProxyHost->setEnabled(is_proxy_selected); m_ui->m_txtProxyHost->setEnabled(is_proxy_selected);
m_ui->m_txtProxyPassword->setEnabled(is_proxy_selected); m_ui->m_txtProxyPassword->setEnabled(is_proxy_selected);
m_ui->m_txtProxyUsername->setEnabled(is_proxy_selected); m_ui->m_txtProxyUsername->setEnabled(is_proxy_selected);
@ -137,66 +133,53 @@ void SettingsBrowserMail::selectEmailExecutable() {
void SettingsBrowserMail::loadSettings() { void SettingsBrowserMail::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
#if !defined(USE_WEBENGINE) #if !defined(USE_WEBENGINE)
m_ui->m_checkOpenLinksInExternal->setChecked(settings()->value(GROUP(Browser), m_ui->m_checkOpenLinksInExternal->setChecked(settings()->value(GROUP(Browser),
SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool()); SETTING(Browser::OpenLinksInExternalBrowserRightAway)).toBool());
#endif #endif
// Load settings of web browser GUI. // Load settings of web browser GUI.
m_ui->m_cmbExternalBrowserPreset->addItem(tr("Opera 12 or older"), QSL("-nosession %1")); 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_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_txtExternalBrowserArguments->setText(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserArguments)).toString());
m_ui->m_grpCustomExternalBrowser->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool()); m_ui->m_grpCustomExternalBrowser->setChecked(settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool());
// Load settings of e-mail. // Load settings of e-mail.
m_ui->m_cmbExternalEmailPreset->addItem(tr("Mozilla Thunderbird"), QSL("-compose \"subject='%1',body='%2'\"")); 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_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_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_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("No proxy"), QNetworkProxy::NoProxy);
m_ui->m_cmbProxyType->addItem(tr("System proxy"), QNetworkProxy::DefaultProxy); 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("Socks5"), QNetworkProxy::Socks5Proxy);
m_ui->m_cmbProxyType->addItem(tr("Http"), QNetworkProxy::HttpProxy); m_ui->m_cmbProxyType->addItem(tr("Http"), QNetworkProxy::HttpProxy);
// Load the settings. // Load the settings.
QNetworkProxy::ProxyType selected_proxy_type = static_cast<QNetworkProxy::ProxyType>(settings()->value(GROUP(Proxy), SETTING(Proxy::Type)).toInt()); 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_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_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_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_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()); m_ui->m_spinProxyPort->setValue(settings()->value(GROUP(Proxy), SETTING(Proxy::Port)).toInt());
onEndLoadSettings(); onEndLoadSettings();
} }
void SettingsBrowserMail::saveSettings() { void SettingsBrowserMail::saveSettings() {
onBeginSaveSettings(); onBeginSaveSettings();
#if !defined(USE_WEBENGINE) #if !defined(USE_WEBENGINE)
settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, m_ui->m_checkOpenLinksInExternal->isChecked()); settings()->setValue(GROUP(Browser), Browser::OpenLinksInExternalBrowserRightAway, m_ui->m_checkOpenLinksInExternal->isChecked());
#endif #endif
// Save settings of GUI of web browser. // Save settings of GUI of web browser.
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserEnabled, m_ui->m_grpCustomExternalBrowser->isChecked()); 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::CustomExternalBrowserExecutable, m_ui->m_txtExternalBrowserExecutable->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserArguments, m_ui->m_txtExternalBrowserArguments->text()); settings()->setValue(GROUP(Browser), Browser::CustomExternalBrowserArguments, m_ui->m_txtExternalBrowserArguments->text());
// Save settings of e-mail. // Save settings of e-mail.
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailExecutable, m_ui->m_txtExternalEmailExecutable->text()); 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::CustomExternalEmailArguments, m_ui->m_txtExternalEmailArguments->text());
settings()->setValue(GROUP(Browser), Browser::CustomExternalEmailEnabled, m_ui->m_grpCustomExternalEmail->isChecked()); 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::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::Host, m_ui->m_txtProxyHost->text());
settings()->setValue(GROUP(Proxy), Proxy::Username, m_ui->m_txtProxyUsername->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::Password, TextFactory::encrypt(m_ui->m_txtProxyPassword->text()));
settings()->setValue(GROUP(Proxy), Proxy::Port, m_ui->m_spinProxyPort->value()); settings()->setValue(GROUP(Proxy), Proxy::Port, m_ui->m_spinProxyPort->value());
// Reload settings for all network access managers. // Reload settings for all network access managers.
SilentNetworkAccessManager::instance()->loadSettings(); SilentNetworkAccessManager::instance()->loadSettings();
onEndSaveSettings(); onEndSaveSettings();
} }

View File

@ -27,11 +27,9 @@
SettingsDatabase::SettingsDatabase(Settings* settings, QWidget* parent) SettingsDatabase::SettingsDatabase(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsDatabase) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsDatabase) {
m_ui->setupUi(this); m_ui->setupUi(this);
GuiUtilities::setLabelAsNotice(m_ui->m_lblDataStorageWarning, true); GuiUtilities::setLabelAsNotice(m_ui->m_lblDataStorageWarning, true);
GuiUtilities::setLabelAsNotice(m_ui->m_lblMysqlInfo, false); GuiUtilities::setLabelAsNotice(m_ui->m_lblMysqlInfo, false);
GuiUtilities::setLabelAsNotice(m_ui->m_lblSqliteInMemoryWarnings, true); 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_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_checkSqliteUseInMemoryDatabase, &QCheckBox::toggled, this, &SettingsDatabase::dirtifySettings);
connect(m_ui->m_txtMysqlDatabase->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings); connect(m_ui->m_txtMysqlDatabase->lineEdit(), &QLineEdit::textChanged, this, &SettingsDatabase::dirtifySettings);
@ -40,7 +38,6 @@ SettingsDatabase::SettingsDatabase(Settings *settings, QWidget *parent)
connect(m_ui->m_checkUseTransactions, &QCheckBox::toggled, 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_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_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_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_checkMysqlShowPassword, &QCheckBox::toggled, this, &SettingsDatabase::switchMysqlPasswordVisiblity);
connect(m_ui->m_txtMysqlUsername->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlUsernameChanged); connect(m_ui->m_txtMysqlUsername->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlUsernameChanged);
@ -48,7 +45,6 @@ SettingsDatabase::SettingsDatabase(Settings *settings, QWidget *parent)
connect(m_ui->m_txtMysqlPassword->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlPasswordChanged); 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_txtMysqlDatabase->lineEdit(), &BaseLineEdit::textChanged, this, &SettingsDatabase::onMysqlDatabaseChanged);
connect(m_ui->m_btnMysqlTestSetup, &QPushButton::clicked, this, &SettingsDatabase::mysqlTestConnection); 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_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_checkSqliteUseInMemoryDatabase, &QCheckBox::toggled, this, &SettingsDatabase::requireRestart);
connect(m_ui->m_spinMysqlPort, &QSpinBox::editingFinished, this, &SettingsDatabase::requireRestart); connect(m_ui->m_spinMysqlPort, &QSpinBox::editingFinished, this, &SettingsDatabase::requireRestart);
@ -69,7 +65,6 @@ void SettingsDatabase::mysqlTestConnection() {
m_ui->m_txtMysqlPassword->lineEdit()->text()); m_ui->m_txtMysqlPassword->lineEdit()->text());
const QString interpretation = qApp->database()->mysqlInterpretErrorCode(error_code); const QString interpretation = qApp->database()->mysqlInterpretErrorCode(error_code);
switch (error_code) { switch (error_code) {
case DatabaseFactory::MySQLOk: case DatabaseFactory::MySQLOk:
case DatabaseFactory::MySQLUnknownDatabase: case DatabaseFactory::MySQLUnknownDatabase:
@ -86,6 +81,7 @@ void SettingsDatabase::onMysqlHostnameChanged(const QString &new_hostname) {
if (new_hostname.isEmpty()) { if (new_hostname.isEmpty()) {
m_ui->m_txtMysqlHostname->setStatus(LineEditWithStatus::Warning, tr("Hostname is empty.")); m_ui->m_txtMysqlHostname->setStatus(LineEditWithStatus::Warning, tr("Hostname is empty."));
} }
else { else {
m_ui->m_txtMysqlHostname->setStatus(LineEditWithStatus::Ok, tr("Hostname looks ok.")); m_ui->m_txtMysqlHostname->setStatus(LineEditWithStatus::Ok, tr("Hostname looks ok."));
} }
@ -95,6 +91,7 @@ void SettingsDatabase::onMysqlUsernameChanged(const QString &new_username) {
if (new_username.isEmpty()) { if (new_username.isEmpty()) {
m_ui->m_txtMysqlUsername->setStatus(LineEditWithStatus::Warning, tr("Username is empty.")); m_ui->m_txtMysqlUsername->setStatus(LineEditWithStatus::Warning, tr("Username is empty."));
} }
else { else {
m_ui->m_txtMysqlUsername->setStatus(LineEditWithStatus::Ok, tr("Username looks ok.")); m_ui->m_txtMysqlUsername->setStatus(LineEditWithStatus::Ok, tr("Username looks ok."));
} }
@ -104,6 +101,7 @@ void SettingsDatabase::onMysqlPasswordChanged(const QString &new_password) {
if (new_password.isEmpty()) { if (new_password.isEmpty()) {
m_ui->m_txtMysqlPassword->setStatus(LineEditWithStatus::Warning, tr("Password is empty.")); m_ui->m_txtMysqlPassword->setStatus(LineEditWithStatus::Warning, tr("Password is empty."));
} }
else { else {
m_ui->m_txtMysqlPassword->setStatus(LineEditWithStatus::Ok, tr("Password looks ok.")); m_ui->m_txtMysqlPassword->setStatus(LineEditWithStatus::Ok, tr("Password looks ok."));
} }
@ -113,6 +111,7 @@ void SettingsDatabase::onMysqlDatabaseChanged(const QString &new_database) {
if (new_database.isEmpty()) { if (new_database.isEmpty()) {
m_ui->m_txtMysqlDatabase->setStatus(LineEditWithStatus::Warning, tr("Working database is empty.")); m_ui->m_txtMysqlDatabase->setStatus(LineEditWithStatus::Warning, tr("Working database is empty."));
} }
else { else {
m_ui->m_txtMysqlDatabase->setStatus(LineEditWithStatus::Ok, tr("Working database is ok.")); m_ui->m_txtMysqlDatabase->setStatus(LineEditWithStatus::Ok, tr("Working database is ok."));
} }
@ -124,9 +123,11 @@ void SettingsDatabase::selectSqlBackend(int index) {
if (selected_db_driver == APP_DB_SQLITE_DRIVER) { if (selected_db_driver == APP_DB_SQLITE_DRIVER) {
m_ui->m_stackedDatabaseDriver->setCurrentIndex(0); m_ui->m_stackedDatabaseDriver->setCurrentIndex(0);
} }
else if (selected_db_driver == APP_DB_MYSQL_DRIVER) { else if (selected_db_driver == APP_DB_MYSQL_DRIVER) {
m_ui->m_stackedDatabaseDriver->setCurrentIndex(1); m_ui->m_stackedDatabaseDriver->setCurrentIndex(1);
} }
else { else {
qWarning("GUI for given database driver '%s' is not available.", qPrintable(selected_db_driver)); qWarning("GUI for given database driver '%s' is not available.", qPrintable(selected_db_driver));
} }
@ -138,13 +139,10 @@ void SettingsDatabase::switchMysqlPasswordVisiblity(bool visible) {
void SettingsDatabase::loadSettings() { void SettingsDatabase::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
m_ui->m_checkUseTransactions->setChecked(qApp->settings()->value(GROUP(Database), SETTING(Database::UseTransactions)).toBool()); 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.")); 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. // Load SQLite.
m_ui->m_cmbDatabaseDriver->addItem(qApp->database()->humanDriverName(DatabaseFactory::SQLITE), APP_DB_SQLITE_DRIVER); m_ui->m_cmbDatabaseDriver->addItem(qApp->database()->humanDriverName(DatabaseFactory::SQLITE), APP_DB_SQLITE_DRIVER);
// Load in-memory database status. // Load in-memory database status.
m_ui->m_checkSqliteUseInMemoryDatabase->setChecked(settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool()); m_ui->m_checkSqliteUseInMemoryDatabase->setChecked(settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool());
@ -153,22 +151,18 @@ void SettingsDatabase::loadSettings() {
onMysqlUsernameChanged(QString()); onMysqlUsernameChanged(QString());
onMysqlPasswordChanged(QString()); onMysqlPasswordChanged(QString());
onMysqlDatabaseChanged(QString()); onMysqlDatabaseChanged(QString());
// Load MySQL. // Load MySQL.
m_ui->m_cmbDatabaseDriver->addItem(qApp->database()->humanDriverName(DatabaseFactory::MYSQL), APP_DB_MYSQL_DRIVER); m_ui->m_cmbDatabaseDriver->addItem(qApp->database()->humanDriverName(DatabaseFactory::MYSQL), APP_DB_MYSQL_DRIVER);
// Setup placeholders. // Setup placeholders.
m_ui->m_txtMysqlHostname->lineEdit()->setPlaceholderText(tr("Hostname of your MySQL server")); 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_txtMysqlUsername->lineEdit()->setPlaceholderText(tr("Username to login with"));
m_ui->m_txtMysqlPassword->lineEdit()->setPlaceholderText(tr("Password for your username")); 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_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_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_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_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_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_spinMysqlPort->setValue(settings()->value(GROUP(Database), SETTING(Database::MySQLPort)).toInt());
m_ui->m_checkMysqlShowPassword->setChecked(false); m_ui->m_checkMysqlShowPassword->setChecked(false);
} }
@ -183,17 +177,13 @@ void SettingsDatabase::loadSettings() {
void SettingsDatabase::saveSettings() { void SettingsDatabase::saveSettings() {
onBeginSaveSettings(); onBeginSaveSettings();
// Setup in-memory database status. // Setup in-memory database status.
const bool original_inmemory = settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool(); const bool original_inmemory = settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool();
const bool new_inmemory = m_ui->m_checkSqliteUseInMemoryDatabase->isChecked(); const bool new_inmemory = m_ui->m_checkSqliteUseInMemoryDatabase->isChecked();
qApp->settings()->setValue(GROUP(Database), Database::UseTransactions, m_ui->m_checkUseTransactions->isChecked()); qApp->settings()->setValue(GROUP(Database), Database::UseTransactions, m_ui->m_checkUseTransactions->isChecked());
// Save data storage settings. // Save data storage settings.
QString original_db_driver = settings()->value(GROUP(Database), SETTING(Database::ActiveDriver)).toString(); 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(); QString selected_db_driver = m_ui->m_cmbDatabaseDriver->itemData(m_ui->m_cmbDatabaseDriver->currentIndex()).toString();
// Save SQLite. // Save SQLite.
settings()->setValue(GROUP(Database), Database::UseInMemory, new_inmemory); settings()->setValue(GROUP(Database), Database::UseInMemory, new_inmemory);

View File

@ -27,11 +27,9 @@
SettingsDownloads::SettingsDownloads(Settings* settings, QWidget* parent) SettingsDownloads::SettingsDownloads(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsDownloads) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsDownloads) {
m_ui->setupUi(this); m_ui->setupUi(this);
connect(m_ui->m_checkOpenManagerWhenDownloadStarts, &QCheckBox::toggled, this, &SettingsDownloads::dirtifySettings); connect(m_ui->m_checkOpenManagerWhenDownloadStarts, &QCheckBox::toggled, this, &SettingsDownloads::dirtifySettings);
connect(m_ui->m_txtDownloadsTargetDirectory, &QLineEdit::textChanged, 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_rbDownloadsAskEachFile, &QRadioButton::toggled, this, &SettingsDownloads::dirtifySettings);
connect(m_ui->m_btnDownloadsTargetDirectory, &QPushButton::clicked, this, &SettingsDownloads::selectDownloadsDirectory); connect(m_ui->m_btnDownloadsTargetDirectory, &QPushButton::clicked, this, &SettingsDownloads::selectDownloadsDirectory);
} }
@ -52,24 +50,20 @@ void SettingsDownloads::selectDownloadsDirectory() {
void SettingsDownloads::loadSettings() { void SettingsDownloads::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
m_ui->m_checkOpenManagerWhenDownloadStarts->setChecked(settings()->value(GROUP(Downloads), m_ui->m_checkOpenManagerWhenDownloadStarts->setChecked(settings()->value(GROUP(Downloads),
SETTING(Downloads::ShowDownloadsWhenNewDownloadStarts)).toBool()); SETTING(Downloads::ShowDownloadsWhenNewDownloadStarts)).toBool());
m_ui->m_txtDownloadsTargetDirectory->setText(QDir::toNativeSeparators(settings()->value(GROUP(Downloads), m_ui->m_txtDownloadsTargetDirectory->setText(QDir::toNativeSeparators(settings()->value(GROUP(Downloads),
SETTING(Downloads::TargetDirectory)).toString())); SETTING(Downloads::TargetDirectory)).toString()));
m_ui->m_rbDownloadsAskEachFile->setChecked(settings()->value(GROUP(Downloads), m_ui->m_rbDownloadsAskEachFile->setChecked(settings()->value(GROUP(Downloads),
SETTING(Downloads::AlwaysPromptForFilename)).toBool()); SETTING(Downloads::AlwaysPromptForFilename)).toBool());
onEndLoadSettings(); onEndLoadSettings();
} }
void SettingsDownloads::saveSettings() { void SettingsDownloads::saveSettings() {
onBeginSaveSettings(); onBeginSaveSettings();
settings()->setValue(GROUP(Downloads), Downloads::ShowDownloadsWhenNewDownloadStarts, m_ui->m_checkOpenManagerWhenDownloadStarts->isChecked()); 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::TargetDirectory, m_ui->m_txtDownloadsTargetDirectory->text());
settings()->setValue(GROUP(Downloads), Downloads::AlwaysPromptForFilename, m_ui->m_rbDownloadsAskEachFile->isChecked()); settings()->setValue(GROUP(Downloads), Downloads::AlwaysPromptForFilename, m_ui->m_rbDownloadsAskEachFile->isChecked());
qApp->downloadManager()->setDownloadDirectory(m_ui->m_txtDownloadsTargetDirectory->text()); qApp->downloadManager()->setDownloadDirectory(m_ui->m_txtDownloadsTargetDirectory->text());
onEndSaveSettings(); onEndSaveSettings();
} }

View File

@ -34,9 +34,7 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings *settings, QWidget *parent
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsFeedsMessages) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsFeedsMessages) {
m_ui->setupUi(this); m_ui->setupUi(this);
initializeMessageDateFormats(); initializeMessageDateFormats();
GuiUtilities::setLabelAsNotice(m_ui->label_9, false); GuiUtilities::setLabelAsNotice(m_ui->label_9, false);
connect(m_ui->m_checkAutoUpdateNotification, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings); connect(m_ui->m_checkAutoUpdateNotification, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_checkAutoUpdate, &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_checkKeppMessagesInTheMiddle, &QCheckBox::toggled, this, &SettingsFeedsMessages::dirtifySettings);
@ -52,7 +50,6 @@ SettingsFeedsMessages::SettingsFeedsMessages(Settings *settings, QWidget *parent
connect(m_ui->m_cmbMessagesDateTimeFormat, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), 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, &QComboBox::currentTextChanged, this, &SettingsFeedsMessages::dirtifySettings);
connect(m_ui->m_cmbCountsFeedList, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), 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); connect(m_ui->m_btnChangeMessagesFont, &QPushButton::clicked, this, &SettingsFeedsMessages::changeMessagesFont);
if (!m_ui->m_spinFeedUpdateTimeout->suffix().startsWith(' ')) { if (!m_ui->m_spinFeedUpdateTimeout->suffix().startsWith(' ')) {
@ -65,7 +62,8 @@ SettingsFeedsMessages::~SettingsFeedsMessages() {
} }
void SettingsFeedsMessages::initializeMessageDateFormats() { void SettingsFeedsMessages::initializeMessageDateFormats() {
QStringList best_formats; best_formats << QSL("d/M/yyyy hh:mm:ss") << QSL("ddd, d. M. yy hh:mm:ss") << 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("yyyy-MM-dd HH:mm:ss.z") << QSL("yyyy-MM-ddThh:mm:ss") <<
QSL("MMM d yyyy hh:mm:ss");; QSL("MMM d yyyy hh:mm:ss");;
const QLocale current_locale = qApp->localization()->loadedLocale(); const QLocale current_locale = qApp->localization()->loadedLocale();
@ -90,7 +88,6 @@ void SettingsFeedsMessages::changeMessagesFont() {
void SettingsFeedsMessages::loadSettings() { void SettingsFeedsMessages::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
m_ui->m_checkAutoUpdateNotification->setChecked(settings()->value(GROUP(Feeds), SETTING(Feeds::EnableAutoUpdateNotification)).toBool()); 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_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_checkRemoveReadMessagesOnExit->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::ClearReadOnExit)).toBool());
@ -101,9 +98,7 @@ void SettingsFeedsMessages::loadSettings() {
m_ui->m_cmbCountsFeedList->addItems(QStringList() << "(%unread)" << "[%unread]" << "%unread/%all" << "%unread-%all" << "[%unread|%all]"); 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_cmbCountsFeedList->setEditText(settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString());
m_ui->m_spinHeightImageAttachments->setValue(settings()->value(GROUP(Messages), SETTING(Messages::MessageHeadImageHeight)).toInt()); m_ui->m_spinHeightImageAttachments->setValue(settings()->value(GROUP(Messages), SETTING(Messages::MessageHeadImageHeight)).toInt());
initializeMessageDateFormats(); initializeMessageDateFormats();
m_ui->m_checkMessagesDateTimeFormat->setChecked(settings()->value(GROUP(Messages), SETTING(Messages::UseCustomDate)).toBool()); 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()); const int index_format = m_ui->m_cmbMessagesDateTimeFormat->findData(settings()->value(GROUP(Messages), SETTING(Messages::CustomDateFormat)).toString());
@ -116,13 +111,11 @@ void SettingsFeedsMessages::loadSettings() {
fon.fromString(settings()->value(GROUP(Messages), fon.fromString(settings()->value(GROUP(Messages),
SETTING(Messages::PreviewerFontStandard)).toString()); SETTING(Messages::PreviewerFontStandard)).toString());
m_ui->m_lblMessagesFont->setFont(fon); m_ui->m_lblMessagesFont->setFont(fon);
onEndLoadSettings(); onEndLoadSettings();
} }
void SettingsFeedsMessages::saveSettings() { void SettingsFeedsMessages::saveSettings() {
onBeginSaveSettings(); onBeginSaveSettings();
settings()->setValue(GROUP(Feeds), Feeds::EnableAutoUpdateNotification, m_ui->m_checkAutoUpdateNotification->isChecked()); 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::KeepCursorInCenter, m_ui->m_checkKeppMessagesInTheMiddle->isChecked());
settings()->setValue(GROUP(Messages), Messages::ClearReadOnExit, m_ui->m_checkRemoveReadMessagesOnExit->isChecked()); settings()->setValue(GROUP(Messages), Messages::ClearReadOnExit, m_ui->m_checkRemoveReadMessagesOnExit->isChecked());
@ -135,16 +128,12 @@ void SettingsFeedsMessages::saveSettings() {
settings()->setValue(GROUP(Messages), Messages::MessageHeadImageHeight, m_ui->m_spinHeightImageAttachments->value()); settings()->setValue(GROUP(Messages), Messages::MessageHeadImageHeight, m_ui->m_spinHeightImageAttachments->value());
settings()->setValue(GROUP(Messages), Messages::CustomDateFormat, settings()->setValue(GROUP(Messages), Messages::CustomDateFormat,
m_ui->m_cmbMessagesDateTimeFormat->itemData(m_ui->m_cmbMessagesDateTimeFormat->currentIndex()).toString()); m_ui->m_cmbMessagesDateTimeFormat->itemData(m_ui->m_cmbMessagesDateTimeFormat->currentIndex()).toString());
// Save fonts. // Save fonts.
settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, m_ui->m_lblMessagesFont->font().toString()); settings()->setValue(GROUP(Messages), Messages::PreviewerFontStandard, m_ui->m_lblMessagesFont->font().toString());
qApp->mainForm()->tabWidget()->feedMessageViewer()->loadMessageViewerFonts(); qApp->mainForm()->tabWidget()->feedMessageViewer()->loadMessageViewerFonts();
qApp->feedReader()->updateAutoUpdateStatus(); qApp->feedReader()->updateAutoUpdateStatus();
qApp->feedReader()->feedsModel()->reloadWholeLayout(); qApp->feedReader()->feedsModel()->reloadWholeLayout();
qApp->feedReader()->messagesModel()->updateDateFormat(); qApp->feedReader()->messagesModel()->updateDateFormat();
qApp->feedReader()->messagesModel()->reloadWholeLayout(); qApp->feedReader()->messagesModel()->reloadWholeLayout();
onEndSaveSettings(); onEndSaveSettings();
} }

View File

@ -25,7 +25,6 @@ SettingsGeneral::SettingsGeneral(Settings *settings, QWidget *parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsGeneral) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsGeneral) {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->m_checkAutostart->setText(m_ui->m_checkAutostart->text().arg(APP_NAME)); 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_checkAutostart, &QCheckBox::stateChanged, this, &SettingsGeneral::dirtifySettings);
connect(m_ui->m_checkForUpdatesOnStart, &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); connect(m_ui->m_checkRemoveTrolltechJunk, &QCheckBox::stateChanged, this, &SettingsGeneral::dirtifySettings);
@ -37,9 +36,7 @@ SettingsGeneral::~SettingsGeneral() {
void SettingsGeneral::loadSettings() { void SettingsGeneral::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
m_ui->m_checkForUpdatesOnStart->setChecked(settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool()); m_ui->m_checkForUpdatesOnStart->setChecked(settings()->value(GROUP(General), SETTING(General::UpdateOnStartup)).toBool());
// Load auto-start status. // Load auto-start status.
const SystemFactory::AutoStartStatus autostart_status = qApp->system()->getAutoStartStatus(); const SystemFactory::AutoStartStatus autostart_status = qApp->system()->getAutoStartStatus();
@ -64,7 +61,6 @@ void SettingsGeneral::loadSettings() {
#else #else
m_ui->m_checkRemoveTrolltechJunk->setVisible(false); m_ui->m_checkRemoveTrolltechJunk->setVisible(false);
#endif #endif
onEndLoadSettings(); onEndLoadSettings();
} }
@ -75,12 +71,12 @@ void SettingsGeneral::saveSettings() {
if (m_ui->m_checkAutostart->isChecked()) { if (m_ui->m_checkAutostart->isChecked()) {
qApp->system()->setAutoStartStatus(SystemFactory::Enabled); qApp->system()->setAutoStartStatus(SystemFactory::Enabled);
} }
else { else {
qApp->system()->setAutoStartStatus(SystemFactory::Disabled); qApp->system()->setAutoStartStatus(SystemFactory::Disabled);
} }
settings()->setValue(GROUP(General), General::UpdateOnStartup, m_ui->m_checkForUpdatesOnStart->isChecked()); settings()->setValue(GROUP(General), General::UpdateOnStartup, m_ui->m_checkForUpdatesOnStart->isChecked());
settings()->setValue(GROUP(General), General::RemoveTrolltechJunk, m_ui->m_checkRemoveTrolltechJunk->isChecked()); settings()->setValue(GROUP(General), General::RemoveTrolltechJunk, m_ui->m_checkRemoveTrolltechJunk->isChecked());
onEndSaveSettings(); onEndSaveSettings();
} }

View File

@ -34,12 +34,10 @@
SettingsGui::SettingsGui(Settings* settings, QWidget* parent) : SettingsPanel(settings, parent), m_ui(new Ui::SettingsGui) { SettingsGui::SettingsGui(Settings* settings, QWidget* parent) : SettingsPanel(settings, parent), m_ui(new Ui::SettingsGui) {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->m_editorMessagesToolbar->activeItemsWidget()->viewport()->installEventFilter(this); m_ui->m_editorMessagesToolbar->activeItemsWidget()->viewport()->installEventFilter(this);
m_ui->m_editorFeedsToolbar->activeItemsWidget()->viewport()->installEventFilter(this); m_ui->m_editorFeedsToolbar->activeItemsWidget()->viewport()->installEventFilter(this);
m_ui->m_editorMessagesToolbar->availableItemsWidget()->viewport()->installEventFilter(this); m_ui->m_editorMessagesToolbar->availableItemsWidget()->viewport()->installEventFilter(this);
m_ui->m_editorFeedsToolbar->availableItemsWidget()->viewport()->installEventFilter(this); m_ui->m_editorFeedsToolbar->availableItemsWidget()->viewport()->installEventFilter(this);
m_ui->m_treeSkins->setColumnCount(4); m_ui->m_treeSkins->setColumnCount(4);
m_ui->m_treeSkins->setHeaderHidden(false); m_ui->m_treeSkins->setHeaderHidden(false);
m_ui->m_treeSkins->setHeaderLabels(QStringList() m_ui->m_treeSkins->setHeaderLabels(QStringList()
@ -47,13 +45,11 @@ SettingsGui::SettingsGui(Settings *settings, QWidget *parent) : SettingsPanel(se
<< /*: Version column of skin list. */ tr("Version") << /*: Version column of skin list. */ tr("Version")
<< tr("Author") << tr("Author")
<< tr("E-mail")); << tr("E-mail"));
// Setup skins. // Setup skins.
m_ui->m_treeSkins->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); m_ui->m_treeSkins->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
m_ui->m_treeSkins->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); m_ui->m_treeSkins->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
m_ui->m_treeSkins->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); m_ui->m_treeSkins->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
m_ui->m_treeSkins->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); m_ui->m_treeSkins->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
connect(m_ui->m_cmbIconTheme, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsGui::requireRestart); connect(m_ui->m_cmbIconTheme, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsGui::requireRestart);
connect(m_ui->m_cmbIconTheme, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsGui::dirtifySettings); connect(m_ui->m_cmbIconTheme, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &SettingsGui::dirtifySettings);
connect(m_ui->m_treeSkins, &QTreeWidget::currentItemChanged, this, &SettingsGui::dirtifySettings); connect(m_ui->m_treeSkins, &QTreeWidget::currentItemChanged, this, &SettingsGui::dirtifySettings);
@ -71,7 +67,6 @@ SettingsGui::SettingsGui(Settings *settings, QWidget *parent) : SettingsPanel(se
connect(m_ui->m_editorMessagesToolbar, &ToolBarEditor::setupChanged, this, &SettingsGui::dirtifySettings); connect(m_ui->m_editorMessagesToolbar, &ToolBarEditor::setupChanged, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_editorStatusbar, &ToolBarEditor::setupChanged, this, &SettingsGui::dirtifySettings); connect(m_ui->m_editorStatusbar, &ToolBarEditor::setupChanged, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_listStyles, &QListWidget::currentItemChanged, this, &SettingsGui::dirtifySettings); connect(m_ui->m_listStyles, &QListWidget::currentItemChanged, this, &SettingsGui::dirtifySettings);
connect(m_ui->m_cmbSelectToolBar, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), m_ui->m_stackedToolbars, &QStackedWidget::setCurrentIndex); connect(m_ui->m_cmbSelectToolBar, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), m_ui->m_stackedToolbars, &QStackedWidget::setCurrentIndex);
} }
@ -101,6 +96,7 @@ void SettingsGui::loadSettings() {
if (SystemTrayIcon::isSystemTrayAvailable()) { if (SystemTrayIcon::isSystemTrayAvailable()) {
m_ui->m_grpTray->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::UseTrayIcon)).toBool()); m_ui->m_grpTray->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::UseTrayIcon)).toBool());
} }
// Tray icon is not supported on this machine. // Tray icon is not supported on this machine.
else { else {
m_ui->m_grpTray->setTitle(m_ui->m_grpTray->title() + QL1C(' ') + tr("(Tray icon is not available.)")); m_ui->m_grpTray->setTitle(m_ui->m_grpTray->title() + QL1C(' ') + tr("(Tray icon is not available.)"));
@ -109,10 +105,8 @@ void SettingsGui::loadSettings() {
m_ui->m_checkHidden->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::MainWindowStartsHidden)).toBool()); m_ui->m_checkHidden->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::MainWindowStartsHidden)).toBool());
m_ui->m_checkHideWhenMinimized->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::HideMainWindowWhenMinimized)).toBool()); m_ui->m_checkHideWhenMinimized->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::HideMainWindowWhenMinimized)).toBool());
// Load fancy notification settings. // Load fancy notification settings.
m_ui->m_checkEnableNotifications->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::EnableNotifications)).toBool()); m_ui->m_checkEnableNotifications->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::EnableNotifications)).toBool());
// Load settings of icon theme. // Load settings of icon theme.
const QString current_theme = qApp->icons()->currentIconTheme(); const QString current_theme = qApp->icons()->currentIconTheme();
@ -122,6 +116,7 @@ void SettingsGui::loadSettings() {
//: Label for disabling icon theme. //: Label for disabling icon theme.
m_ui->m_cmbIconTheme->addItem(tr("no icon theme/system icon theme"), APP_NO_THEME); m_ui->m_cmbIconTheme->addItem(tr("no icon theme/system icon theme"), APP_NO_THEME);
} }
else { else {
m_ui->m_cmbIconTheme->addItem(icon_theme_name, icon_theme_name); m_ui->m_cmbIconTheme->addItem(icon_theme_name, icon_theme_name);
} }
@ -132,6 +127,7 @@ void SettingsGui::loadSettings() {
// Because "no icon theme" lies at the index 0. // Because "no icon theme" lies at the index 0.
m_ui->m_cmbIconTheme->setCurrentIndex(0); m_ui->m_cmbIconTheme->setCurrentIndex(0);
} }
else { else {
m_ui->m_cmbIconTheme->setCurrentText(current_theme); m_ui->m_cmbIconTheme->setCurrentText(current_theme);
} }
@ -146,7 +142,6 @@ void SettingsGui::loadSettings() {
skin.m_author << skin.m_author <<
skin.m_email); skin.m_email);
new_item->setData(0, Qt::UserRole, QVariant::fromValue(skin)); new_item->setData(0, Qt::UserRole, QVariant::fromValue(skin));
// Add this skin and mark it as active if its active now. // Add this skin and mark it as active if its active now.
m_ui->m_treeSkins->addTopLevelItem(new_item); m_ui->m_treeSkins->addTopLevelItem(new_item);
@ -179,28 +174,23 @@ void SettingsGui::loadSettings() {
m_ui->m_checkCloseTabsDoubleClick->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::TabCloseDoubleClick)).toBool()); m_ui->m_checkCloseTabsDoubleClick->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::TabCloseDoubleClick)).toBool());
m_ui->m_checkNewTabDoubleClick->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::TabNewDoubleClick)).toBool()); m_ui->m_checkNewTabDoubleClick->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::TabNewDoubleClick)).toBool());
m_ui->m_checkHideTabBarIfOneTabVisible->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::HideTabBarIfOnlyOneTab)).toBool()); m_ui->m_checkHideTabBarIfOneTabVisible->setChecked(settings()->value(GROUP(GUI), SETTING(GUI::HideTabBarIfOnlyOneTab)).toBool());
// Load toolbar button style. // Load toolbar button style.
m_ui->m_cmbToolbarButtonStyle->addItem(tr("Icon only"), Qt::ToolButtonIconOnly); m_ui->m_cmbToolbarButtonStyle->addItem(tr("Icon only"), Qt::ToolButtonIconOnly);
m_ui->m_cmbToolbarButtonStyle->addItem(tr("Text only"), Qt::ToolButtonTextOnly); m_ui->m_cmbToolbarButtonStyle->addItem(tr("Text only"), Qt::ToolButtonTextOnly);
m_ui->m_cmbToolbarButtonStyle->addItem(tr("Text beside icon"), Qt::ToolButtonTextBesideIcon); m_ui->m_cmbToolbarButtonStyle->addItem(tr("Text beside icon"), Qt::ToolButtonTextBesideIcon);
m_ui->m_cmbToolbarButtonStyle->addItem(tr("Text under icon"), Qt::ToolButtonTextUnderIcon); m_ui->m_cmbToolbarButtonStyle->addItem(tr("Text under icon"), Qt::ToolButtonTextUnderIcon);
m_ui->m_cmbToolbarButtonStyle->addItem(tr("Follow OS style"), Qt::ToolButtonFollowStyle); m_ui->m_cmbToolbarButtonStyle->addItem(tr("Follow OS style"), Qt::ToolButtonFollowStyle);
m_ui->m_cmbToolbarButtonStyle->setCurrentIndex(m_ui->m_cmbToolbarButtonStyle->findData(settings()->value(GROUP(GUI), m_ui->m_cmbToolbarButtonStyle->setCurrentIndex(m_ui->m_cmbToolbarButtonStyle->findData(settings()->value(GROUP(GUI),
SETTING(GUI::ToolbarStyle)).toInt())); SETTING(GUI::ToolbarStyle)).toInt()));
// Load toolbars. // Load toolbars.
m_ui->m_editorFeedsToolbar->loadFromToolBar(qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsToolBar()); m_ui->m_editorFeedsToolbar->loadFromToolBar(qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsToolBar());
m_ui->m_editorMessagesToolbar->loadFromToolBar(qApp->mainForm()->tabWidget()->feedMessageViewer()->messagesToolBar()); m_ui->m_editorMessagesToolbar->loadFromToolBar(qApp->mainForm()->tabWidget()->feedMessageViewer()->messagesToolBar());
m_ui->m_editorStatusbar->loadFromToolBar(qApp->mainForm()->statusBar()); m_ui->m_editorStatusbar->loadFromToolBar(qApp->mainForm()->statusBar());
onEndLoadSettings(); onEndLoadSettings();
} }
void SettingsGui::saveSettings() { void SettingsGui::saveSettings() {
onBeginSaveSettings(); onBeginSaveSettings();
// Save toolbar. // Save toolbar.
settings()->setValue(GROUP(GUI), GUI::ToolbarStyle, m_ui->m_cmbToolbarButtonStyle->itemData(m_ui->m_cmbToolbarButtonStyle->currentIndex())); settings()->setValue(GROUP(GUI), GUI::ToolbarStyle, m_ui->m_cmbToolbarButtonStyle->itemData(m_ui->m_cmbToolbarButtonStyle->currentIndex()));
@ -211,6 +201,7 @@ void SettingsGui::saveSettings() {
if (m_ui->m_grpTray->isChecked()) { if (m_ui->m_grpTray->isChecked()) {
qApp->showTrayIcon(); qApp->showTrayIcon();
} }
else { else {
qApp->deleteTrayIcon(); qApp->deleteTrayIcon();
} }
@ -218,10 +209,8 @@ void SettingsGui::saveSettings() {
settings()->setValue(GROUP(GUI), GUI::MainWindowStartsHidden, m_ui->m_checkHidden->isChecked()); settings()->setValue(GROUP(GUI), GUI::MainWindowStartsHidden, m_ui->m_checkHidden->isChecked());
settings()->setValue(GROUP(GUI), GUI::HideMainWindowWhenMinimized, m_ui->m_checkHideWhenMinimized->isChecked()); settings()->setValue(GROUP(GUI), GUI::HideMainWindowWhenMinimized, m_ui->m_checkHideWhenMinimized->isChecked());
// Save notifications. // Save notifications.
settings()->setValue(GROUP(GUI), GUI::EnableNotifications, m_ui->m_checkEnableNotifications->isChecked()); settings()->setValue(GROUP(GUI), GUI::EnableNotifications, m_ui->m_checkEnableNotifications->isChecked());
// Save selected icon theme. // Save selected icon theme.
QString selected_icon_theme = m_ui->m_cmbIconTheme->itemData(m_ui->m_cmbIconTheme->currentIndex()).toString(); QString selected_icon_theme = m_ui->m_cmbIconTheme->itemData(m_ui->m_cmbIconTheme->currentIndex()).toString();
QString original_icon_theme = qApp->icons()->currentIconTheme(); QString original_icon_theme = qApp->icons()->currentIconTheme();
@ -259,13 +248,10 @@ void SettingsGui::saveSettings() {
settings()->setValue(GROUP(GUI), GUI::TabCloseDoubleClick, m_ui->m_checkCloseTabsDoubleClick->isChecked()); settings()->setValue(GROUP(GUI), GUI::TabCloseDoubleClick, m_ui->m_checkCloseTabsDoubleClick->isChecked());
settings()->setValue(GROUP(GUI), GUI::TabNewDoubleClick, m_ui->m_checkNewTabDoubleClick->isChecked()); settings()->setValue(GROUP(GUI), GUI::TabNewDoubleClick, m_ui->m_checkNewTabDoubleClick->isChecked());
settings()->setValue(GROUP(GUI), GUI::HideTabBarIfOnlyOneTab, m_ui->m_checkHideTabBarIfOneTabVisible->isChecked()); settings()->setValue(GROUP(GUI), GUI::HideTabBarIfOnlyOneTab, m_ui->m_checkHideTabBarIfOneTabVisible->isChecked());
m_ui->m_editorFeedsToolbar->saveToolBar(); m_ui->m_editorFeedsToolbar->saveToolBar();
m_ui->m_editorMessagesToolbar->saveToolBar(); m_ui->m_editorMessagesToolbar->saveToolBar();
m_ui->m_editorStatusbar->saveToolBar(); m_ui->m_editorStatusbar->saveToolBar();
qApp->mainForm()->tabWidget()->checkTabBarVisibility(); qApp->mainForm()->tabWidget()->checkTabBarVisibility();
qApp->mainForm()->tabWidget()->feedMessageViewer()->refreshVisualProperties(); qApp->mainForm()->tabWidget()->feedMessageViewer()->refreshVisualProperties();
onEndSaveSettings(); onEndSaveSettings();
} }

View File

@ -26,19 +26,16 @@
SettingsLocalization::SettingsLocalization(Settings* settings, QWidget* parent) SettingsLocalization::SettingsLocalization(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsLocalization) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsLocalization) {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->m_treeLanguages->setColumnCount(3); m_ui->m_treeLanguages->setColumnCount(3);
m_ui->m_treeLanguages->setHeaderHidden(false); m_ui->m_treeLanguages->setHeaderHidden(false);
m_ui->m_treeLanguages->setHeaderLabels(QStringList() m_ui->m_treeLanguages->setHeaderLabels(QStringList()
<< /*: Language column of language list. */ tr("Language") << /*: Language column of language list. */ tr("Language")
<< /*: Lang. code column of language list. */ tr("Code") << /*: Lang. code column of language list. */ tr("Code")
<< tr("Author")); << tr("Author"));
// Setup languages. // Setup languages.
m_ui->m_treeLanguages->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); m_ui->m_treeLanguages->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
m_ui->m_treeLanguages->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); m_ui->m_treeLanguages->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
m_ui->m_treeLanguages->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); m_ui->m_treeLanguages->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
connect(m_ui->m_treeLanguages, &QTreeWidget::currentItemChanged, this, &SettingsLocalization::requireRestart); connect(m_ui->m_treeLanguages, &QTreeWidget::currentItemChanged, this, &SettingsLocalization::requireRestart);
connect(m_ui->m_treeLanguages, &QTreeWidget::currentItemChanged, this, &SettingsLocalization::dirtifySettings); connect(m_ui->m_treeLanguages, &QTreeWidget::currentItemChanged, this, &SettingsLocalization::dirtifySettings);
} }
@ -59,7 +56,6 @@ void SettingsLocalization::loadSettings() {
} }
m_ui->m_treeLanguages->sortByColumn(0, Qt::AscendingOrder); m_ui->m_treeLanguages->sortByColumn(0, Qt::AscendingOrder);
QList<QTreeWidgetItem*> matching_items = m_ui->m_treeLanguages->findItems(qApp->localization()->loadedLanguage(), Qt::MatchContains, 1); QList<QTreeWidgetItem*> matching_items = m_ui->m_treeLanguages->findItems(qApp->localization()->loadedLanguage(), Qt::MatchContains, 1);
if (!matching_items.isEmpty()) { if (!matching_items.isEmpty()) {

View File

@ -30,7 +30,6 @@ void SettingsPanel::onBeginLoadSettings() {
void SettingsPanel::onEndLoadSettings() { void SettingsPanel::onEndLoadSettings() {
m_isLoading = false; m_isLoading = false;
setRequiresRestart(false); setRequiresRestart(false);
setIsDirty(false); setIsDirty(false);
} }

View File

@ -24,7 +24,6 @@
SettingsShortcuts::SettingsShortcuts(Settings* settings, QWidget* parent) SettingsShortcuts::SettingsShortcuts(Settings* settings, QWidget* parent)
: SettingsPanel(settings, parent), m_ui(new Ui::SettingsShortcuts) { : SettingsPanel(settings, parent), m_ui(new Ui::SettingsShortcuts) {
m_ui->setupUi(this); m_ui->setupUi(this);
connect(m_ui->m_shortcuts, &DynamicShortcutsWidget::setupChanged, this, &SettingsShortcuts::dirtifySettings); connect(m_ui->m_shortcuts, &DynamicShortcutsWidget::setupChanged, this, &SettingsShortcuts::dirtifySettings);
} }
@ -34,17 +33,13 @@ SettingsShortcuts::~SettingsShortcuts() {
void SettingsShortcuts::loadSettings() { void SettingsShortcuts::loadSettings() {
onBeginLoadSettings(); onBeginLoadSettings();
m_ui->m_shortcuts->populate(qApp->userActions()); m_ui->m_shortcuts->populate(qApp->userActions());
onEndLoadSettings(); onEndLoadSettings();
} }
void SettingsShortcuts::saveSettings() { void SettingsShortcuts::saveSettings() {
onBeginSaveSettings(); onBeginSaveSettings();
m_ui->m_shortcuts->updateShortcuts(); m_ui->m_shortcuts->updateShortcuts();
DynamicShortcuts::save(qApp->userActions()); DynamicShortcuts::save(qApp->userActions());
onEndSaveSettings(); onEndSaveSettings();
} }

View File

@ -31,42 +31,33 @@
StatusBar::StatusBar(QWidget* parent) : QStatusBar(parent), m_mutex(new Mutex(QMutex::NonRecursive, this)) { StatusBar::StatusBar(QWidget* parent) : QStatusBar(parent), m_mutex(new Mutex(QMutex::NonRecursive, this)) {
setSizeGripEnabled(false); setSizeGripEnabled(false);
setContentsMargins(2, 0, 2, 2); setContentsMargins(2, 0, 2, 2);
m_barProgressFeeds = new QProgressBar(this); m_barProgressFeeds = new QProgressBar(this);
m_barProgressFeeds->setTextVisible(false); m_barProgressFeeds->setTextVisible(false);
m_barProgressFeeds->setFixedWidth(100); m_barProgressFeeds->setFixedWidth(100);
m_barProgressFeeds->setVisible(false); m_barProgressFeeds->setVisible(false);
m_barProgressFeeds->setObjectName(QSL("m_barProgressFeeds")); m_barProgressFeeds->setObjectName(QSL("m_barProgressFeeds"));
m_barProgressFeedsAction = new QAction(qApp->icons()->fromTheme(QSL("application-rss+xml")), tr("Feed update progress bar"), this); m_barProgressFeedsAction = new QAction(qApp->icons()->fromTheme(QSL("application-rss+xml")), tr("Feed update progress bar"), this);
m_barProgressFeedsAction->setObjectName(QSL("m_barProgressFeedsAction")); m_barProgressFeedsAction->setObjectName(QSL("m_barProgressFeedsAction"));
m_lblProgressFeeds = new QLabel(this); m_lblProgressFeeds = new QLabel(this);
m_lblProgressFeeds->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); m_lblProgressFeeds->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_lblProgressFeeds->setVisible(false); m_lblProgressFeeds->setVisible(false);
m_lblProgressFeeds->setObjectName(QSL("m_lblProgressFeeds")); m_lblProgressFeeds->setObjectName(QSL("m_lblProgressFeeds"));
m_lblProgressFeedsAction = new QAction(qApp->icons()->fromTheme(QSL("application-rss+xml")), tr("Feed update label"), this); m_lblProgressFeedsAction = new QAction(qApp->icons()->fromTheme(QSL("application-rss+xml")), tr("Feed update label"), this);
m_lblProgressFeedsAction->setObjectName(QSL("m_lblProgressFeedsAction")); m_lblProgressFeedsAction->setObjectName(QSL("m_lblProgressFeedsAction"));
m_barProgressDownload = new QProgressBar(this); m_barProgressDownload = new QProgressBar(this);
m_barProgressDownload->setTextVisible(true); m_barProgressDownload->setTextVisible(true);
m_barProgressDownload->setFixedWidth(100); m_barProgressDownload->setFixedWidth(100);
m_barProgressDownload->setVisible(false); m_barProgressDownload->setVisible(false);
m_barProgressDownload->setObjectName(QSL("m_barProgressDownload")); m_barProgressDownload->setObjectName(QSL("m_barProgressDownload"));
m_barProgressDownloadAction = new QAction(qApp->icons()->fromTheme(QSL("emblem-downloads")), tr("File download progress bar"), this); m_barProgressDownloadAction = new QAction(qApp->icons()->fromTheme(QSL("emblem-downloads")), tr("File download progress bar"), this);
m_barProgressDownloadAction->setObjectName(QSL("m_barProgressDownloadAction")); m_barProgressDownloadAction->setObjectName(QSL("m_barProgressDownloadAction"));
m_lblProgressDownload = new QLabel(this); m_lblProgressDownload = new QLabel(this);
m_lblProgressDownload->setText("Downloading files in background"); m_lblProgressDownload->setText("Downloading files in background");
m_lblProgressDownload->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); m_lblProgressDownload->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_lblProgressDownload->setVisible(false); m_lblProgressDownload->setVisible(false);
m_lblProgressDownload->setObjectName(QSL("m_lblProgressDownload")); m_lblProgressDownload->setObjectName(QSL("m_lblProgressDownload"));
m_lblProgressDownloadAction = new QAction(qApp->icons()->fromTheme(QSL("emblem-downloads")), tr("File download label"), this); m_lblProgressDownloadAction = new QAction(qApp->icons()->fromTheme(QSL("emblem-downloads")), tr("File download label"), this);
m_lblProgressDownloadAction->setObjectName(QSL("m_lblProgressDownloadAction")); m_lblProgressDownloadAction->setObjectName(QSL("m_lblProgressDownloadAction"));
m_lblProgressDownload->installEventFilter(this); m_lblProgressDownload->installEventFilter(this);
m_barProgressDownload->installEventFilter(this); m_barProgressDownload->installEventFilter(this);
} }
@ -78,11 +69,9 @@ StatusBar::~StatusBar() {
QList<QAction*> StatusBar::availableActions() const { QList<QAction*> StatusBar::availableActions() const {
QList<QAction*> actions = qApp->userActions(); QList<QAction*> actions = qApp->userActions();
// Now, add placeholder actions for custom stuff. // Now, add placeholder actions for custom stuff.
actions << m_barProgressDownloadAction << m_barProgressFeedsAction << actions << m_barProgressDownloadAction << m_barProgressFeedsAction <<
m_lblProgressDownloadAction << m_lblProgressFeedsAction; m_lblProgressDownloadAction << m_lblProgressFeedsAction;
return actions; return actions;
} }
@ -92,7 +81,6 @@ QList<QAction*> StatusBar::changeableActions() const {
void StatusBar::saveChangeableActions(const QStringList& actions) { void StatusBar::saveChangeableActions(const QStringList& actions) {
QMutexLocker locker(*m_mutex); QMutexLocker locker(*m_mutex);
qApp->settings()->setValue(GROUP(GUI), GUI::StatusbarActions, actions.join(QSL(","))); qApp->settings()->setValue(GROUP(GUI), GUI::StatusbarActions, actions.join(QSL(",")));
loadSpecificActions(getSpecificActions(actions)); loadSpecificActions(getSpecificActions(actions));
} }
@ -121,57 +109,56 @@ QList<QAction*> StatusBar::getSpecificActions(const QStringList &actions) {
if (matching_action == m_barProgressDownloadAction) { if (matching_action == m_barProgressDownloadAction) {
widget_to_add = m_barProgressDownload; widget_to_add = m_barProgressDownload;
action_to_add = m_barProgressDownloadAction; action_to_add = m_barProgressDownloadAction;
widget_to_add->setVisible(false); widget_to_add->setVisible(false);
} }
else if (matching_action == m_barProgressFeedsAction) { else if (matching_action == m_barProgressFeedsAction) {
widget_to_add = m_barProgressFeeds; widget_to_add = m_barProgressFeeds;
action_to_add = m_barProgressFeedsAction; action_to_add = m_barProgressFeedsAction;
widget_to_add->setVisible(progress_visible); widget_to_add->setVisible(progress_visible);
} }
else if (matching_action == m_lblProgressDownloadAction) { else if (matching_action == m_lblProgressDownloadAction) {
widget_to_add = m_lblProgressDownload; widget_to_add = m_lblProgressDownload;
action_to_add = m_lblProgressDownloadAction; action_to_add = m_lblProgressDownloadAction;
widget_to_add->setVisible(false); widget_to_add->setVisible(false);
} }
else if (matching_action == m_lblProgressFeedsAction) { else if (matching_action == m_lblProgressFeedsAction) {
widget_to_add = m_lblProgressFeeds; widget_to_add = m_lblProgressFeeds;
action_to_add = m_lblProgressFeedsAction; action_to_add = m_lblProgressFeedsAction;
widget_to_add->setVisible(progress_visible); widget_to_add->setVisible(progress_visible);
} }
else { else {
if (action_name == SEPARATOR_ACTION_NAME) { if (action_name == SEPARATOR_ACTION_NAME) {
QLabel* lbl = new QLabel(QString::fromUtf8("")); QLabel* lbl = new QLabel(QString::fromUtf8(""));
widget_to_add = lbl; widget_to_add = lbl;
action_to_add = new QAction(this); action_to_add = new QAction(this);
action_to_add->setSeparator(true); action_to_add->setSeparator(true);
action_to_add->setProperty("should_remove_action", true); action_to_add->setProperty("should_remove_action", true);
} }
else if (action_name == SPACER_ACTION_NAME) { else if (action_name == SPACER_ACTION_NAME) {
QLabel* lbl = new QLabel(QSL("\t\t")); QLabel* lbl = new QLabel(QSL("\t\t"));
widget_to_add = lbl; widget_to_add = lbl;
action_to_add = new QAction(this); action_to_add = new QAction(this);
action_to_add->setProperty("should_remove_action", true); action_to_add->setProperty("should_remove_action", true);
action_to_add->setIcon(qApp->icons()->fromTheme(QSL("system-search"))); action_to_add->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
action_to_add->setProperty("type", SPACER_ACTION_NAME); action_to_add->setProperty("type", SPACER_ACTION_NAME);
action_to_add->setProperty("name", tr("Toolbar spacer")); action_to_add->setProperty("name", tr("Toolbar spacer"));
} }
else if (matching_action != nullptr) { else if (matching_action != nullptr) {
// Add originally toolbar action. // Add originally toolbar action.
PlainToolButton* tool_button = new PlainToolButton(this); PlainToolButton* tool_button = new PlainToolButton(this);
tool_button->reactOnActionChange(matching_action); tool_button->reactOnActionChange(matching_action);
widget_to_add = tool_button; widget_to_add = tool_button;
action_to_add = matching_action; action_to_add = matching_action;
connect(tool_button, &PlainToolButton::clicked, matching_action, &QAction::trigger); connect(tool_button, &PlainToolButton::clicked, matching_action, &QAction::trigger);
connect(matching_action, &QAction::changed, tool_button, &PlainToolButton::reactOnSenderActionChange); connect(matching_action, &QAction::changed, tool_button, &PlainToolButton::reactOnSenderActionChange);
} }
else { else {
action_to_add = nullptr; action_to_add = nullptr;
widget_to_add = nullptr; widget_to_add = nullptr;
@ -208,7 +195,6 @@ void StatusBar::loadSpecificActions(const QList<QAction*> &actions) {
foreach (QAction* act, actions) { foreach (QAction* act, actions) {
QWidget* widget = act->property("widget").isValid() ? static_cast<QWidget*>(act->property("widget").value<void*>()) : nullptr; QWidget* widget = act->property("widget").isValid() ? static_cast<QWidget*>(act->property("widget").value<void*>()) : nullptr;
addAction(act); addAction(act);
// And also add widget. // And also add widget.
@ -234,7 +220,6 @@ void StatusBar::clear() {
QWidget* widget = act->property("widget").isValid() ? static_cast<QWidget*>(act->property("widget").value<void*>()) : nullptr; QWidget* widget = act->property("widget").isValid() ? static_cast<QWidget*>(act->property("widget").value<void*>()) : nullptr;
bool should_remove_widget = act->property("should_remove_widget").isValid(); bool should_remove_widget = act->property("should_remove_widget").isValid();
bool should_remove_action = act->property("should_remove_action").isValid(); bool should_remove_action = act->property("should_remove_action").isValid();
removeAction(act); removeAction(act);
if (widget != nullptr) { if (widget != nullptr) {
@ -256,7 +241,6 @@ void StatusBar::showProgressFeeds(int progress, const QString &label) {
if (actions().contains(m_barProgressFeedsAction)) { if (actions().contains(m_barProgressFeedsAction)) {
m_lblProgressFeeds->setVisible(true); m_lblProgressFeeds->setVisible(true);
m_barProgressFeeds->setVisible(true); m_barProgressFeeds->setVisible(true);
m_lblProgressFeeds->setText(label); m_lblProgressFeeds->setText(label);
m_barProgressFeeds->setValue(progress); m_barProgressFeeds->setValue(progress);
} }

View File

@ -54,13 +54,10 @@ SystemTrayIcon::SystemTrayIcon(const QString &normal_icon, const QString &plain_
m_bubbleClickTarget(nullptr), m_bubbleClickTarget(nullptr),
m_bubbleClickSlot(nullptr) { m_bubbleClickSlot(nullptr) {
qDebug("Creating SystemTrayIcon instance."); qDebug("Creating SystemTrayIcon instance.");
m_font.setBold(true); m_font.setBold(true);
// Initialize icon. // Initialize icon.
setNumber(); setNumber();
setContextMenu(parent->trayMenu()); setContextMenu(parent->trayMenu());
// Create necessary connections. // Create necessary connections.
connect(this, &SystemTrayIcon::activated, this, &SystemTrayIcon::onActivated); connect(this, &SystemTrayIcon::activated, this, &SystemTrayIcon::onActivated);
} }
@ -100,7 +97,6 @@ void SystemTrayIcon::showPrivate() {
// the settings window) gets closed. Behavior for main window // the settings window) gets closed. Behavior for main window
// is handled explicitly by FormMain::closeEvent() method. // is handled explicitly by FormMain::closeEvent() method.
qApp->setQuitOnLastWindowClosed(false); qApp->setQuitOnLastWindowClosed(false);
// Display the tray icon. // Display the tray icon.
QSystemTrayIcon::show(); QSystemTrayIcon::show();
emit shown(); emit shown();
@ -124,12 +120,11 @@ void SystemTrayIcon::setNumber(int number, bool any_new_message) {
setToolTip(QSL(APP_LONG_NAME)); setToolTip(QSL(APP_LONG_NAME));
QSystemTrayIcon::setIcon(QIcon(m_normalIcon)); QSystemTrayIcon::setIcon(QIcon(m_normalIcon));
} }
else { else {
setToolTip(tr("%1\nUnread news: %2").arg(QSL(APP_LONG_NAME), QString::number(number))); setToolTip(tr("%1\nUnread news: %2").arg(QSL(APP_LONG_NAME), QString::number(number)));
QPixmap background(m_plainPixmap); QPixmap background(m_plainPixmap);
QPainter tray_painter; QPainter tray_painter;
// FIXME: Here draw different background instead of different color of number. // FIXME: Here draw different background instead of different color of number.
tray_painter.begin(&background); tray_painter.begin(&background);
tray_painter.setPen(any_new_message ? Qt::black : Qt::black); tray_painter.setPen(any_new_message ? Qt::black : Qt::black);
@ -143,14 +138,17 @@ void SystemTrayIcon::setNumber(int number, bool any_new_message) {
tray_painter.setFont(m_font); tray_painter.setFont(m_font);
tray_painter.drawText(QRect(0, 0, 128, 128), Qt::AlignVCenter | Qt::AlignCenter, QChar(8734)); tray_painter.drawText(QRect(0, 0, 128, 128), Qt::AlignVCenter | Qt::AlignCenter, QChar(8734));
} }
else { else {
// Smaller number if it has 3 digits. // Smaller number if it has 3 digits.
if (number > 99) { if (number > 99) {
m_font.setPixelSize(55); m_font.setPixelSize(55);
} }
else if (number > 9) { else if (number > 9) {
m_font.setPixelSize(80); m_font.setPixelSize(80);
} }
// Bigger number if it has just one digit. // Bigger number if it has just one digit.
else { else {
m_font.setPixelSize(100); m_font.setPixelSize(100);

View File

@ -44,12 +44,10 @@ void TabBar::setTabType(int index, const TabBar::TabType &type) {
case TabBar::DownloadManager: case TabBar::DownloadManager:
case TabBar::Closable: { case TabBar::Closable: {
PlainToolButton* close_button = new PlainToolButton(this); PlainToolButton* close_button = new PlainToolButton(this);
close_button->setIcon(qApp->icons()->fromTheme(QSL("application-exit"))); close_button->setIcon(qApp->icons()->fromTheme(QSL("application-exit")));
close_button->setToolTip(tr("Close this tab.")); close_button->setToolTip(tr("Close this tab."));
close_button->setText(tr("Close tab")); close_button->setText(tr("Close tab"));
close_button->setFixedSize(iconSize()); close_button->setFixedSize(iconSize());
// Close underlying tab when button is clicked. // Close underlying tab when button is clicked.
connect(close_button, &PlainToolButton::clicked, this, &TabBar::closeTabViaButton); connect(close_button, &PlainToolButton::clicked, this, &TabBar::closeTabViaButton);
setTabButton(index, button_position, close_button); setTabButton(index, button_position, close_button);
@ -77,7 +75,6 @@ void TabBar::closeTabViaButton() {
for (int i = 0; i < count(); i++) { for (int i = 0; i < count(); i++) {
if (tabButton(i, button_position) == close_button) { if (tabButton(i, button_position) == close_button) {
emit tabCloseRequested(i); emit tabCloseRequested(i);
return; return;
} }
} }
@ -96,6 +93,7 @@ void TabBar::wheelEvent(QWheelEvent *event) {
number_of_tabs - 1 : number_of_tabs - 1 :
current_index - 1); current_index - 1);
} }
else if (event->delta() < 0) { else if (event->delta() < 0) {
// Scroll to the RIGHT tab. // Scroll to the RIGHT tab.
setCurrentIndex(current_index == number_of_tabs - 1 ? setCurrentIndex(current_index == number_of_tabs - 1 ?
@ -107,7 +105,6 @@ void TabBar::wheelEvent(QWheelEvent *event) {
void TabBar::mousePressEvent(QMouseEvent* event) { void TabBar::mousePressEvent(QMouseEvent* event) {
QTabBar::mousePressEvent(event); QTabBar::mousePressEvent(event);
const int tab_index = tabAt(event->pos()); const int tab_index = tabAt(event->pos());
// Check if user clicked on some tab or on empty space. // Check if user clicked on some tab or on empty space.
@ -126,7 +123,6 @@ void TabBar::mousePressEvent(QMouseEvent *event) {
void TabBar::mouseDoubleClickEvent(QMouseEvent* event) { void TabBar::mouseDoubleClickEvent(QMouseEvent* event) {
QTabBar::mouseDoubleClickEvent(event); QTabBar::mouseDoubleClickEvent(event);
const int tab_index = tabAt(event->pos()); const int tab_index = tabAt(event->pos());
// Check if user clicked on some tab or on empty space. // Check if user clicked on some tab or on empty space.
@ -141,6 +137,7 @@ void TabBar::mouseDoubleClickEvent(QMouseEvent *event) {
} }
} }
} }
else { else {
emit emptySpaceDoubleClicked(); emit emptySpaceDoubleClicked();
} }

View File

@ -59,7 +59,6 @@ void TabWidget::setupMainMenuButton() {
m_btnMainMenu->setToolTip(tr("Displays main menu.")); m_btnMainMenu->setToolTip(tr("Displays main menu."));
m_btnMainMenu->setIcon(qApp->icons()->fromTheme(QSL("go-home"))); m_btnMainMenu->setIcon(qApp->icons()->fromTheme(QSL("go-home")));
m_btnMainMenu->setPopupMode(QToolButton::InstantPopup); m_btnMainMenu->setPopupMode(QToolButton::InstantPopup);
connect(m_btnMainMenu, &PlainToolButton::clicked, this, &TabWidget::openMainMenu); connect(m_btnMainMenu, &PlainToolButton::clicked, this, &TabWidget::openMainMenu);
} }
@ -78,10 +77,8 @@ void TabWidget::openMainMenu() {
QPoint button_position = m_btnMainMenu->pos(); QPoint button_position = m_btnMainMenu->pos();
const QSize target_size = m_btnMainMenu->size() / 2.0; const QSize target_size = m_btnMainMenu->size() / 2.0;
button_position.setX(button_position.x() + target_size.width()); button_position.setX(button_position.x() + target_size.width());
button_position.setY(button_position.y() + target_size.height()); button_position.setY(button_position.y() + target_size.height());
m_menuMain->exec(mapToGlobal(button_position)); m_menuMain->exec(mapToGlobal(button_position));
} }
@ -106,6 +103,7 @@ void TabWidget::checkTabBarVisibility() {
setCornerWidget(m_btnMainMenu, Qt::TopLeftCorner); setCornerWidget(m_btnMainMenu, Qt::TopLeftCorner);
m_btnMainMenu->setVisible(true); m_btnMainMenu->setVisible(true);
} }
else { else {
setCornerWidget(0, Qt::TopLeftCorner); setCornerWidget(0, Qt::TopLeftCorner);
setCornerWidget(0, Qt::TopRightCorner); setCornerWidget(0, Qt::TopRightCorner);
@ -118,7 +116,6 @@ void TabWidget::checkTabBarVisibility() {
void TabWidget::tabInserted(int index) { void TabWidget::tabInserted(int index) {
QTabWidget::tabInserted(index); QTabWidget::tabInserted(index);
checkTabBarVisibility(); checkTabBarVisibility();
const int count_of_tabs = count(); const int count_of_tabs = count();
if (index < count_of_tabs - 1 && count_of_tabs > 1) { if (index < count_of_tabs - 1 && count_of_tabs > 1) {
@ -130,7 +127,6 @@ void TabWidget::tabInserted(int index) {
void TabWidget::tabRemoved(int index) { void TabWidget::tabRemoved(int index) {
QTabWidget::tabRemoved(index); QTabWidget::tabRemoved(index);
checkTabBarVisibility(); checkTabBarVisibility();
const int count_of_tabs = count(); const int count_of_tabs = count();
if (index < count_of_tabs && count_of_tabs > 1) { if (index < count_of_tabs && count_of_tabs > 1) {
@ -143,7 +139,6 @@ void TabWidget::createConnections() {
connect(tabBar(), &TabBar::tabCloseRequested, this, &TabWidget::closeTab); connect(tabBar(), &TabBar::tabCloseRequested, this, &TabWidget::closeTab);
connect(tabBar(), &TabBar::emptySpaceDoubleClicked, this, &TabWidget::addEmptyBrowser); connect(tabBar(), &TabBar::emptySpaceDoubleClicked, this, &TabWidget::addEmptyBrowser);
connect(tabBar(), &TabBar::tabMoved, this, &TabWidget::fixContentsAfterMove); connect(tabBar(), &TabBar::tabMoved, this, &TabWidget::fixContentsAfterMove);
connect(feedMessageViewer()->messagesView(), &MessagesView::openMessagesInNewspaperView, this, &TabWidget::addNewspaperView); connect(feedMessageViewer()->messagesView(), &MessagesView::openMessagesInNewspaperView, this, &TabWidget::addNewspaperView);
connect(feedMessageViewer()->feedsView(), &FeedsView::openMessagesInNewspaperView, this, &TabWidget::addNewspaperView); connect(feedMessageViewer()->feedsView(), &FeedsView::openMessagesInNewspaperView, this, &TabWidget::addNewspaperView);
} }
@ -171,10 +166,12 @@ bool TabWidget::closeTab(int index) {
removeTab(index, true); removeTab(index, true);
return true; return true;
} }
else if (tabBar()->tabType(index) == TabBar::DownloadManager) { else if (tabBar()->tabType(index) == TabBar::DownloadManager) {
removeTab(index, false); removeTab(index, false);
return true; return true;
} }
else { else {
return false; return false;
} }
@ -207,15 +204,11 @@ int TabWidget::addNewspaperView(RootItem *root, const QList<Message> &messages)
#else #else
NewspaperPreviewer* prev = new NewspaperPreviewer(root, messages, this); NewspaperPreviewer* prev = new NewspaperPreviewer(root, messages, this);
#endif #endif
int index = addTab(prev, qApp->icons()->fromTheme(QSL("format-justify-fill")), tr("Newspaper view"), TabBar::Closable); int index = addTab(prev, qApp->icons()->fromTheme(QSL("format-justify-fill")), tr("Newspaper view"), TabBar::Closable);
setCurrentIndex(index); setCurrentIndex(index);
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
prev->loadMessages(messages, root); prev->loadMessages(messages, root);
#endif #endif
return index; return index;
} }
@ -233,11 +226,9 @@ int TabWidget::addLinkedBrowser(const QString &initial_url) {
int TabWidget::addBrowser(bool move_after_current, bool make_active, const QUrl& initial_url) { int TabWidget::addBrowser(bool move_after_current, bool make_active, const QUrl& initial_url) {
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
// Create new WebBrowser. // Create new WebBrowser.
WebBrowser* browser = new WebBrowser(this); WebBrowser* browser = new WebBrowser(this);
int final_index; int final_index;
#if defined (Q_OS_MACOS) #if defined (Q_OS_MACOS)
const QString browser_tab_name = tr(" Web browser"); const QString browser_tab_name = tr(" Web browser");
#else #else
@ -249,6 +240,7 @@ int TabWidget::addBrowser(bool move_after_current, bool make_active, const QUrl
final_index = insertTab(currentIndex() + 1, browser, qApp->icons()->fromTheme(QSL("text-html")), final_index = insertTab(currentIndex() + 1, browser, qApp->icons()->fromTheme(QSL("text-html")),
browser_tab_name, TabBar::Closable); browser_tab_name, TabBar::Closable);
} }
else { else {
// Add new browser as the last tab. // Add new browser as the last tab.
final_index = addTab(browser, qApp->icons()->fromTheme(QSL("text-html")), final_index = addTab(browser, qApp->icons()->fromTheme(QSL("text-html")),
@ -260,7 +252,6 @@ int TabWidget::addBrowser(bool move_after_current, bool make_active, const QUrl
// Make connections. // Make connections.
connect(browser, &WebBrowser::titleChanged, this, &TabWidget::changeTitle); connect(browser, &WebBrowser::titleChanged, this, &TabWidget::changeTitle);
connect(browser, &WebBrowser::iconChanged, this, &TabWidget::changeIcon); connect(browser, &WebBrowser::iconChanged, this, &TabWidget::changeIcon);
// Setup the tab index. // Setup the tab index.
browser->setIndex(final_index); browser->setIndex(final_index);
@ -279,15 +270,14 @@ int TabWidget::addBrowser(bool move_after_current, bool make_active, const QUrl
#else #else
Q_UNUSED(move_after_current) Q_UNUSED(move_after_current)
Q_UNUSED(make_active) Q_UNUSED(make_active)
WebFactory::instance()->openUrlInExternalBrowser(initial_url.toString()); WebFactory::instance()->openUrlInExternalBrowser(initial_url.toString());
return -1; return -1;
#endif #endif
} }
void TabWidget::indentTabText(int index) { void TabWidget::indentTabText(int index) {
#if defined (Q_OS_MACOS) #if defined (Q_OS_MACOS)
if (tabBar()->tabType(index) != TabBar::FeedReader && !tabIcon(index).isNull()) { if (tabBar()->tabType(index) != TabBar::FeedReader && !tabIcon(index).isNull()) {
// We have closable tab with some icon, fix the title. // We have closable tab with some icon, fix the title.
const QString text = tabText(index); const QString text = tabText(index);
@ -296,6 +286,7 @@ void TabWidget::indentTabText(int index){
setTabText(index, QSL(" ") + text); setTabText(index, QSL(" ") + text);
} }
} }
#else #else
Q_UNUSED(index) Q_UNUSED(index)
#endif #endif
@ -313,7 +304,6 @@ int TabWidget::addTab(TabContent *widget, const QIcon &icon, const QString &labe
const int index = QTabWidget::addTab(widget, icon, label); const int index = QTabWidget::addTab(widget, icon, label);
tabBar()->setTabType(index, type); tabBar()->setTabType(index, type);
indentTabText(index); indentTabText(index);
return index; return index;
} }
@ -321,7 +311,6 @@ int TabWidget::addTab(TabContent *widget, const QString &label, const TabBar::Ta
const int index = QTabWidget::addTab(widget, label); const int index = QTabWidget::addTab(widget, label);
tabBar()->setTabType(index, type); tabBar()->setTabType(index, type);
indentTabText(index); indentTabText(index);
return index; return index;
} }
@ -329,7 +318,6 @@ int TabWidget::insertTab(int index, QWidget *widget, const QIcon &icon, const QS
const int tab_index = QTabWidget::insertTab(index, widget, icon, label); const int tab_index = QTabWidget::insertTab(index, widget, icon, label);
tabBar()->setTabType(tab_index, type); tabBar()->setTabType(tab_index, type);
indentTabText(index); indentTabText(index);
return tab_index; return tab_index;
} }
@ -337,7 +325,6 @@ int TabWidget::insertTab(int index, QWidget *widget, const QString &label, const
const int tab_index = QTabWidget::insertTab(index, widget, label); const int tab_index = QTabWidget::insertTab(index, widget, label);
tabBar()->setTabType(tab_index, type); tabBar()->setTabType(tab_index, type);
indentTabText(index); indentTabText(index);
return tab_index; return tab_index;
} }

5
src/gui/timespinbox.cpp Normal file → Executable file
View File

@ -37,6 +37,7 @@ double TimeSpinBox::valueFromText(const QString &text) const {
if (ok) { if (ok) {
return value; return value;
} }
else { else {
QRegExp rx("\\b[0-9]{1,}\\b"); QRegExp rx("\\b[0-9]{1,}\\b");
QStringList numbers; QStringList numbers;
@ -55,6 +56,7 @@ double TimeSpinBox::valueFromText(const QString &text) const {
if (numbers.size() == 2) { if (numbers.size() == 2) {
return (numbers.at(0).toDouble() * 60.0) + numbers.at(1).toDouble(); return (numbers.at(0).toDouble() * 60.0) + numbers.at(1).toDouble();
} }
else { else {
return -1.0; return -1.0;
} }
@ -65,10 +67,8 @@ QString TimeSpinBox::textFromValue(double val) const {
int minutes_total = (int)val; int minutes_total = (int)val;
int minutes_val = minutes_total % 60; int minutes_val = minutes_total % 60;
int hours_val = (minutes_total - minutes_val) / 60; int hours_val = (minutes_total - minutes_val) / 60;
QString hours = tr("%n hour(s)", "", hours_val); QString hours = tr("%n hour(s)", "", hours_val);
QString minutes = tr("%n minute(s)", "", minutes_val); QString minutes = tr("%n minute(s)", "", minutes_val);
return hours + tr(" and ") + minutes; return hours + tr(" and ") + minutes;
} }
@ -83,6 +83,5 @@ void TimeSpinBox::fixup(QString &input) const {
QValidator::State TimeSpinBox::validate(QString& input, int& pos) const { QValidator::State TimeSpinBox::validate(QString& input, int& pos) const {
Q_UNUSED(pos) Q_UNUSED(pos)
return (valueFromText(input) != -1.0) ? QValidator::Acceptable : QValidator::Intermediate; return (valueFromText(input) != -1.0) ? QValidator::Acceptable : QValidator::Intermediate;
} }

View File

@ -26,25 +26,20 @@
ToolBarEditor::ToolBarEditor(QWidget* parent) ToolBarEditor::ToolBarEditor(QWidget* parent)
: QWidget(parent), m_ui(new Ui::ToolBarEditor) { : QWidget(parent), m_ui(new Ui::ToolBarEditor) {
m_ui->setupUi(this); m_ui->setupUi(this);
// Create connections. // Create connections.
connect(m_ui->m_btnInsertSeparator, &QToolButton::clicked, this, &ToolBarEditor::insertSeparator); connect(m_ui->m_btnInsertSeparator, &QToolButton::clicked, this, &ToolBarEditor::insertSeparator);
connect(m_ui->m_btnInsertSpacer, &QToolButton::clicked, this, &ToolBarEditor::insertSpacer); connect(m_ui->m_btnInsertSpacer, &QToolButton::clicked, this, &ToolBarEditor::insertSpacer);
connect(m_ui->m_btnAddSelectedAction, &QToolButton::clicked, this, &ToolBarEditor::addSelectedAction); connect(m_ui->m_btnAddSelectedAction, &QToolButton::clicked, this, &ToolBarEditor::addSelectedAction);
connect(m_ui->m_btnDeleteAllActions, &QToolButton::clicked, this, &ToolBarEditor::deleteAllActions); connect(m_ui->m_btnDeleteAllActions, &QToolButton::clicked, this, &ToolBarEditor::deleteAllActions);
connect(m_ui->m_btnDeleteSelectedAction, &QToolButton::clicked, this, &ToolBarEditor::deleteSelectedAction); connect(m_ui->m_btnDeleteSelectedAction, &QToolButton::clicked, this, &ToolBarEditor::deleteSelectedAction);
connect(m_ui->m_btnMoveActionUp, &QToolButton::clicked, this, &ToolBarEditor::moveActionUp); connect(m_ui->m_btnMoveActionUp, &QToolButton::clicked, this, &ToolBarEditor::moveActionUp);
connect(m_ui->m_btnMoveActionDown, &QToolButton::clicked, this, &ToolBarEditor::moveActionDown); connect(m_ui->m_btnMoveActionDown, &QToolButton::clicked, this, &ToolBarEditor::moveActionDown);
connect(m_ui->m_btnReset, &QToolButton::clicked, this, &ToolBarEditor::resetToolBar); connect(m_ui->m_btnReset, &QToolButton::clicked, this, &ToolBarEditor::resetToolBar);
connect(m_ui->m_listAvailableActions, &QListWidget::itemSelectionChanged, this, &ToolBarEditor::updateActionsAvailability); connect(m_ui->m_listAvailableActions, &QListWidget::itemSelectionChanged, this, &ToolBarEditor::updateActionsAvailability);
connect(m_ui->m_listActivatedActions, &QListWidget::itemSelectionChanged, this, &ToolBarEditor::updateActionsAvailability); connect(m_ui->m_listActivatedActions, &QListWidget::itemSelectionChanged, this, &ToolBarEditor::updateActionsAvailability);
connect(m_ui->m_listActivatedActions, &QListWidget::itemDoubleClicked, this, &ToolBarEditor::deleteSelectedAction); connect(m_ui->m_listActivatedActions, &QListWidget::itemDoubleClicked, this, &ToolBarEditor::deleteSelectedAction);
connect(m_ui->m_listAvailableActions, &QListWidget::itemDoubleClicked, this, &ToolBarEditor::addSelectedAction); connect(m_ui->m_listAvailableActions, &QListWidget::itemDoubleClicked, this, &ToolBarEditor::addSelectedAction);
m_ui->m_listActivatedActions->installEventFilter(this); m_ui->m_listActivatedActions->installEventFilter(this);
m_ui->m_btnInsertSeparator->setIcon(qApp->icons()->fromTheme(QSL("insert-object"))); m_ui->m_btnInsertSeparator->setIcon(qApp->icons()->fromTheme(QSL("insert-object")));
m_ui->m_btnInsertSpacer->setIcon(qApp->icons()->fromTheme(QSL("go-jump"))); m_ui->m_btnInsertSpacer->setIcon(qApp->icons()->fromTheme(QSL("go-jump")));
m_ui->m_btnAddSelectedAction->setIcon(qApp->icons()->fromTheme(QSL("back"))); m_ui->m_btnAddSelectedAction->setIcon(qApp->icons()->fromTheme(QSL("back")));
@ -61,10 +56,8 @@ ToolBarEditor::~ToolBarEditor() {
void ToolBarEditor::loadFromToolBar(BaseBar* tool_bar) { void ToolBarEditor::loadFromToolBar(BaseBar* tool_bar) {
m_toolBar = tool_bar; m_toolBar = tool_bar;
QList<QAction*> activated_actions = m_toolBar->changeableActions(); QList<QAction*> activated_actions = m_toolBar->changeableActions();
QList<QAction*> available_actions = m_toolBar->availableActions(); QList<QAction*> available_actions = m_toolBar->availableActions();
loadEditor(activated_actions, available_actions); loadEditor(activated_actions, available_actions);
} }
@ -97,11 +90,13 @@ void ToolBarEditor::loadEditor(const QList<QAction *> activated_actions, const Q
action_item->setText(tr("Separator")); action_item->setText(tr("Separator"));
action_item->setToolTip(tr("Separator")); action_item->setToolTip(tr("Separator"));
} }
else if (action->property("type").isValid()) { else if (action->property("type").isValid()) {
action_item->setData(Qt::UserRole, action->property("type").toString()); action_item->setData(Qt::UserRole, action->property("type").toString());
action_item->setText(action->property("name").toString()); action_item->setText(action->property("name").toString());
action_item->setToolTip(action_item->text()); action_item->setToolTip(action_item->text());
} }
else { else {
action_item->setData(Qt::UserRole, action->objectName()); action_item->setData(Qt::UserRole, action->objectName());
action_item->setToolTip(action->toolTip()); action_item->setToolTip(action->toolTip());
@ -118,11 +113,13 @@ void ToolBarEditor::loadEditor(const QList<QAction *> activated_actions, const Q
action_item->setToolTip(tr("Separator")); action_item->setToolTip(tr("Separator"));
action_item->setIcon(qApp->icons()->fromTheme(QSL("insert-object"))); action_item->setIcon(qApp->icons()->fromTheme(QSL("insert-object")));
} }
else if (action->property("type").isValid()) { else if (action->property("type").isValid()) {
action_item->setData(Qt::UserRole, action->property("type").toString()); action_item->setData(Qt::UserRole, action->property("type").toString());
action_item->setText(action->property("name").toString()); action_item->setText(action->property("name").toString());
action_item->setToolTip(action_item->text()); action_item->setToolTip(action_item->text());
} }
else { else {
action_item->setData(Qt::UserRole, action->objectName()); action_item->setData(Qt::UserRole, action->objectName());
action_item->setToolTip(action->toolTip()); action_item->setToolTip(action->toolTip());
@ -144,10 +141,12 @@ bool ToolBarEditor::eventFilter(QObject *object, QEvent *event) {
deleteSelectedAction(); deleteSelectedAction();
return true; return true;
} }
else if (key_event->key() == Qt::Key_Down && key_event->modifiers() & Qt::ControlModifier) { else if (key_event->key() == Qt::Key_Down && key_event->modifiers() & Qt::ControlModifier) {
moveActionDown(); moveActionDown();
return true; return true;
} }
else if (key_event->key() == Qt::Key_Up && key_event->modifiers() & Qt::ControlModifier) { else if (key_event->key() == Qt::Key_Up && key_event->modifiers() & Qt::ControlModifier) {
moveActionUp(); moveActionUp();
return true; return true;
@ -171,27 +170,21 @@ void ToolBarEditor::updateActionsAvailability() {
void ToolBarEditor::insertSpacer() { void ToolBarEditor::insertSpacer() {
const int current_row = m_ui->m_listActivatedActions->currentRow(); const int current_row = m_ui->m_listActivatedActions->currentRow();
QListWidgetItem* item = new QListWidgetItem(tr("Toolbar spacer")); QListWidgetItem* item = new QListWidgetItem(tr("Toolbar spacer"));
item->setIcon(qApp->icons()->fromTheme(QSL("go-jump"))); item->setIcon(qApp->icons()->fromTheme(QSL("go-jump")));
item->setData(Qt::UserRole, SPACER_ACTION_NAME); item->setData(Qt::UserRole, SPACER_ACTION_NAME);
m_ui->m_listActivatedActions->insertItem(current_row + 1, item); m_ui->m_listActivatedActions->insertItem(current_row + 1, item);
m_ui->m_listActivatedActions->setCurrentRow(current_row + 1); m_ui->m_listActivatedActions->setCurrentRow(current_row + 1);
emit setupChanged(); emit setupChanged();
} }
void ToolBarEditor::insertSeparator() { void ToolBarEditor::insertSeparator() {
const int current_row = m_ui->m_listActivatedActions->currentRow(); const int current_row = m_ui->m_listActivatedActions->currentRow();
QListWidgetItem* item = new QListWidgetItem(tr("Separator")); QListWidgetItem* item = new QListWidgetItem(tr("Separator"));
item->setData(Qt::UserRole, SEPARATOR_ACTION_NAME); item->setData(Qt::UserRole, SEPARATOR_ACTION_NAME);
item->setToolTip(tr("Separator")); item->setToolTip(tr("Separator"));
item->setIcon(qApp->icons()->fromTheme(QSL("insert-object"))); item->setIcon(qApp->icons()->fromTheme(QSL("insert-object")));
m_ui->m_listActivatedActions->insertItem(current_row + 1, item); m_ui->m_listActivatedActions->insertItem(current_row + 1, item);
m_ui->m_listActivatedActions->setCurrentRow(current_row + 1); m_ui->m_listActivatedActions->setCurrentRow(current_row + 1);
emit setupChanged(); emit setupChanged();
} }
@ -201,11 +194,9 @@ void ToolBarEditor::moveActionDown() {
if (items.size() == 1 && m_ui->m_listActivatedActions->currentRow() < m_ui->m_listActivatedActions->count() - 1) { if (items.size() == 1 && m_ui->m_listActivatedActions->currentRow() < m_ui->m_listActivatedActions->count() - 1) {
QListWidgetItem* selected_item = items.at(0); QListWidgetItem* selected_item = items.at(0);
int row = m_ui->m_listActivatedActions->row(selected_item); int row = m_ui->m_listActivatedActions->row(selected_item);
m_ui->m_listActivatedActions->takeItem(row++); m_ui->m_listActivatedActions->takeItem(row++);
m_ui->m_listActivatedActions->insertItem(row, selected_item); m_ui->m_listActivatedActions->insertItem(row, selected_item);
m_ui->m_listActivatedActions->setCurrentRow(row); m_ui->m_listActivatedActions->setCurrentRow(row);
emit setupChanged(); emit setupChanged();
} }
} }
@ -216,11 +207,9 @@ void ToolBarEditor::moveActionUp() {
if (items.size() == 1 && m_ui->m_listActivatedActions->currentRow() > 0) { if (items.size() == 1 && m_ui->m_listActivatedActions->currentRow() > 0) {
QListWidgetItem* selected_item = items.at(0); QListWidgetItem* selected_item = items.at(0);
int row = m_ui->m_listActivatedActions->row(selected_item); int row = m_ui->m_listActivatedActions->row(selected_item);
m_ui->m_listActivatedActions->takeItem(row--); m_ui->m_listActivatedActions->takeItem(row--);
m_ui->m_listActivatedActions->insertItem(row, selected_item); m_ui->m_listActivatedActions->insertItem(row, selected_item);
m_ui->m_listActivatedActions->setCurrentRow(row); m_ui->m_listActivatedActions->setCurrentRow(row);
emit setupChanged(); emit setupChanged();
} }
} }
@ -230,12 +219,10 @@ void ToolBarEditor::addSelectedAction() {
if (items.size() == 1) { if (items.size() == 1) {
QListWidgetItem* selected_item = items.at(0); QListWidgetItem* selected_item = items.at(0);
m_ui->m_listActivatedActions->insertItem( m_ui->m_listActivatedActions->insertItem(
m_ui->m_listActivatedActions->currentRow() + 1, m_ui->m_listActivatedActions->currentRow() + 1,
m_ui->m_listAvailableActions->takeItem(m_ui->m_listAvailableActions->row(selected_item))); m_ui->m_listAvailableActions->takeItem(m_ui->m_listAvailableActions->row(selected_item)));
m_ui->m_listActivatedActions->setCurrentRow(m_ui->m_listActivatedActions->currentRow() + 1); m_ui->m_listActivatedActions->setCurrentRow(m_ui->m_listActivatedActions->currentRow() + 1);
emit setupChanged(); emit setupChanged();
} }
} }
@ -249,9 +236,9 @@ void ToolBarEditor::deleteSelectedAction() {
if (data_item == SEPARATOR_ACTION_NAME || data_item == SPACER_ACTION_NAME) { if (data_item == SEPARATOR_ACTION_NAME || data_item == SPACER_ACTION_NAME) {
m_ui->m_listActivatedActions->takeItem(m_ui->m_listActivatedActions->row(selected_item)); m_ui->m_listActivatedActions->takeItem(m_ui->m_listActivatedActions->row(selected_item));
updateActionsAvailability(); updateActionsAvailability();
} }
else { else {
m_ui->m_listAvailableActions->insertItem( m_ui->m_listAvailableActions->insertItem(
m_ui->m_listAvailableActions->currentRow() + 1, m_ui->m_listAvailableActions->currentRow() + 1,

View File

@ -32,20 +32,16 @@ void TreeViewColumnsMenu::prepareMenu() {
for (int i = 0; i < header_view->count(); i++) { for (int i = 0; i < header_view->count(); i++) {
QAction* act = addAction(header_view->model()->headerData(i, Qt::Horizontal, Qt::EditRole).toString()); QAction* act = addAction(header_view->model()->headerData(i, Qt::Horizontal, Qt::EditRole).toString());
act->setData(i); act->setData(i);
act->setCheckable(true); act->setCheckable(true);
act->setChecked(!header_view->isSectionHidden(i)); act->setChecked(!header_view->isSectionHidden(i));
connect(act, &QAction::toggled, this, &TreeViewColumnsMenu::actionTriggered); connect(act, &QAction::toggled, this, &TreeViewColumnsMenu::actionTriggered);
} }
} }
void TreeViewColumnsMenu::actionTriggered(bool toggle) { void TreeViewColumnsMenu::actionTriggered(bool toggle) {
Q_UNUSED(toggle) Q_UNUSED(toggle)
QAction* send_act = qobject_cast<QAction*>(sender()); QAction* send_act = qobject_cast<QAction*>(sender());
header()->setSectionHidden(send_act->data().toInt(), !send_act->isChecked()); header()->setSectionHidden(send_act->data().toInt(), !send_act->isChecked());
} }

View File

@ -95,19 +95,23 @@ void TreeWidget::filterString(const QString &string) {
QList<QTreeWidgetItem*> _allItems = allItems(); QList<QTreeWidgetItem*> _allItems = allItems();
QList<QTreeWidgetItem*> parents; QList<QTreeWidgetItem*> parents;
bool stringIsEmpty = string.isEmpty(); bool stringIsEmpty = string.isEmpty();
foreach (QTreeWidgetItem* item, _allItems) { foreach (QTreeWidgetItem* item, _allItems) {
bool containsString = stringIsEmpty || item->text(0).contains(string, Qt::CaseInsensitive); bool containsString = stringIsEmpty || item->text(0).contains(string, Qt::CaseInsensitive);
if (containsString) { if (containsString) {
item->setHidden(false); item->setHidden(false);
if (item->parent()) { if (item->parent()) {
if (!parents.contains(item->parent())) { if (!parents.contains(item->parent())) {
parents << item->parent(); parents << item->parent();
} }
} }
} }
else { else {
item->setHidden(true); item->setHidden(true);
if (item->parent()) { if (item->parent()) {
item->parent()->setHidden(true); item->parent()->setHidden(true);
} }
@ -121,6 +125,7 @@ void TreeWidget::filterString(const QString &string) {
if (stringIsEmpty) { if (stringIsEmpty) {
parentItem->setExpanded(m_showMode == ItemsExpanded); parentItem->setExpanded(m_showMode == ItemsExpanded);
} }
else { else {
parentItem->setExpanded(true); parentItem->setExpanded(true);
} }
@ -161,6 +166,7 @@ bool TreeWidget::appendToParentItem(QTreeWidgetItem *parent, QTreeWidgetItem *it
bool TreeWidget::prependToParentItem(const QString& parentText, QTreeWidgetItem* item) { bool TreeWidget::prependToParentItem(const QString& parentText, QTreeWidgetItem* item) {
QList<QTreeWidgetItem*> list = findItems(parentText, Qt::MatchExactly); QList<QTreeWidgetItem*> list = findItems(parentText, Qt::MatchExactly);
if (list.count() == 0) { if (list.count() == 0) {
return false; return false;
} }

View File

@ -30,8 +30,12 @@ class TreeWidget : public QTreeWidget {
enum ItemShowMode { ItemsCollapsed = 0, ItemsExpanded = 1 }; enum ItemShowMode { ItemsCollapsed = 0, ItemsExpanded = 1 };
ItemShowMode defaultItemShowMode() { return m_showMode; } ItemShowMode defaultItemShowMode() {
void setDefaultItemShowMode(ItemShowMode mode) { m_showMode = mode; } return m_showMode;
}
void setDefaultItemShowMode(ItemShowMode mode) {
m_showMode = mode;
}
QList<QTreeWidgetItem*> allItems(); QList<QTreeWidgetItem*> allItems();
bool appendToParentItem(const QString& parentText, QTreeWidgetItem* item); bool appendToParentItem(const QString& parentText, QTreeWidgetItem* item);

View File

@ -36,19 +36,15 @@
void WebBrowser::createConnections() { void WebBrowser::createConnections() {
connect(m_webView, &WebViewer::messageStatusChangeRequested, this, &WebBrowser::receiveMessageStatusChangeRequest); connect(m_webView, &WebViewer::messageStatusChangeRequested, this, &WebBrowser::receiveMessageStatusChangeRequest);
connect(m_txtLocation, &LocationLineEdit::submitted, connect(m_txtLocation, &LocationLineEdit::submitted,
this, static_cast<void (WebBrowser::*)(const QString&)>(&WebBrowser::loadUrl)); this, static_cast<void (WebBrowser::*)(const QString&)>(&WebBrowser::loadUrl));
connect(m_webView, &WebViewer::urlChanged, this, &WebBrowser::updateUrl); connect(m_webView, &WebViewer::urlChanged, this, &WebBrowser::updateUrl);
// Change location textbox status according to webpage status. // Change location textbox status according to webpage status.
connect(m_webView, &WebViewer::loadStarted, this, &WebBrowser::onLoadingStarted); connect(m_webView, &WebViewer::loadStarted, this, &WebBrowser::onLoadingStarted);
connect(m_webView, &WebViewer::loadProgress, this, &WebBrowser::onLoadingProgress); connect(m_webView, &WebViewer::loadProgress, this, &WebBrowser::onLoadingProgress);
connect(m_webView, &WebViewer::loadFinished, this, &WebBrowser::onLoadingFinished); connect(m_webView, &WebViewer::loadFinished, this, &WebBrowser::onLoadingFinished);
// Forward title/icon changes. // Forward title/icon changes.
connect(m_webView, &WebViewer::titleChanged, this, &WebBrowser::onTitleChanged); connect(m_webView, &WebViewer::titleChanged, this, &WebBrowser::onTitleChanged);
#if QT_VERSION >= 0x050700 #if QT_VERSION >= 0x050700
connect(m_webView, &WebViewer::iconChanged, this, &WebBrowser::onIconChanged); connect(m_webView, &WebViewer::iconChanged, this, &WebBrowser::onIconChanged);
#endif #endif
@ -56,7 +52,6 @@ void WebBrowser::createConnections() {
void WebBrowser::updateUrl(const QUrl& url) { void WebBrowser::updateUrl(const QUrl& url) {
QString url_string = url.toString(); QString url_string = url.toString();
m_txtLocation->setText(url_string); m_txtLocation->setText(url_string);
//setNavigationBarVisible(url_string != INTERNAL_URL_EMPTY && url_string != INTERNAL_URL_NEWSPAPER); //setNavigationBarVisible(url_string != INTERNAL_URL_EMPTY && url_string != INTERNAL_URL_NEWSPAPER);
} }
@ -77,14 +72,11 @@ WebBrowser::WebBrowser(QWidget *parent) : TabContent(parent),
m_actionForward(m_webView->pageAction(QWebEnginePage::Forward)), m_actionForward(m_webView->pageAction(QWebEnginePage::Forward)),
m_actionReload(m_webView->pageAction(QWebEnginePage::Reload)), m_actionReload(m_webView->pageAction(QWebEnginePage::Reload)),
m_actionStop(m_webView->pageAction(QWebEnginePage::Stop)) { m_actionStop(m_webView->pageAction(QWebEnginePage::Stop)) {
// Initialize the components and layout. // Initialize the components and layout.
initializeLayout(); initializeLayout();
setFocusProxy(m_txtLocation); setFocusProxy(m_txtLocation);
setTabOrder(m_txtLocation, m_toolBar); setTabOrder(m_txtLocation, m_toolBar);
setTabOrder(m_toolBar, m_webView); setTabOrder(m_toolBar, m_webView);
createConnections(); createConnections();
reloadFontSettings(); reloadFontSettings();
} }
@ -98,7 +90,6 @@ void WebBrowser::reloadFontSettings() {
QFont fon; QFont fon;
fon.fromString(qApp->settings()->value(GROUP(Messages), fon.fromString(qApp->settings()->value(GROUP(Messages),
SETTING(Messages::PreviewerFontStandard)).toString()); SETTING(Messages::PreviewerFontStandard)).toString());
QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::StandardFont, fon.family()); QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::StandardFont, fon.family());
QWebEngineSettings::globalSettings()->setFontSize(QWebEngineSettings::DefaultFontSize, fon.pointSize()); QWebEngineSettings::globalSettings()->setFontSize(QWebEngineSettings::DefaultFontSize, fon.pointSize());
} }
@ -167,6 +158,7 @@ void WebBrowser::onTitleChanged(const QString &new_title) {
//: Webbrowser tab title when no title is available. //: Webbrowser tab title when no title is available.
emit titleChanged(m_index, tr("No title")); emit titleChanged(m_index, tr("No title"));
} }
else { else {
emit titleChanged(m_index, new_title); emit titleChanged(m_index, new_title);
} }
@ -182,7 +174,6 @@ void WebBrowser::initializeLayout() {
m_toolBar->setFloatable(false); m_toolBar->setFloatable(false);
m_toolBar->setMovable(false); m_toolBar->setMovable(false);
m_toolBar->setAllowedAreas(Qt::TopToolBarArea); m_toolBar->setAllowedAreas(Qt::TopToolBarArea);
// Modify action texts. // Modify action texts.
m_actionBack->setText(tr("Back")); m_actionBack->setText(tr("Back"));
m_actionBack->setToolTip(tr("Go back.")); m_actionBack->setToolTip(tr("Go back."));
@ -192,11 +183,8 @@ void WebBrowser::initializeLayout() {
m_actionReload->setToolTip(tr("Reload current web page.")); m_actionReload->setToolTip(tr("Reload current web page."));
m_actionStop->setText(tr("Stop")); m_actionStop->setText(tr("Stop"));
m_actionStop->setToolTip(tr("Stop web page loading.")); m_actionStop->setToolTip(tr("Stop web page loading."));
QWidgetAction* act_discover = new QWidgetAction(this); QWidgetAction* act_discover = new QWidgetAction(this);
act_discover->setDefaultWidget(m_btnDiscoverFeeds); act_discover->setDefaultWidget(m_btnDiscoverFeeds);
// Add needed actions into toolbar. // Add needed actions into toolbar.
m_toolBar->addAction(m_actionBack); m_toolBar->addAction(m_actionBack);
m_toolBar->addAction(m_actionForward); m_toolBar->addAction(m_actionForward);
@ -204,14 +192,12 @@ void WebBrowser::initializeLayout() {
m_toolBar->addAction(m_actionStop); m_toolBar->addAction(m_actionStop);
m_toolBar->addAction(act_discover); m_toolBar->addAction(act_discover);
m_toolBar->addWidget(m_txtLocation); m_toolBar->addWidget(m_txtLocation);
m_loadingProgress = new QProgressBar(this); m_loadingProgress = new QProgressBar(this);
m_loadingProgress->setFixedHeight(5); m_loadingProgress->setFixedHeight(5);
m_loadingProgress->setMinimum(0); m_loadingProgress->setMinimum(0);
m_loadingProgress->setTextVisible(false); m_loadingProgress->setTextVisible(false);
m_loadingProgress->setMaximum(100); m_loadingProgress->setMaximum(100);
m_loadingProgress->setAttribute(Qt::WA_TranslucentBackground); m_loadingProgress->setAttribute(Qt::WA_TranslucentBackground);
// Setup layout. // Setup layout.
m_layout->addWidget(m_toolBar); m_layout->addWidget(m_toolBar);
m_layout->addWidget(m_webView); m_layout->addWidget(m_webView);
@ -237,6 +223,7 @@ void WebBrowser::onLoadingFinished(bool success) {
this->m_btnDiscoverFeeds->setFeedAddresses(NetworkFactory::extractFeedLinksFromHtmlPage(m_webView->url(), result)); this->m_btnDiscoverFeeds->setFeedAddresses(NetworkFactory::extractFeedLinksFromHtmlPage(m_webView->url(), result));
}); });
} }
else { else {
m_btnDiscoverFeeds->clearFeedAddresses(); m_btnDiscoverFeeds->clearFeedAddresses();
} }
@ -258,7 +245,6 @@ void WebBrowser::markMessageAsRead(int id, bool read) {
m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(), m_root->getParentServiceRoot()->onAfterSetMessagesRead(m_root.data(),
QList<Message>() << *msg, QList<Message>() << *msg,
read ? RootItem::Read : RootItem::Unread); read ? RootItem::Read : RootItem::Unread);
emit markMessageRead(msg->m_id, read ? RootItem::Read : RootItem::Unread); emit markMessageRead(msg->m_id, read ? RootItem::Read : RootItem::Unread);
msg->m_isRead = read ? RootItem::Read : RootItem::Unread; msg->m_isRead = read ? RootItem::Read : RootItem::Unread;
} }
@ -276,13 +262,11 @@ void WebBrowser::switchMessageImportance(int id, bool checked) {
RootItem::Important))) { RootItem::Important))) {
DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings), DatabaseQueries::switchMessagesImportance(qApp->database()->connection(objectName(), DatabaseFactory::FromSettings),
QStringList() << QString::number(msg->m_id)); QStringList() << QString::number(msg->m_id));
m_root->getParentServiceRoot()->onAfterSwitchMessageImportance(m_root.data(), m_root->getParentServiceRoot()->onAfterSwitchMessageImportance(m_root.data(),
QList<ImportanceChange>() << ImportanceChange(*msg, QList<ImportanceChange>() << ImportanceChange(*msg,
msg->m_isImportant ? msg->m_isImportant ?
RootItem::NotImportant : RootItem::NotImportant :
RootItem::Important)); RootItem::Important));
emit markMessageImportant(msg->m_id, msg->m_isImportant ? RootItem::NotImportant : RootItem::Important); emit markMessageImportant(msg->m_id, msg->m_isImportant ? RootItem::NotImportant : RootItem::Important);
msg->m_isImportant = checked; msg->m_isImportant = checked;
} }

View File

@ -31,7 +31,6 @@
WebViewer::WebViewer(QWidget* parent) : QWebEngineView(parent) { WebViewer::WebViewer(QWidget* parent) : QWebEngineView(parent) {
WebPage* page = new WebPage(this); WebPage* page = new WebPage(this);
connect(page, &WebPage::messageStatusChangeRequested, this, &WebViewer::messageStatusChangeRequested); connect(page, &WebPage::messageStatusChangeRequested, this, &WebViewer::messageStatusChangeRequested);
setPage(page); setPage(page);
} }
@ -57,6 +56,7 @@ bool WebViewer::increaseWebPageZoom() {
setZoomFactor(zoomFactor() + ZOOM_FACTOR_STEP); setZoomFactor(zoomFactor() + ZOOM_FACTOR_STEP);
return true; return true;
} }
else { else {
return false; return false;
} }
@ -67,6 +67,7 @@ bool WebViewer::decreaseWebPageZoom() {
setZoomFactor(zoomFactor() - ZOOM_FACTOR_STEP); setZoomFactor(zoomFactor() - ZOOM_FACTOR_STEP);
return true; return true;
} }
else { else {
return false; return false;
} }
@ -79,6 +80,7 @@ bool WebViewer::resetWebPageZoom() {
setZoomFactor(new_factor); setZoomFactor(new_factor);
return true; return true;
} }
else { else {
return false; return false;
} }
@ -123,7 +125,6 @@ void WebViewer::loadMessages(const QList<Message> &messages) {
m_messageContents = skin.m_layoutMarkupWrapper.arg(messages.size() == 1 ? messages.at(0).m_title : tr("Newspaper view"), m_messageContents = skin.m_layoutMarkupWrapper.arg(messages.size() == 1 ? messages.at(0).m_title : tr("Newspaper view"),
messages_layout); messages_layout);
bool previously_enabled = isEnabled(); bool previously_enabled = isEnabled();
setEnabled(false); setEnabled(false);
displayMessage(); displayMessage();
setEnabled(previously_enabled); setEnabled(previously_enabled);
@ -135,7 +136,6 @@ void WebViewer::loadMessage(const Message &message) {
void WebViewer::clear() { void WebViewer::clear() {
bool previously_enabled = isEnabled(); bool previously_enabled = isEnabled();
setEnabled(false); setEnabled(false);
setHtml("<!DOCTYPE html><html><body</body></html>", QUrl(INTERNAL_URL_BLANK)); setHtml("<!DOCTYPE html><html><body</body></html>", QUrl(INTERNAL_URL_BLANK));
setEnabled(previously_enabled); setEnabled(previously_enabled);
@ -143,11 +143,8 @@ void WebViewer::clear() {
void WebViewer::contextMenuEvent(QContextMenuEvent* event) { void WebViewer::contextMenuEvent(QContextMenuEvent* event) {
event->accept(); event->accept();
QMenu* menu = page()->createStandardContextMenu(); QMenu* menu = page()->createStandardContextMenu();
menu->addAction(qApp->mainForm()->adblockIcon()->menuAction()); menu->addAction(qApp->mainForm()->adblockIcon()->menuAction());
const QPoint pos = event->globalPos(); const QPoint pos = event->globalPos();
QPoint p(pos.x(), pos.y() + 1); QPoint p(pos.x(), pos.y() + 1);
menu->popup(p); menu->popup(p);
@ -155,12 +152,12 @@ void WebViewer::contextMenuEvent(QContextMenuEvent *event) {
QWebEngineView* WebViewer::createWindow(QWebEnginePage::WebWindowType type) { QWebEngineView* WebViewer::createWindow(QWebEnginePage::WebWindowType type) {
Q_UNUSED(type) Q_UNUSED(type)
int index = qApp->mainForm()->tabWidget()->addBrowser(false, false); int index = qApp->mainForm()->tabWidget()->addBrowser(false, false);
if (index >= 0) { if (index >= 0) {
return qApp->mainForm()->tabWidget()->widget(index)->webBrowser()->viewer(); return qApp->mainForm()->tabWidget()->widget(index)->webBrowser()->viewer();
} }
else { else {
return nullptr; return nullptr;
} }
@ -173,6 +170,7 @@ void WebViewer::wheelEvent(QWheelEvent *event) {
if (event->delta() > 0) { if (event->delta() > 0) {
increaseWebPageZoom(); increaseWebPageZoom();
} }
else if (event->delta() < 0) { else if (event->delta() < 0) {
decreaseWebPageZoom(); decreaseWebPageZoom();
} }

View File

@ -28,16 +28,13 @@ WidgetWithStatus::WidgetWithStatus(QWidget *parent)
m_layout = new QHBoxLayout(this); m_layout = new QHBoxLayout(this);
m_btnStatus = new PlainToolButton(this); m_btnStatus = new PlainToolButton(this);
m_btnStatus->setFocusPolicy(Qt::NoFocus); m_btnStatus->setFocusPolicy(Qt::NoFocus);
m_iconProgress = qApp->icons()->fromTheme(QSL("view-refresh")); m_iconProgress = qApp->icons()->fromTheme(QSL("view-refresh"));
m_iconInformation = qApp->icons()->fromTheme(QSL("dialog-information")); m_iconInformation = qApp->icons()->fromTheme(QSL("dialog-information"));
m_iconWarning = qApp->icons()->fromTheme(QSL("dialog-warning")); m_iconWarning = qApp->icons()->fromTheme(QSL("dialog-warning"));
m_iconError = qApp->icons()->fromTheme(QSL("dialog-error")); m_iconError = qApp->icons()->fromTheme(QSL("dialog-error"));
m_iconOk = qApp->icons()->fromTheme(QSL("dialog-yes")); m_iconOk = qApp->icons()->fromTheme(QSL("dialog-yes"));
// Set layout properties. // Set layout properties.
m_layout->setMargin(0); m_layout->setMargin(0);
setLayout(m_layout); setLayout(m_layout);
setStatus(Information, QString()); setStatus(Information, QString());
} }

View File

@ -49,7 +49,6 @@ int main(int argc, char *argv[]) {
qDebug("Usage: rssguard [OPTIONS]\n\n" qDebug("Usage: rssguard [OPTIONS]\n\n"
"Option\t\tMeaning\n" "Option\t\tMeaning\n"
"-h\t\tDisplays this help."); "-h\t\tDisplays this help.");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
} }
@ -60,13 +59,10 @@ int main(int argc, char *argv[]) {
QObject::tr("LANG_ABBREV"); QObject::tr("LANG_ABBREV");
//: Name of translator - optional. //: Name of translator - optional.
QObject::tr("LANG_AUTHOR"); QObject::tr("LANG_AUTHOR");
// Ensure that ini format is used as application settings storage on Mac OS. // Ensure that ini format is used as application settings storage on Mac OS.
QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setDefaultFormat(QSettings::IniFormat);
// Setup debug output system. // Setup debug output system.
qInstallMessageHandler(Debugging::debugHandler); qInstallMessageHandler(Debugging::debugHandler);
// Instantiate base application object. // Instantiate base application object.
Application application(APP_LOW_NAME, argc, argv); Application application(APP_LOW_NAME, argc, argv);
qDebug("Instantiated Application class."); qDebug("Instantiated Application class.");
@ -79,49 +75,37 @@ int main(int argc, char *argv[]) {
// Load localization and setup locale before any widget is constructed. // Load localization and setup locale before any widget is constructed.
qApp->localization()->loadActiveLanguage(); qApp->localization()->loadActiveLanguage();
application.setFeedReader(new FeedReader(&application)); application.setFeedReader(new FeedReader(&application));
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); QApplication::setAttribute(Qt::AA_DontShowIconsInMenus);
disableWindowTabbing(); disableWindowTabbing();
#endif #endif
// Register needed metatypes. // Register needed metatypes.
qRegisterMetaType<QList<Message>>("QList<Message>"); qRegisterMetaType<QList<Message>>("QList<Message>");
qRegisterMetaType<QList<RootItem*>>("QList<RootItem*>"); qRegisterMetaType<QList<RootItem*>>("QList<RootItem*>");
// Just call this instance, so that is is created in main GUI thread. // Just call this instance, so that is is created in main GUI thread.
WebFactory::instance(); WebFactory::instance();
// Add an extra path for non-system icon themes and set current icon theme // Add an extra path for non-system icon themes and set current icon theme
// and skin. // and skin.
qApp->icons()->setupSearchPaths(); qApp->icons()->setupSearchPaths();
qApp->icons()->loadCurrentIconTheme(); qApp->icons()->loadCurrentIconTheme();
qApp->skins()->loadCurrentSkin(); qApp->skins()->loadCurrentSkin();
// These settings needs to be set before any QSettings object. // These settings needs to be set before any QSettings object.
Application::setApplicationName(APP_NAME); Application::setApplicationName(APP_NAME);
Application::setApplicationVersion(APP_VERSION); Application::setApplicationVersion(APP_VERSION);
Application::setOrganizationDomain(APP_URL); Application::setOrganizationDomain(APP_URL);
Application::setWindowIcon(QIcon(APP_ICON_PATH)); Application::setWindowIcon(QIcon(APP_ICON_PATH));
// Load activated accounts. // Load activated accounts.
qApp->feedReader()->feedsModel()->loadActivatedServiceAccounts(); qApp->feedReader()->feedsModel()->loadActivatedServiceAccounts();
// Setup single-instance behavior. // Setup single-instance behavior.
QObject::connect(&application, &Application::messageReceived, &application, &Application::processExecutionMessage); QObject::connect(&application, &Application::messageReceived, &application, &Application::processExecutionMessage);
qDebug().nospace() << "Creating main application form in thread: \'" << QThread::currentThreadId() << "\'."; qDebug().nospace() << "Creating main application form in thread: \'" << QThread::currentThreadId() << "\'.";
// Instantiate main application window. // Instantiate main application window.
FormMain main_window; FormMain main_window;
// Set correct information for main window. // Set correct information for main window.
main_window.setWindowTitle(APP_LONG_NAME); main_window.setWindowTitle(APP_LONG_NAME);
// Now is a good time to initialize dynamic keyboard shortcuts. // Now is a good time to initialize dynamic keyboard shortcuts.
DynamicShortcuts::load(qApp->userActions()); DynamicShortcuts::load(qApp->userActions());
@ -130,6 +114,7 @@ int main(int argc, char *argv[]) {
qDebug("Hiding the main window when the application is starting."); qDebug("Hiding the main window when the application is starting.");
main_window.switchVisibility(true); main_window.switchVisibility(true);
} }
else { else {
qDebug("Showing the main window when the application is starting."); qDebug("Showing the main window when the application is starting.");
main_window.show(); main_window.show();
@ -145,6 +130,7 @@ int main(int argc, char *argv[]) {
"version by clicking this popup notification.").arg(APP_LONG_NAME), "version by clicking this popup notification.").arg(APP_LONG_NAME),
QSystemTrayIcon::NoIcon, 0, false, &main_window, SLOT(showAbout())); QSystemTrayIcon::NoIcon, 0, false, &main_window, SLOT(showAbout()));
} }
else { else {
qApp->showGuiMessage(QSL(APP_NAME), QObject::tr("Welcome to %1.").arg(APP_NAME), QSystemTrayIcon::NoIcon); qApp->showGuiMessage(QSL(APP_NAME), QObject::tr("Welcome to %1.").arg(APP_NAME), QSystemTrayIcon::NoIcon);
} }
@ -154,7 +140,6 @@ int main(int argc, char *argv[]) {
} }
qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->loadAllExpandStates(); qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->loadAllExpandStates();
// Enter global event loop. // Enter global event loop.
return Application::exec(); return Application::exec();
} }

View File

@ -59,12 +59,9 @@ Application::Application(const QString &id, int &argc, char **argv)
connect(this, &Application::aboutToQuit, this, &Application::onAboutToQuit); connect(this, &Application::aboutToQuit, this, &Application::onAboutToQuit);
connect(this, &Application::commitDataRequest, this, &Application::onCommitData); connect(this, &Application::commitDataRequest, this, &Application::onCommitData);
connect(this, &Application::saveStateRequest, this, &Application::onSaveState); connect(this, &Application::saveStateRequest, this, &Application::onSaveState);
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, this, &Application::downloadRequested); connect(QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, this, &Application::downloadRequested);
QWebEngineProfile::defaultProfile()->setRequestInterceptor(m_urlInterceptor); QWebEngineProfile::defaultProfile()->setRequestInterceptor(m_urlInterceptor);
// TODO: Teď tam žádný nastavení není, ale jestli se DNT třeba // TODO: Teď tam žádný nastavení není, ale jestli se DNT třeba
// přidá do dialogu nastavení, tak toto volat při ukládání nastavení. // přidá do dialogu nastavení, tak toto volat při ukládání nastavení.
m_urlInterceptor->loadSettings(); m_urlInterceptor->loadSettings();
@ -96,6 +93,7 @@ bool Application::isFirstRun(const QString &version) {
// Check this only if checked version is equal to actual version. // Check this only if checked version is equal to actual version.
return settings()->value(GROUP(General), QString(General::FirstRun) + QL1C('_') + version, true).toBool(); return settings()->value(GROUP(General), QString(General::FirstRun) + QL1C('_') + version, true).toBool();
} }
else { else {
return false; return false;
} }
@ -143,7 +141,6 @@ void Application::eliminateFirstRun(const QString &version) {
void Application::setFeedReader(FeedReader* feed_reader) { void Application::setFeedReader(FeedReader* feed_reader) {
m_feedReader = feed_reader; m_feedReader = feed_reader;
connect(m_feedReader, &FeedReader::feedUpdatesStarted, this, &Application::onFeedUpdatesStarted); connect(m_feedReader, &FeedReader::feedUpdatesStarted, this, &Application::onFeedUpdatesStarted);
connect(m_feedReader, &FeedReader::feedUpdatesProgress, this, &Application::onFeedUpdatesProgress); connect(m_feedReader, &FeedReader::feedUpdatesProgress, this, &Application::onFeedUpdatesProgress);
connect(m_feedReader, &FeedReader::feedUpdatesFinished, this, &Application::onFeedUpdatesFinished); connect(m_feedReader, &FeedReader::feedUpdatesFinished, this, &Application::onFeedUpdatesFinished);
@ -160,7 +157,6 @@ IconFactory *Application::icons() {
DownloadManager* Application::downloadManager() { DownloadManager* Application::downloadManager() {
if (m_downloadManager == nullptr) { if (m_downloadManager == nullptr) {
m_downloadManager = new DownloadManager(); m_downloadManager = new DownloadManager();
connect(m_downloadManager, &DownloadManager::downloadFinished, mainForm()->statusBar(), &StatusBar::clearProgressDownload); connect(m_downloadManager, &DownloadManager::downloadFinished, mainForm()->statusBar(), &StatusBar::clearProgressDownload);
connect(m_downloadManager, &DownloadManager::downloadProgressed, mainForm()->statusBar(), &StatusBar::showProgressDownload); connect(m_downloadManager, &DownloadManager::downloadProgressed, mainForm()->statusBar(), &StatusBar::showProgressDownload);
} }
@ -212,6 +208,7 @@ QString Application::getUserDataPath() {
if (settings()->type() == SettingsProperties::Portable) { if (settings()->type() == SettingsProperties::Portable) {
return getUserDataAppPath(); return getUserDataAppPath();
} }
else { else {
return getUserDataHomePath(); return getUserDataHomePath();
} }
@ -224,6 +221,7 @@ QString Application::getUserDataHomePath() {
if (QDir().exists(home_folder)) { if (QDir().exists(home_folder)) {
return home_folder; return home_folder;
} }
else { else {
return getConfigHomePath() + QDir::separator() + QSL(APP_NAME); return getConfigHomePath() + QDir::separator() + QSL(APP_NAME);
} }
@ -284,18 +282,19 @@ void Application::restoreDatabaseSettings(bool restore_database, bool restore_se
void Application::processExecutionMessage(const QString& message) { void Application::processExecutionMessage(const QString& message) {
qDebug("Received '%s' execution message from another application instance.", qPrintable(message)); qDebug("Received '%s' execution message from another application instance.", qPrintable(message));
const QStringList messages = message.split(ARGUMENTS_LIST_SEPARATOR); const QStringList messages = message.split(ARGUMENTS_LIST_SEPARATOR);
if (messages.contains(APP_QUIT_INSTANCE)) { if (messages.contains(APP_QUIT_INSTANCE)) {
quit(); quit();
} }
else { else {
foreach (const QString& msg, messages) { foreach (const QString& msg, messages) {
if (msg == APP_IS_RUNNING) { if (msg == APP_IS_RUNNING) {
showGuiMessage(APP_NAME, tr("Application is already running."), QSystemTrayIcon::Information); showGuiMessage(APP_NAME, tr("Application is already running."), QSystemTrayIcon::Information);
mainForm()->display(); mainForm()->display();
} }
else if (msg.startsWith(QL1S(URI_SCHEME_FEED_SHORT))) { else if (msg.startsWith(QL1S(URI_SCHEME_FEED_SHORT))) {
// Application was running, and someone wants to add new feed. // Application was running, and someone wants to add new feed.
StandardServiceRoot* root = qApp->feedReader()->feedsModel()->standardServiceRoot(); StandardServiceRoot* root = qApp->feedReader()->feedsModel()->standardServiceRoot();
@ -303,6 +302,7 @@ void Application::processExecutionMessage(const QString &message) {
if (root != nullptr) { if (root != nullptr) {
root->checkArgumentForFeedAdding(msg); root->checkArgumentForFeedAdding(msg);
} }
else { else {
showGuiMessage(tr("Cannot add feed"), showGuiMessage(tr("Cannot add feed"),
tr("Feed cannot be added because standard RSS/ATOM account is not enabled."), tr("Feed cannot be added because standard RSS/ATOM account is not enabled."),
@ -341,7 +341,6 @@ void Application::deleteTrayIcon() {
m_mainForm->display(); m_mainForm->display();
delete m_trayIcon; delete m_trayIcon;
m_trayIcon = nullptr; m_trayIcon = nullptr;
// Make sure that application quits when last window is closed. // Make sure that application quits when last window is closed.
setQuitOnLastWindowClosed(true); setQuitOnLastWindowClosed(true);
} }
@ -354,10 +353,12 @@ void Application::showGuiMessage(const QString &title, const QString &message,
if (SystemTrayIcon::areNotificationsEnabled() && SystemTrayIcon::isSystemTrayActivated()) { if (SystemTrayIcon::areNotificationsEnabled() && SystemTrayIcon::isSystemTrayActivated()) {
trayIcon()->showMessage(title, message, message_type, TRAY_ICON_BUBBLE_TIMEOUT, invokation_target, invokation_slot); trayIcon()->showMessage(title, message, message_type, TRAY_ICON_BUBBLE_TIMEOUT, invokation_target, invokation_slot);
} }
else if (show_at_least_msgbox) { else if (show_at_least_msgbox) {
// Tray icon or OSD is not available, display simple text box. // Tray icon or OSD is not available, display simple text box.
MessageBox::show(parent, (QMessageBox::Icon) message_type, title, message); MessageBox::show(parent, (QMessageBox::Icon) message_type, title, message);
} }
else { else {
qDebug("Silencing GUI message: '%s'.", qPrintable(message)); qDebug("Silencing GUI message: '%s'.", qPrintable(message));
} }
@ -365,14 +366,12 @@ void Application::showGuiMessage(const QString &title, const QString &message,
void Application::onCommitData(QSessionManager& manager) { void Application::onCommitData(QSessionManager& manager) {
qDebug("OS asked application to commit its data."); qDebug("OS asked application to commit its data.");
manager.setRestartHint(QSessionManager::RestartNever); manager.setRestartHint(QSessionManager::RestartNever);
manager.release(); manager.release();
} }
void Application::onSaveState(QSessionManager& manager) { void Application::onSaveState(QSessionManager& manager) {
qDebug("OS asked application to save its state."); qDebug("OS asked application to save its state.");
manager.setRestartHint(QSessionManager::RestartNever); manager.setRestartHint(QSessionManager::RestartNever);
manager.release(); manager.release();
} }
@ -380,22 +379,16 @@ void Application::onSaveState(QSessionManager &manager) {
void Application::onAboutToQuit() { void Application::onAboutToQuit() {
eliminateFirstRun(); eliminateFirstRun();
eliminateFirstRun(APP_VERSION); eliminateFirstRun(APP_VERSION);
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
AdBlockManager::instance()->save(); AdBlockManager::instance()->save();
#endif #endif
// Make sure that we obtain close lock BEFORE even trying to quit the application. // Make sure that we obtain close lock BEFORE even trying to quit the application.
const bool locked_safely = feedUpdateLock()->tryLock(4 * CLOSE_LOCK_TIMEOUT); const bool locked_safely = feedUpdateLock()->tryLock(4 * CLOSE_LOCK_TIMEOUT);
processEvents(); processEvents();
qDebug("Cleaning up resources and saving application state."); qDebug("Cleaning up resources and saving application state.");
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
system()->removeTrolltechJunkRegistryKeys(); system()->removeTrolltechJunkRegistryKeys();
#endif #endif
qApp->feedReader()->quit(); qApp->feedReader()->quit();
database()->saveDatabase(); database()->saveDatabase();
@ -406,10 +399,10 @@ void Application::onAboutToQuit() {
if (locked_safely) { if (locked_safely) {
// Application obtained permission to close in a safe way. // Application obtained permission to close in a safe way.
qDebug("Close lock was obtained safely."); qDebug("Close lock was obtained safely.");
// We locked the lock to exit peacefully, unlock it to avoid warnings. // We locked the lock to exit peacefully, unlock it to avoid warnings.
feedUpdateLock()->unlock(); feedUpdateLock()->unlock();
} }
else { else {
// Request for write lock timed-out. This means // Request for write lock timed-out. This means
// that some critical action can be processed right now. // that some critical action can be processed right now.
@ -426,6 +419,7 @@ void Application::onAboutToQuit() {
if (QProcess::startDetached(QString("\"") + QDir::toNativeSeparators(applicationFilePath()) + QString("\""))) { if (QProcess::startDetached(QString("\"") + QDir::toNativeSeparators(applicationFilePath()) + QString("\""))) {
qDebug("New application instance was started."); qDebug("New application instance was started.");
} }
else { else {
qWarning("New application instance was not started successfully."); qWarning("New application instance was not started successfully.");
} }

View File

@ -47,6 +47,7 @@ void AutoSaver::changeOccurred() {
if (m_firstChange.elapsed() > MAXWAIT) { if (m_firstChange.elapsed() > MAXWAIT) {
saveIfNeccessary(); saveIfNeccessary();
} }
else { else {
m_timer.start(AUTOSAVE_IN, this); m_timer.start(AUTOSAVE_IN, this);
} }
@ -56,6 +57,7 @@ void AutoSaver::timerEvent(QTimerEvent *event) {
if (event->timerId() == m_timer.timerId()) { if (event->timerId() == m_timer.timerId()) {
saveIfNeccessary(); saveIfNeccessary();
} }
else { else {
QObject::timerEvent(event); QObject::timerEvent(event);
} }

View File

@ -32,10 +32,8 @@ DatabaseCleaner::~DatabaseCleaner() {
void DatabaseCleaner::purgeDatabaseData(const CleanerOrders& which_data) { void DatabaseCleaner::purgeDatabaseData(const CleanerOrders& which_data) {
qDebug().nospace() << "Performing database cleanup in thread: \'" << QThread::currentThreadId() << "\'."; qDebug().nospace() << "Performing database cleanup in thread: \'" << QThread::currentThreadId() << "\'.";
// Inform everyone about the start of the process. // Inform everyone about the start of the process.
emit purgeStarted(); emit purgeStarted();
bool result = true; bool result = true;
const int difference = 99 / 8; const int difference = 99 / 8;
int progress = 0; int progress = 0;
@ -44,10 +42,8 @@ void DatabaseCleaner::purgeDatabaseData(const CleanerOrders &which_data) {
if (which_data.m_removeReadMessages) { if (which_data.m_removeReadMessages) {
progress += difference; progress += difference;
emit purgeProgress(progress, tr("Removing read messages...")); emit purgeProgress(progress, tr("Removing read messages..."));
// Remove read messages. // Remove read messages.
result &= purgeReadMessages(database); result &= purgeReadMessages(database);
progress += difference; progress += difference;
emit purgeProgress(progress, tr("Read messages purged...")); emit purgeProgress(progress, tr("Read messages purged..."));
} }
@ -55,10 +51,8 @@ void DatabaseCleaner::purgeDatabaseData(const CleanerOrders &which_data) {
if (which_data.m_removeRecycleBin) { if (which_data.m_removeRecycleBin) {
progress += difference; progress += difference;
emit purgeProgress(progress, tr("Purging recycle bin...")); emit purgeProgress(progress, tr("Purging recycle bin..."));
// Remove read messages. // Remove read messages.
result &= purgeRecycleBin(database); result &= purgeRecycleBin(database);
progress += difference; progress += difference;
emit purgeProgress(progress, tr("Recycle bin purged...")); emit purgeProgress(progress, tr("Recycle bin purged..."));
} }
@ -66,10 +60,8 @@ void DatabaseCleaner::purgeDatabaseData(const CleanerOrders &which_data) {
if (which_data.m_removeOldMessages) { if (which_data.m_removeOldMessages) {
progress += difference; progress += difference;
emit purgeProgress(progress, tr("Removing old messages...")); emit purgeProgress(progress, tr("Removing old messages..."));
// Remove old messages. // Remove old messages.
result &= purgeOldMessages(database, which_data.m_barrierForRemovingOldMessagesInDays); result &= purgeOldMessages(database, which_data.m_barrierForRemovingOldMessagesInDays);
progress += difference; progress += difference;
emit purgeProgress(progress, tr("Old messages purged...")); emit purgeProgress(progress, tr("Old messages purged..."));
} }
@ -77,10 +69,8 @@ void DatabaseCleaner::purgeDatabaseData(const CleanerOrders &which_data) {
if (which_data.m_shrinkDatabase) { if (which_data.m_shrinkDatabase) {
progress += difference; progress += difference;
emit purgeProgress(progress, tr("Shrinking database file...")); emit purgeProgress(progress, tr("Shrinking database file..."));
// Call driver-specific vacuuming function. // Call driver-specific vacuuming function.
result &= qApp->database()->vacuumDatabase(); result &= qApp->database()->vacuumDatabase();
progress += difference; progress += difference;
emit purgeProgress(progress, tr("Database file shrinked...")); emit purgeProgress(progress, tr("Database file shrinked..."));
} }

View File

@ -44,6 +44,7 @@ qint64 DatabaseFactory::getDatabaseFileSize() const {
if (m_activeDatabaseDriver == SQLITE || m_activeDatabaseDriver == SQLITE_MEMORY) { if (m_activeDatabaseDriver == SQLITE || m_activeDatabaseDriver == SQLITE_MEMORY) {
return QFileInfo(sqliteDatabaseFilePath()).size(); return QFileInfo(sqliteDatabaseFilePath()).size();
} }
else { else {
return 0; return 0;
} }
@ -59,6 +60,7 @@ qint64 DatabaseFactory::getDatabaseDataSize() const {
query.next(); query.next();
result *= query.value(0).value<qint64>(); result *= query.value(0).value<qint64>();
} }
else { else {
return 0; return 0;
} }
@ -67,12 +69,14 @@ qint64 DatabaseFactory::getDatabaseDataSize() const {
query.next(); query.next();
result *= query.value(0).value<qint64>(); result *= query.value(0).value<qint64>();
} }
else { else {
return 0; return 0;
} }
return result; return result;
} }
else if (m_activeDatabaseDriver == MYSQL) { else if (m_activeDatabaseDriver == MYSQL) {
QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings); QSqlDatabase database = qApp->database()->connection(metaObject()->className(), DatabaseFactory::FromSettings);
qint64 result = 1; qint64 result = 1;
@ -87,10 +91,12 @@ qint64 DatabaseFactory::getDatabaseDataSize() const {
return result; return result;
} }
else { else {
return 0; return 0;
} }
} }
else { else {
return 0; return 0;
} }
@ -99,7 +105,6 @@ qint64 DatabaseFactory::getDatabaseDataSize() const {
DatabaseFactory::MySQLError DatabaseFactory::mysqlTestConnection(const QString& hostname, int port, const QString& w_database, DatabaseFactory::MySQLError DatabaseFactory::mysqlTestConnection(const QString& hostname, int port, const QString& w_database,
const QString& username, const QString& password) { const QString& username, const QString& password) {
QSqlDatabase database = QSqlDatabase::addDatabase(APP_DB_MYSQL_DRIVER, APP_DB_MYSQL_TEST); QSqlDatabase database = QSqlDatabase::addDatabase(APP_DB_MYSQL_DRIVER, APP_DB_MYSQL_TEST);
database.setHostName(hostname); database.setHostName(hostname);
database.setPort(port); database.setPort(port);
database.setUserName(username); database.setUserName(username);
@ -111,20 +116,22 @@ DatabaseFactory::MySQLError DatabaseFactory::mysqlTestConnection(const QString &
if (!query.lastError().isValid() && query.next()) { if (!query.lastError().isValid() && query.next()) {
qDebug("Checked MySQL database, version is '%s'.", qPrintable(query.value(0).toString())); qDebug("Checked MySQL database, version is '%s'.", qPrintable(query.value(0).toString()));
// Connection succeeded, clean up the mess and return OK status. // Connection succeeded, clean up the mess and return OK status.
database.close(); database.close();
return MySQLOk; return MySQLOk;
} }
else { else {
database.close(); database.close();
return MySQLUnknownError; return MySQLUnknownError;
} }
} }
else if (database.lastError().isValid()) { else if (database.lastError().isValid()) {
// Connection failed, do cleanup and return specific error code. // Connection failed, do cleanup and return specific error code.
return static_cast<MySQLError>(database.lastError().number()); return static_cast<MySQLError>(database.lastError().number());
} }
else { else {
return MySQLUnknownError; return MySQLUnknownError;
} }
@ -180,6 +187,7 @@ void DatabaseFactory::finishRestoration() {
QFile::remove(backup_database_file); QFile::remove(backup_database_file);
qDebug("Database file was restored successully."); qDebug("Database file was restored successully.");
} }
else { else {
qCritical("Database file was NOT restored due to error when copying the file."); qCritical("Database file was NOT restored due to error when copying the file.");
} }
@ -192,15 +200,14 @@ void DatabaseFactory::sqliteAssemblyDatabaseFilePath() {
QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() { QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
QSqlDatabase database = QSqlDatabase::addDatabase(APP_DB_SQLITE_DRIVER); QSqlDatabase database = QSqlDatabase::addDatabase(APP_DB_SQLITE_DRIVER);
database.setDatabaseName(QSL(":memory:")); database.setDatabaseName(QSL(":memory:"));
if (!database.open()) { if (!database.open()) {
qFatal("In-memory SQLite database was NOT opened. Delivered error message: '%s'", qPrintable(database.lastError().text())); qFatal("In-memory SQLite database was NOT opened. Delivered error message: '%s'", qPrintable(database.lastError().text()));
} }
else { else {
QSqlQuery query_db(database); QSqlQuery query_db(database);
query_db.setForwardOnly(true); query_db.setForwardOnly(true);
query_db.exec(QSL("PRAGMA encoding = \"UTF-8\"")); query_db.exec(QSL("PRAGMA encoding = \"UTF-8\""));
query_db.exec(QSL("PRAGMA synchronous = OFF")); query_db.exec(QSL("PRAGMA synchronous = OFF"));
@ -209,13 +216,11 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
query_db.exec(QSL("PRAGMA cache_size = 16384")); query_db.exec(QSL("PRAGMA cache_size = 16384"));
query_db.exec(QSL("PRAGMA count_changes = OFF")); query_db.exec(QSL("PRAGMA count_changes = OFF"));
query_db.exec(QSL("PRAGMA temp_store = MEMORY")); query_db.exec(QSL("PRAGMA temp_store = MEMORY"));
// Sample query which checks for existence of tables. // Sample query which checks for existence of tables.
query_db.exec(QSL("SELECT inf_value FROM Information WHERE inf_key = 'schema_version'")); query_db.exec(QSL("SELECT inf_value FROM Information WHERE inf_key = 'schema_version'"));
if (query_db.lastError().isValid()) { if (query_db.lastError().isValid()) {
qWarning("Error occurred. In-memory SQLite database is not initialized. Initializing now."); qWarning("Error occurred. In-memory SQLite database is not initialized. Initializing now.");
QFile file_init(APP_SQL_PATH + QDir::separator() + APP_DB_SQLITE_INIT); QFile file_init(APP_SQL_PATH + QDir::separator() + APP_DB_SQLITE_INIT);
if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) {
@ -239,9 +244,9 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
database.commit(); database.commit();
qDebug("In-memory SQLite database backend should be ready now."); qDebug("In-memory SQLite database backend should be ready now.");
} }
else { else {
query_db.next(); query_db.next();
qDebug("In-memory SQLite database connection seems to be established."); qDebug("In-memory SQLite database connection seems to be established.");
qDebug("In-memory SQLite database has version '%s'.", qPrintable(query_db.value(0).toString())); qDebug("In-memory SQLite database has version '%s'.", qPrintable(query_db.value(0).toString()));
} }
@ -249,10 +254,8 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
// Loading messages from file-based database. // Loading messages from file-based database.
QSqlDatabase file_database = sqliteConnection(objectName(), StrictlyFileBased); QSqlDatabase file_database = sqliteConnection(objectName(), StrictlyFileBased);
QSqlQuery copy_contents(database); QSqlQuery copy_contents(database);
// Attach database. // Attach database.
copy_contents.exec(QString("ATTACH DATABASE '%1' AS 'storage';").arg(file_database.databaseName())); copy_contents.exec(QString("ATTACH DATABASE '%1' AS 'storage';").arg(file_database.databaseName()));
// Copy all stuff. // Copy all stuff.
// WARNING: All tables belong here. // WARNING: All tables belong here.
QStringList tables; QStringList tables;
@ -262,6 +265,7 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
tables.append(copy_contents.value(0).toString()); tables.append(copy_contents.value(0).toString());
} }
} }
else { else {
qFatal("Cannot obtain list of table names from file-base SQLite database."); qFatal("Cannot obtain list of table names from file-base SQLite database.");
} }
@ -271,23 +275,19 @@ QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
} }
qDebug("Copying data from file-based database into working in-memory database."); qDebug("Copying data from file-based database into working in-memory database.");
// Detach database and finish. // Detach database and finish.
copy_contents.exec(QSL("DETACH 'storage'")); copy_contents.exec(QSL("DETACH 'storage'"));
copy_contents.finish(); copy_contents.finish();
query_db.finish(); query_db.finish();
} }
// Everything is initialized now. // Everything is initialized now.
m_sqliteInMemoryDatabaseInitialized = true; m_sqliteInMemoryDatabaseInitialized = true;
return database; return database;
} }
QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString& connection_name) { QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString& connection_name) {
finishRestoration(); finishRestoration();
// Prepare file paths. // Prepare file paths.
const QDir db_path(m_sqliteDatabaseFilePath); const QDir db_path(m_sqliteDatabaseFilePath);
QFile db_file(db_path.absoluteFilePath(APP_DB_SQLITE_FILE)); QFile db_file(db_path.absoluteFilePath(APP_DB_SQLITE_FILE));
@ -305,7 +305,6 @@ QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString &c
// Folders are created. Create new QSQLDatabase object. // Folders are created. Create new QSQLDatabase object.
QSqlDatabase database; QSqlDatabase database;
database = QSqlDatabase::addDatabase(APP_DB_SQLITE_DRIVER, connection_name); database = QSqlDatabase::addDatabase(APP_DB_SQLITE_DRIVER, connection_name);
database.setDatabaseName(db_file.fileName()); database.setDatabaseName(db_file.fileName());
@ -313,9 +312,9 @@ QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString &c
qFatal("File-based SQLite database was NOT opened. Delivered error message: '%s'", qFatal("File-based SQLite database was NOT opened. Delivered error message: '%s'",
qPrintable(database.lastError().text())); qPrintable(database.lastError().text()));
} }
else { else {
QSqlQuery query_db(database); QSqlQuery query_db(database);
query_db.setForwardOnly(true); query_db.setForwardOnly(true);
query_db.exec(QSL("PRAGMA encoding = \"UTF-8\"")); query_db.exec(QSL("PRAGMA encoding = \"UTF-8\""));
query_db.exec(QSL("PRAGMA synchronous = OFF")); query_db.exec(QSL("PRAGMA synchronous = OFF"));
@ -328,7 +327,6 @@ QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString &c
// Sample query which checks for existence of tables. // Sample query which checks for existence of tables.
if (!query_db.exec(QSL("SELECT inf_value FROM Information WHERE inf_key = 'schema_version'"))) { if (!query_db.exec(QSL("SELECT inf_value FROM Information WHERE inf_key = 'schema_version'"))) {
qWarning("Error occurred. File-based SQLite database is not initialized. Initializing now."); qWarning("Error occurred. File-based SQLite database is not initialized. Initializing now.");
QFile file_init(APP_SQL_PATH + QDir::separator() + APP_DB_SQLITE_INIT); QFile file_init(APP_SQL_PATH + QDir::separator() + APP_DB_SQLITE_INIT);
if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) {
@ -354,6 +352,7 @@ QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString &c
query_db.finish(); query_db.finish();
qDebug("File-based SQLite database backend should be ready now."); qDebug("File-based SQLite database backend should be ready now.");
} }
else { else {
query_db.next(); query_db.next();
const QString installed_db_schema = query_db.value(0).toString(); const QString installed_db_schema = query_db.value(0).toString();
@ -365,6 +364,7 @@ QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString &c
qPrintable(installed_db_schema), qPrintable(installed_db_schema),
APP_DB_SCHEMA_VERSION); APP_DB_SCHEMA_VERSION);
} }
else { else {
qFatal("Database schema was not updated from '%s' to '%s' successully.", qFatal("Database schema was not updated from '%s' to '%s' successully.",
qPrintable(installed_db_schema), qPrintable(installed_db_schema),
@ -381,7 +381,6 @@ QSqlDatabase DatabaseFactory::sqliteInitializeFileBasedDatabase(const QString &c
// Everything is initialized now. // Everything is initialized now.
m_sqliteFileBasedDatabaseinitialized = true; m_sqliteFileBasedDatabaseinitialized = true;
return database; return database;
} }
@ -397,6 +396,7 @@ bool DatabaseFactory::sqliteUpdateDatabaseSchema(QSqlDatabase database, const QS
if (IOFactory::copyFile(sqliteDatabaseFilePath(), sqliteDatabaseFilePath() + ".bak")) { if (IOFactory::copyFile(sqliteDatabaseFilePath(), sqliteDatabaseFilePath() + ".bak")) {
qDebug("Creating backup of SQLite DB file."); qDebug("Creating backup of SQLite DB file.");
} }
else { else {
qFatal("Creation of backup SQLite DB file failed."); qFatal("Creation of backup SQLite DB file failed.");
} }
@ -501,9 +501,11 @@ QString DatabaseFactory::humanDriverName(const QString &driver_code) const {
if (driver_code == APP_DB_SQLITE_DRIVER) { if (driver_code == APP_DB_SQLITE_DRIVER) {
return humanDriverName(SQLITE); return humanDriverName(SQLITE);
} }
else if (driver_code == APP_DB_MYSQL_DRIVER) { else if (driver_code == APP_DB_MYSQL_DRIVER) {
return humanDriverName(MYSQL); return humanDriverName(MYSQL);
} }
else { else {
return humanDriverName(SQLITE); return humanDriverName(SQLITE);
} }
@ -518,6 +520,7 @@ QString DatabaseFactory::obtainBeginTransactionSql() const {
if (m_activeDatabaseDriver == DatabaseFactory::SQLITE || m_activeDatabaseDriver == DatabaseFactory::SQLITE_MEMORY) { if (m_activeDatabaseDriver == DatabaseFactory::SQLITE || m_activeDatabaseDriver == DatabaseFactory::SQLITE_MEMORY) {
return QSL("BEGIN IMMEDIATE TRANSACTION;"); return QSL("BEGIN IMMEDIATE TRANSACTION;");
} }
else { else {
return QSL("START TRANSACTION;"); return QSL("START TRANSACTION;");
} }
@ -525,14 +528,11 @@ QString DatabaseFactory::obtainBeginTransactionSql() const {
void DatabaseFactory::sqliteSaveMemoryDatabase() { void DatabaseFactory::sqliteSaveMemoryDatabase() {
qDebug("Saving in-memory working database back to persistent file-based storage."); qDebug("Saving in-memory working database back to persistent file-based storage.");
QSqlDatabase database = sqliteConnection(objectName(), StrictlyInMemory); QSqlDatabase database = sqliteConnection(objectName(), StrictlyInMemory);
QSqlDatabase file_database = sqliteConnection(objectName(), StrictlyFileBased); QSqlDatabase file_database = sqliteConnection(objectName(), StrictlyFileBased);
QSqlQuery copy_contents(database); QSqlQuery copy_contents(database);
// Attach database. // Attach database.
copy_contents.exec(QString(QSL("ATTACH DATABASE '%1' AS 'storage';")).arg(file_database.databaseName())); copy_contents.exec(QString(QSL("ATTACH DATABASE '%1' AS 'storage';")).arg(file_database.databaseName()));
// Copy all stuff. // Copy all stuff.
// WARNING: All tables belong here. // WARNING: All tables belong here.
QStringList tables; QStringList tables;
@ -542,6 +542,7 @@ void DatabaseFactory::sqliteSaveMemoryDatabase() {
tables.append(copy_contents.value(0).toString()); tables.append(copy_contents.value(0).toString());
} }
} }
else { else {
qFatal("Cannot obtain list of table names from file-base SQLite database."); qFatal("Cannot obtain list of table names from file-base SQLite database.");
} }
@ -562,22 +563,21 @@ void DatabaseFactory::determineDriver() {
if (db_driver == APP_DB_MYSQL_DRIVER && QSqlDatabase::isDriverAvailable(APP_DB_SQLITE_DRIVER)) { if (db_driver == APP_DB_MYSQL_DRIVER && QSqlDatabase::isDriverAvailable(APP_DB_SQLITE_DRIVER)) {
// User wants to use MySQL and MySQL is actually available. Use it. // User wants to use MySQL and MySQL is actually available. Use it.
m_activeDatabaseDriver = MYSQL; m_activeDatabaseDriver = MYSQL;
qDebug("Working database source was as MySQL database."); qDebug("Working database source was as MySQL database.");
} }
else { else {
// User wants to use SQLite, which is always available. Check if file-based // User wants to use SQLite, which is always available. Check if file-based
// or in-memory database will be used. // or in-memory database will be used.
if (qApp->settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool()) { if (qApp->settings()->value(GROUP(Database), SETTING(Database::UseInMemory)).toBool()) {
// Use in-memory SQLite database. // Use in-memory SQLite database.
m_activeDatabaseDriver = SQLITE_MEMORY; m_activeDatabaseDriver = SQLITE_MEMORY;
qDebug("Working database source was determined as SQLite in-memory database."); qDebug("Working database source was determined as SQLite in-memory database.");
} }
else { else {
// Use strictly file-base SQLite database. // Use strictly file-base SQLite database.
m_activeDatabaseDriver = SQLITE; m_activeDatabaseDriver = SQLITE;
qDebug("Working database source was determined as SQLite file-based database."); qDebug("Working database source was determined as SQLite file-based database.");
} }
@ -594,21 +594,21 @@ QSqlDatabase DatabaseFactory::mysqlConnection(const QString &connection_name) {
// Return initialized database. // Return initialized database.
return mysqlInitializeDatabase(connection_name); return mysqlInitializeDatabase(connection_name);
} }
else { else {
QSqlDatabase database; QSqlDatabase database;
if (QSqlDatabase::contains(connection_name)) { if (QSqlDatabase::contains(connection_name)) {
qDebug("MySQL connection '%s' is already active.", qPrintable(connection_name)); qDebug("MySQL connection '%s' is already active.", qPrintable(connection_name));
// This database connection was added previously, no need to // This database connection was added previously, no need to
// setup its properties. // setup its properties.
database = QSqlDatabase::database(connection_name); database = QSqlDatabase::database(connection_name);
} }
else { else {
// Database connection with this name does not exist // Database connection with this name does not exist
// yet, add it and set it up. // yet, add it and set it up.
database = QSqlDatabase::addDatabase(APP_DB_MYSQL_DRIVER, connection_name); database = QSqlDatabase::addDatabase(APP_DB_MYSQL_DRIVER, connection_name);
database.setHostName(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLHostname)).toString()); database.setHostName(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLHostname)).toString());
database.setPort(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLPort)).toInt()); database.setPort(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLPort)).toInt());
database.setUserName(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLUsername)).toString()); database.setUserName(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLUsername)).toString());
@ -620,6 +620,7 @@ QSqlDatabase DatabaseFactory::mysqlConnection(const QString &connection_name) {
qFatal("MySQL database was NOT opened. Delivered error message: '%s'.", qFatal("MySQL database was NOT opened. Delivered error message: '%s'.",
qPrintable(database.lastError().text())); qPrintable(database.lastError().text()));
} }
else { else {
qDebug("MySQL database connection '%s' to file '%s' seems to be established.", qDebug("MySQL database connection '%s' to file '%s' seems to be established.",
qPrintable(connection_name), qPrintable(connection_name),
@ -634,7 +635,6 @@ QSqlDatabase DatabaseFactory::mysqlInitializeDatabase(const QString &connection_
// Folders are created. Create new QSQLDatabase object. // Folders are created. Create new QSQLDatabase object.
QSqlDatabase database = QSqlDatabase::addDatabase(APP_DB_MYSQL_DRIVER, connection_name); QSqlDatabase database = QSqlDatabase::addDatabase(APP_DB_MYSQL_DRIVER, connection_name);
const QString database_name = qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLDatabase)).toString(); const QString database_name = qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLDatabase)).toString();
database.setHostName(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLHostname)).toString()); database.setHostName(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLHostname)).toString());
database.setPort(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLPort)).toInt()); database.setPort(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLPort)).toInt());
database.setUserName(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLUsername)).toString()); database.setUserName(qApp->settings()->value(GROUP(Database), SETTING(Database::MySQLUsername)).toString());
@ -642,7 +642,6 @@ QSqlDatabase DatabaseFactory::mysqlInitializeDatabase(const QString &connection_
if (!database.open()) { if (!database.open()) {
qCritical("MySQL database was NOT opened. Delivered error message: '%s'", qPrintable(database.lastError().text())); qCritical("MySQL database was NOT opened. Delivered error message: '%s'", qPrintable(database.lastError().text()));
// Now, we will display error warning and return SQLite connection. // Now, we will display error warning and return SQLite connection.
// Also, we set the SQLite driver as active one. // Also, we set the SQLite driver as active one.
qApp->settings()->setValue(GROUP(Database), Database::ActiveDriver, APP_DB_SQLITE_DRIVER); qApp->settings()->setValue(GROUP(Database), Database::ActiveDriver, APP_DB_SQLITE_DRIVER);
@ -650,9 +649,9 @@ QSqlDatabase DatabaseFactory::mysqlInitializeDatabase(const QString &connection_
MessageBox::show(nullptr, QMessageBox::Critical, tr("MySQL database not available"), MessageBox::show(nullptr, QMessageBox::Critical, tr("MySQL database not available"),
tr("%1 cannot use MySQL storage, it is not available. %1 is now switching to SQLite database. Start your MySQL server " tr("%1 cannot use MySQL storage, it is not available. %1 is now switching to SQLite database. Start your MySQL server "
"and make adjustments in application settings.").arg(APP_NAME)); "and make adjustments in application settings.").arg(APP_NAME));
return connection(objectName(), FromSettings); return connection(objectName(), FromSettings);
} }
else { else {
QSqlQuery query_db(database); QSqlQuery query_db(database);
query_db.setForwardOnly(true); query_db.setForwardOnly(true);
@ -660,7 +659,6 @@ QSqlDatabase DatabaseFactory::mysqlInitializeDatabase(const QString &connection_
if (!query_db.exec(QString("USE %1").arg(database_name)) || !query_db.exec(QSL("SELECT inf_value FROM Information WHERE inf_key = 'schema_version'"))) { if (!query_db.exec(QString("USE %1").arg(database_name)) || !query_db.exec(QSL("SELECT inf_value FROM Information WHERE inf_key = 'schema_version'"))) {
// If no "rssguard" database exists or schema version is wrong, then initialize it. // If no "rssguard" database exists or schema version is wrong, then initialize it.
qWarning("Error occurred. MySQL database is not initialized. Initializing now."); qWarning("Error occurred. MySQL database is not initialized. Initializing now.");
QFile file_init(APP_SQL_PATH + QDir::separator() + APP_DB_MYSQL_INIT); QFile file_init(APP_SQL_PATH + QDir::separator() + APP_DB_MYSQL_INIT);
if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) { if (!file_init.open(QIODevice::ReadOnly | QIODevice::Text)) {
@ -686,10 +684,10 @@ QSqlDatabase DatabaseFactory::mysqlInitializeDatabase(const QString &connection_
database.commit(); database.commit();
qDebug("MySQL database backend should be ready now."); qDebug("MySQL database backend should be ready now.");
} }
else { else {
// Database was previously initialized. Now just check the schema version. // Database was previously initialized. Now just check the schema version.
query_db.next(); query_db.next();
const QString installed_db_schema = query_db.value(0).toString(); const QString installed_db_schema = query_db.value(0).toString();
if (installed_db_schema < APP_DB_SCHEMA_VERSION) { if (installed_db_schema < APP_DB_SCHEMA_VERSION) {
@ -697,8 +695,8 @@ QSqlDatabase DatabaseFactory::mysqlInitializeDatabase(const QString &connection_
qDebug("Database schema was updated from '%s' to '%s' successully or it is already up to date.", qDebug("Database schema was updated from '%s' to '%s' successully or it is already up to date.",
qPrintable(installed_db_schema), qPrintable(installed_db_schema),
APP_DB_SCHEMA_VERSION); APP_DB_SCHEMA_VERSION);
} }
else { else {
qFatal("Database schema was not updated from '%s' to '%s' successully.", qFatal("Database schema was not updated from '%s' to '%s' successully.",
qPrintable(installed_db_schema), qPrintable(installed_db_schema),
@ -712,14 +710,12 @@ QSqlDatabase DatabaseFactory::mysqlInitializeDatabase(const QString &connection_
// Everything is initialized now. // Everything is initialized now.
m_mysqlDatabaseInitialized = true; m_mysqlDatabaseInitialized = true;
return database; return database;
} }
bool DatabaseFactory::mysqlVacuumDatabase() { bool DatabaseFactory::mysqlVacuumDatabase() {
QSqlDatabase database = mysqlConnection(objectName()); QSqlDatabase database = mysqlConnection(objectName());
QSqlQuery query_vacuum(database); QSqlQuery query_vacuum(database);
return query_vacuum.exec(QSL("OPTIMIZE TABLE rssguard.feeds;")) && query_vacuum.exec(QSL("OPTIMIZE TABLE rssguard.messages;")); return query_vacuum.exec(QSL("OPTIMIZE TABLE rssguard.feeds;")) && query_vacuum.exec(QSL("OPTIMIZE TABLE rssguard.messages;"));
} }
@ -732,15 +728,16 @@ QSqlDatabase DatabaseFactory::sqliteConnection(const QString &connection_name, D
// It is not initialized yet. // It is not initialized yet.
return sqliteInitializeInMemoryDatabase(); return sqliteInitializeInMemoryDatabase();
} }
else { else {
QSqlDatabase database = QSqlDatabase::database(); QSqlDatabase database = QSqlDatabase::database();
database.setDatabaseName(QSL(":memory:")); database.setDatabaseName(QSL(":memory:"));
if (!database.isOpen() && !database.open()) { if (!database.isOpen() && !database.open()) {
qFatal("In-memory SQLite database was NOT opened. Delivered error message: '%s'.", qFatal("In-memory SQLite database was NOT opened. Delivered error message: '%s'.",
qPrintable(database.lastError().text())); qPrintable(database.lastError().text()));
} }
else { else {
qDebug("In-memory SQLite database connection seems to be established."); qDebug("In-memory SQLite database connection seems to be established.");
} }
@ -748,30 +745,30 @@ QSqlDatabase DatabaseFactory::sqliteConnection(const QString &connection_name, D
return database; return database;
} }
} }
else { else {
// We request file-based database. // We request file-based database.
if (!m_sqliteFileBasedDatabaseinitialized) { if (!m_sqliteFileBasedDatabaseinitialized) {
// File-based database is not yet initialised. // File-based database is not yet initialised.
return sqliteInitializeFileBasedDatabase(connection_name); return sqliteInitializeFileBasedDatabase(connection_name);
} }
else { else {
QSqlDatabase database; QSqlDatabase database;
if (QSqlDatabase::contains(connection_name)) { if (QSqlDatabase::contains(connection_name)) {
qDebug("SQLite connection '%s' is already active.", qPrintable(connection_name)); qDebug("SQLite connection '%s' is already active.", qPrintable(connection_name));
// This database connection was added previously, no need to // This database connection was added previously, no need to
// setup its properties. // setup its properties.
database = QSqlDatabase::database(connection_name); database = QSqlDatabase::database(connection_name);
} }
else { else {
// Database connection with this name does not exist // Database connection with this name does not exist
// yet, add it and set it up. // yet, add it and set it up.
database = QSqlDatabase::addDatabase(APP_DB_SQLITE_DRIVER, connection_name); database = QSqlDatabase::addDatabase(APP_DB_SQLITE_DRIVER, connection_name);
const QDir db_path(m_sqliteDatabaseFilePath); const QDir db_path(m_sqliteDatabaseFilePath);
QFile db_file(db_path.absoluteFilePath(APP_DB_SQLITE_FILE)); QFile db_file(db_path.absoluteFilePath(APP_DB_SQLITE_FILE));
// Setup database file path. // Setup database file path.
database.setDatabaseName(db_file.fileName()); database.setDatabaseName(db_file.fileName());
} }
@ -780,6 +777,7 @@ QSqlDatabase DatabaseFactory::sqliteConnection(const QString &connection_name, D
qFatal("File-based SQLite database was NOT opened. Delivered error message: '%s'.", qFatal("File-based SQLite database was NOT opened. Delivered error message: '%s'.",
qPrintable(database.lastError().text())); qPrintable(database.lastError().text()));
} }
else { else {
qDebug("File-based SQLite database connection '%s' to file '%s' seems to be established.", qDebug("File-based SQLite database connection '%s' to file '%s' seems to be established.",
qPrintable(connection_name), qPrintable(connection_name),
@ -797,16 +795,17 @@ bool DatabaseFactory::sqliteVacuumDatabase() {
if (m_activeDatabaseDriver == SQLITE) { if (m_activeDatabaseDriver == SQLITE) {
database = sqliteConnection(objectName(), StrictlyFileBased); database = sqliteConnection(objectName(), StrictlyFileBased);
} }
else if (m_activeDatabaseDriver == SQLITE_MEMORY) { else if (m_activeDatabaseDriver == SQLITE_MEMORY) {
sqliteSaveMemoryDatabase(); sqliteSaveMemoryDatabase();
database = sqliteConnection(objectName(), StrictlyFileBased); database = sqliteConnection(objectName(), StrictlyFileBased);
} }
else { else {
return false; return false;
} }
QSqlQuery query_vacuum(database); QSqlQuery query_vacuum(database);
return query_vacuum.exec(QSL("VACUUM")); return query_vacuum.exec(QSL("VACUUM"));
} }

View File

@ -41,7 +41,6 @@
bool DatabaseQueries::markMessagesReadUnread(QSqlDatabase db, const QStringList& ids, RootItem::ReadStatus read) { bool DatabaseQueries::markMessagesReadUnread(QSqlDatabase db, const QStringList& ids, RootItem::ReadStatus read) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
return q.exec(QString(QSL("UPDATE Messages SET is_read = %2 WHERE id IN (%1);")) return q.exec(QString(QSL("UPDATE Messages SET is_read = %2 WHERE id IN (%1);"))
.arg(ids.join(QSL(", ")), read == RootItem::Read ? QSL("1") : QSL("0"))); .arg(ids.join(QSL(", ")), read == RootItem::Read ? QSL("1") : QSL("0")));
} }
@ -57,7 +56,6 @@ bool DatabaseQueries::markMessageImportant(QSqlDatabase db, int id, RootItem::Im
q.bindValue(QSL(":id"), id); q.bindValue(QSL(":id"), id);
q.bindValue(QSL(":important"), (int) importance); q.bindValue(QSL(":important"), (int) importance);
// Commit changes. // Commit changes.
return q.exec(); return q.exec();
} }
@ -67,10 +65,8 @@ bool DatabaseQueries::markFeedsReadUnread(QSqlDatabase db, const QStringList &id
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QString("UPDATE Messages SET is_read = :read " q.prepare(QString("UPDATE Messages SET is_read = :read "
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;").arg(ids.join(QSL(", ")))); "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;").arg(ids.join(QSL(", "))));
q.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0); q.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0);
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
return q.exec(); return q.exec();
} }
@ -79,10 +75,8 @@ bool DatabaseQueries::markBinReadUnread(QSqlDatabase db, int account_id, RootIte
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare("UPDATE Messages SET is_read = :read " q.prepare("UPDATE Messages SET is_read = :read "
"WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;"); "WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;");
q.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0); q.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0);
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
return q.exec(); return q.exec();
} }
@ -90,31 +84,26 @@ bool DatabaseQueries::markAccountReadUnread(QSqlDatabase db, int account_id, Roo
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("UPDATE Messages SET is_read = :read WHERE is_pdeleted = 0 AND account_id = :account_id;")); q.prepare(QSL("UPDATE Messages SET is_read = :read WHERE is_pdeleted = 0 AND account_id = :account_id;"));
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
q.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0); q.bindValue(QSL(":read"), read == RootItem::Read ? 1 : 0);
return q.exec(); return q.exec();
} }
bool DatabaseQueries::switchMessagesImportance(QSqlDatabase db, const QStringList& ids) { bool DatabaseQueries::switchMessagesImportance(QSqlDatabase db, const QStringList& ids) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
return q.exec(QString(QSL("UPDATE Messages SET is_important = NOT is_important WHERE id IN (%1);")).arg(ids.join(QSL(", ")))); return q.exec(QString(QSL("UPDATE Messages SET is_important = NOT is_important WHERE id IN (%1);")).arg(ids.join(QSL(", "))));
} }
bool DatabaseQueries::permanentlyDeleteMessages(QSqlDatabase db, const QStringList& ids) { bool DatabaseQueries::permanentlyDeleteMessages(QSqlDatabase db, const QStringList& ids) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
return q.exec(QString(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE id IN (%1);")).arg(ids.join(QSL(", ")))); return q.exec(QString(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE id IN (%1);")).arg(ids.join(QSL(", "))));
} }
bool DatabaseQueries::deleteOrRestoreMessagesToFromBin(QSqlDatabase db, const QStringList& ids, bool deleted) { bool DatabaseQueries::deleteOrRestoreMessagesToFromBin(QSqlDatabase db, const QStringList& ids, bool deleted) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
return q.exec(QString(QSL("UPDATE Messages SET is_deleted = %2, is_pdeleted = %3 WHERE id IN (%1);")).arg(ids.join(QSL(", ")), return q.exec(QString(QSL("UPDATE Messages SET is_deleted = %2, is_pdeleted = %3 WHERE id IN (%1);")).arg(ids.join(QSL(", ")),
QString::number(deleted ? 1 : 0), QString::number(deleted ? 1 : 0),
QString::number(0))); QString::number(0)));
@ -126,7 +115,6 @@ bool DatabaseQueries::restoreBin(QSqlDatabase db, int account_id) {
q.prepare("UPDATE Messages SET is_deleted = 0 " q.prepare("UPDATE Messages SET is_deleted = 0 "
"WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;"); "WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;");
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
return q.exec(); return q.exec();
} }
@ -134,7 +122,6 @@ bool DatabaseQueries::purgeImportantMessages(QSqlDatabase db) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM Messages WHERE is_important = 1;")); q.prepare(QSL("DELETE FROM Messages WHERE is_important = 1;"));
return q.exec(); return q.exec();
} }
@ -143,40 +130,31 @@ bool DatabaseQueries::purgeReadMessages(QSqlDatabase db) {
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM Messages WHERE is_important = :is_important AND is_deleted = :is_deleted AND is_read = :is_read;")); q.prepare(QSL("DELETE FROM Messages WHERE is_important = :is_important AND is_deleted = :is_deleted AND is_read = :is_read;"));
q.bindValue(QSL(":is_read"), 1); q.bindValue(QSL(":is_read"), 1);
// Remove only messages which are NOT in recycle bin. // Remove only messages which are NOT in recycle bin.
q.bindValue(QSL(":is_deleted"), 0); q.bindValue(QSL(":is_deleted"), 0);
// Remove only messages which are NOT starred. // Remove only messages which are NOT starred.
q.bindValue(QSL(":is_important"), 0); q.bindValue(QSL(":is_important"), 0);
return q.exec(); return q.exec();
} }
bool DatabaseQueries::purgeOldMessages(QSqlDatabase db, int older_than_days) { bool DatabaseQueries::purgeOldMessages(QSqlDatabase db, int older_than_days) {
QSqlQuery q(db); QSqlQuery q(db);
const qint64 since_epoch = QDateTime::currentDateTimeUtc().addDays(-older_than_days).toMSecsSinceEpoch(); const qint64 since_epoch = QDateTime::currentDateTimeUtc().addDays(-older_than_days).toMSecsSinceEpoch();
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM Messages WHERE is_important = :is_important AND date_created < :date_created;")); q.prepare(QSL("DELETE FROM Messages WHERE is_important = :is_important AND date_created < :date_created;"));
q.bindValue(QSL(":date_created"), since_epoch); q.bindValue(QSL(":date_created"), since_epoch);
// Remove only messages which are NOT starred. // Remove only messages which are NOT starred.
q.bindValue(QSL(":is_important"), 0); q.bindValue(QSL(":is_important"), 0);
return q.exec(); return q.exec();
} }
bool DatabaseQueries::purgeRecycleBin(QSqlDatabase db) { bool DatabaseQueries::purgeRecycleBin(QSqlDatabase db) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM Messages WHERE is_important = :is_important AND is_deleted = :is_deleted;")); q.prepare(QSL("DELETE FROM Messages WHERE is_important = :is_important AND is_deleted = :is_deleted;"));
q.bindValue(QSL(":is_deleted"), 1); q.bindValue(QSL(":is_deleted"), 1);
// Remove only messages which are NOT starred. // Remove only messages which are NOT starred.
q.bindValue(QSL(":is_important"), 0); q.bindValue(QSL(":is_important"), 0);
return q.exec(); return q.exec();
} }
@ -191,6 +169,7 @@ QMap<int,QPair<int,int> > DatabaseQueries::getMessageCountsForCategory(QSqlDatab
"WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id " "WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id "
"GROUP BY feed;"); "GROUP BY feed;");
} }
else { else {
q.prepare("SELECT feed, sum((is_read + 1) % 2) FROM Messages " q.prepare("SELECT feed, sum((is_read + 1) % 2) FROM Messages "
"WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id " "WHERE feed IN (SELECT custom_id FROM Feeds WHERE category = :category AND account_id = :account_id) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id "
@ -207,9 +186,9 @@ QMap<int,QPair<int,int> > DatabaseQueries::getMessageCountsForCategory(QSqlDatab
if (including_total_counts) { if (including_total_counts) {
int total_count = q.value(2).toInt(); int total_count = q.value(2).toInt();
counts.insert(feed_id, QPair<int, int>(unread_count, total_count)); counts.insert(feed_id, QPair<int, int>(unread_count, total_count));
} }
else { else {
counts.insert(feed_id, QPair<int, int>(unread_count, 0)); counts.insert(feed_id, QPair<int, int>(unread_count, 0));
} }
@ -219,6 +198,7 @@ QMap<int,QPair<int,int> > DatabaseQueries::getMessageCountsForCategory(QSqlDatab
*ok = true; *ok = true;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -239,6 +219,7 @@ QMap<int,QPair<int,int> > DatabaseQueries::getMessageCountsForAccount(QSqlDataba
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id " "WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id "
"GROUP BY feed;"); "GROUP BY feed;");
} }
else { else {
q.prepare("SELECT feed, sum((is_read + 1) % 2) FROM Messages " q.prepare("SELECT feed, sum((is_read + 1) % 2) FROM Messages "
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id " "WHERE is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id "
@ -254,9 +235,9 @@ QMap<int,QPair<int,int> > DatabaseQueries::getMessageCountsForAccount(QSqlDataba
if (including_total_counts) { if (including_total_counts) {
int total_count = q.value(2).toInt(); int total_count = q.value(2).toInt();
counts.insert(feed_id, QPair<int, int>(unread_count, total_count)); counts.insert(feed_id, QPair<int, int>(unread_count, total_count));
} }
else { else {
counts.insert(feed_id, QPair<int, int>(unread_count, 0)); counts.insert(feed_id, QPair<int, int>(unread_count, 0));
} }
@ -266,6 +247,7 @@ QMap<int,QPair<int,int> > DatabaseQueries::getMessageCountsForAccount(QSqlDataba
*ok = true; *ok = true;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -284,6 +266,7 @@ int DatabaseQueries::getMessageCountsForFeed(QSqlDatabase db, int feed_custom_id
q.prepare("SELECT count(*) FROM Messages " q.prepare("SELECT count(*) FROM Messages "
"WHERE feed = :feed AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;"); "WHERE feed = :feed AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;");
} }
else { else {
q.prepare("SELECT count(*) FROM Messages " q.prepare("SELECT count(*) FROM Messages "
"WHERE feed = :feed AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 0 AND account_id = :account_id;"); "WHERE feed = :feed AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 0 AND account_id = :account_id;");
@ -299,6 +282,7 @@ int DatabaseQueries::getMessageCountsForFeed(QSqlDatabase db, int feed_custom_id
return q.value(0).toInt(); return q.value(0).toInt();
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -316,6 +300,7 @@ int DatabaseQueries::getMessageCountsForBin(QSqlDatabase db, int account_id, boo
q.prepare("SELECT count(*) FROM Messages " q.prepare("SELECT count(*) FROM Messages "
"WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;"); "WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;");
} }
else { else {
q.prepare("SELECT count(*) FROM Messages " q.prepare("SELECT count(*) FROM Messages "
"WHERE is_read = 0 AND is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;"); "WHERE is_read = 0 AND is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;");
@ -330,6 +315,7 @@ int DatabaseQueries::getMessageCountsForBin(QSqlDatabase db, int account_id, boo
return q.value(0).toInt(); return q.value(0).toInt();
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -346,7 +332,6 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForFeed(QSqlDatabase db, int
q.prepare("SELECT * " q.prepare("SELECT * "
"FROM Messages " "FROM Messages "
"WHERE is_deleted = 0 AND is_pdeleted = 0 AND feed = :feed AND account_id = :account_id;"); "WHERE is_deleted = 0 AND is_pdeleted = 0 AND feed = :feed AND account_id = :account_id;");
q.bindValue(QSL(":feed"), feed_custom_id); q.bindValue(QSL(":feed"), feed_custom_id);
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
@ -364,6 +349,7 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForFeed(QSqlDatabase db, int
*ok = true; *ok = true;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -380,7 +366,6 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForBin(QSqlDatabase db, int
q.prepare("SELECT * " q.prepare("SELECT * "
"FROM Messages " "FROM Messages "
"WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;"); "WHERE is_deleted = 1 AND is_pdeleted = 0 AND account_id = :account_id;");
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
if (q.exec()) { if (q.exec()) {
@ -397,6 +382,7 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForBin(QSqlDatabase db, int
*ok = true; *ok = true;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -429,6 +415,7 @@ QList<Message> DatabaseQueries::getUndeletedMessagesForAccount(QSqlDatabase db,
*ok = true; *ok = true;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -452,18 +439,15 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
} }
bool use_transactions = qApp->settings()->value(GROUP(Database), SETTING(Database::UseTransactions)).toBool(); bool use_transactions = qApp->settings()->value(GROUP(Database), SETTING(Database::UseTransactions)).toBool();
// Does not make any difference, since each feed now has // Does not make any difference, since each feed now has
// its own "custom ID" (standard feeds have their custom ID equal to primary key ID). // its own "custom ID" (standard feeds have their custom ID equal to primary key ID).
int updated_messages = 0; int updated_messages = 0;
// Prepare queries. // Prepare queries.
QSqlQuery query_select_with_url(db); QSqlQuery query_select_with_url(db);
QSqlQuery query_select_with_id(db); QSqlQuery query_select_with_id(db);
QSqlQuery query_update(db); QSqlQuery query_update(db);
QSqlQuery query_insert(db); QSqlQuery query_insert(db);
QSqlQuery query_begin_transaction(db); QSqlQuery query_begin_transaction(db);
// Here we have query which will check for existence of the "same" message in given feed. // Here we have query which will check for existence of the "same" message in given feed.
// The two message are the "same" if: // The two message are the "same" if:
// 1) they belong to the same feed AND, // 1) they belong to the same feed AND,
@ -472,19 +456,16 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
query_select_with_url.setForwardOnly(true); query_select_with_url.setForwardOnly(true);
query_select_with_url.prepare("SELECT id, date_created, is_read, is_important, contents FROM Messages " query_select_with_url.prepare("SELECT id, date_created, is_read, is_important, contents FROM Messages "
"WHERE feed = :feed AND title = :title AND url = :url AND author = :author AND account_id = :account_id;"); "WHERE feed = :feed AND title = :title AND url = :url AND author = :author AND account_id = :account_id;");
// When we have custom ID of the message, we can check directly for existence // When we have custom ID of the message, we can check directly for existence
// of that particular message. // of that particular message.
query_select_with_id.setForwardOnly(true); query_select_with_id.setForwardOnly(true);
query_select_with_id.prepare("SELECT id, date_created, is_read, is_important, contents FROM Messages " query_select_with_id.prepare("SELECT id, date_created, is_read, is_important, contents FROM Messages "
"WHERE custom_id = :custom_id AND account_id = :account_id;"); "WHERE custom_id = :custom_id AND account_id = :account_id;");
// Used to insert new messages. // Used to insert new messages.
query_insert.setForwardOnly(true); query_insert.setForwardOnly(true);
query_insert.prepare("INSERT INTO Messages " query_insert.prepare("INSERT INTO Messages "
"(feed, title, is_read, is_important, url, author, date_created, contents, enclosures, custom_id, custom_hash, account_id) " "(feed, title, is_read, is_important, url, author, date_created, contents, enclosures, custom_id, custom_hash, account_id) "
"VALUES (:feed, :title, :is_read, :is_important, :url, :author, :date_created, :contents, :enclosures, :custom_id, :custom_hash, :account_id);"); "VALUES (:feed, :title, :is_read, :is_important, :url, :author, :date_created, :contents, :enclosures, :custom_id, :custom_hash, :account_id);");
// Used to update existing messages. // Used to update existing messages.
query_update.setForwardOnly(true); query_update.setForwardOnly(true);
query_update.prepare("UPDATE Messages " query_update.prepare("UPDATE Messages "
@ -501,13 +482,13 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
if (message.m_url.startsWith(QL1S("//"))) { if (message.m_url.startsWith(QL1S("//"))) {
message.m_url = QString(URI_SCHEME_HTTP) + message.m_url.mid(2); message.m_url = QString(URI_SCHEME_HTTP) + message.m_url.mid(2);
} }
else if (message.m_url.startsWith(QL1S("/"))) { else if (message.m_url.startsWith(QL1S("/"))) {
QString new_message_url = QUrl(url).toString(QUrl::RemoveUserInfo | QString new_message_url = QUrl(url).toString(QUrl::RemoveUserInfo |
QUrl::RemovePath | QUrl::RemovePath |
QUrl::RemoveQuery | QUrl::RemoveQuery |
QUrl::RemoveFilename | QUrl::RemoveFilename |
QUrl::StripTrailingSlash); QUrl::StripTrailingSlash);
new_message_url += message.m_url; new_message_url += message.m_url;
message.m_url = new_message_url; message.m_url = new_message_url;
} }
@ -534,12 +515,14 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
is_important_existing_message = query_select_with_url.value(3).toBool(); is_important_existing_message = query_select_with_url.value(3).toBool();
contents_existing_message = query_select_with_url.value(4).toString(); contents_existing_message = query_select_with_url.value(4).toString();
} }
else if (query_select_with_url.lastError().isValid()) { else if (query_select_with_url.lastError().isValid()) {
qWarning("Failed to check for existing message in DB via URL: '%s'.", qPrintable(query_select_with_url.lastError().text())); qWarning("Failed to check for existing message in DB via URL: '%s'.", qPrintable(query_select_with_url.lastError().text()));
} }
query_select_with_url.finish(); query_select_with_url.finish();
} }
else { else {
// We can recognize existing messages via their custom ID. // We can recognize existing messages via their custom ID.
// NOTE: This concerns messages from custom accounts, like TT-RSS or ownCloud News. // NOTE: This concerns messages from custom accounts, like TT-RSS or ownCloud News.
@ -553,6 +536,7 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
is_important_existing_message = query_select_with_id.value(3).toBool(); is_important_existing_message = query_select_with_id.value(3).toBool();
contents_existing_message = query_select_with_id.value(4).toString(); contents_existing_message = query_select_with_id.value(4).toString();
} }
else if (query_select_with_id.lastError().isValid()) { else if (query_select_with_id.lastError().isValid()) {
qDebug("Failed to check for existing message in DB via ID: '%s'.", qPrintable(query_select_with_id.lastError().text())); qDebug("Failed to check for existing message in DB via ID: '%s'.", qPrintable(query_select_with_id.lastError().text()));
} }
@ -567,7 +551,8 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
// Now, we update it if at least one of next conditions is true: // Now, we update it if at least one of next conditions is true:
// 1) Message has custom ID AND (its date OR read status OR starred status are changed). // 1) Message has custom ID AND (its date OR read status OR starred status are changed).
// 2) Message has its date fetched from feed AND its date is different from date in DB and contents is changed. // 2) Message has its date fetched from feed AND its date is different from date in DB and contents is changed.
if (/* 1 */ (!message.m_customId.isEmpty() && (message.m_created.toMSecsSinceEpoch() != date_existing_message || message.m_isRead != is_read_existing_message || message.m_isImportant != is_important_existing_message)) || if (/* 1 */ (!message.m_customId.isEmpty() && (message.m_created.toMSecsSinceEpoch() != date_existing_message || message.m_isRead != is_read_existing_message
|| message.m_isImportant != is_important_existing_message)) ||
/* 2 */ (message.m_createdFromFeed && message.m_created.toMSecsSinceEpoch() != date_existing_message && message.m_contents != contents_existing_message)) { /* 2 */ (message.m_createdFromFeed && message.m_created.toMSecsSinceEpoch() != date_existing_message && message.m_contents != contents_existing_message)) {
// Message exists, it is changed, update it. // Message exists, it is changed, update it.
query_update.bindValue(QSL(":title"), message.m_title); query_update.bindValue(QSL(":title"), message.m_title);
@ -579,12 +564,12 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
query_update.bindValue(QSL(":contents"), message.m_contents); query_update.bindValue(QSL(":contents"), message.m_contents);
query_update.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures)); query_update.bindValue(QSL(":enclosures"), Enclosures::encodeEnclosuresToString(message.m_enclosures));
query_update.bindValue(QSL(":id"), id_existing_message); query_update.bindValue(QSL(":id"), id_existing_message);
*any_message_changed = true; *any_message_changed = true;
if (query_update.exec() && !message.m_isRead) { if (query_update.exec() && !message.m_isRead) {
updated_messages++; updated_messages++;
} }
else if (query_update.lastError().isValid()) { else if (query_update.lastError().isValid()) {
qWarning("Failed to update message in DB: '%s'.", qPrintable(query_update.lastError().text())); qWarning("Failed to update message in DB: '%s'.", qPrintable(query_update.lastError().text()));
} }
@ -593,6 +578,7 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
qDebug("Updating message '%s' in DB.", qPrintable(message.m_title)); qDebug("Updating message '%s' in DB.", qPrintable(message.m_title));
} }
} }
else { else {
// Message with this URL is not fetched in this feed yet. // Message with this URL is not fetched in this feed yet.
query_insert.bindValue(QSL(":feed"), feed_custom_id); query_insert.bindValue(QSL(":feed"), feed_custom_id);
@ -612,6 +598,7 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
updated_messages++; updated_messages++;
qDebug("Added new message '%s' to DB.", qPrintable(message.m_title)); qDebug("Added new message '%s' to DB.", qPrintable(message.m_title));
} }
else if (query_insert.lastError().isValid()) { else if (query_insert.lastError().isValid()) {
qWarning("Failed to insert message to DB: '%s' - message title is '%s'.", qWarning("Failed to insert message to DB: '%s' - message title is '%s'.",
qPrintable(query_insert.lastError().text()), qPrintable(query_insert.lastError().text()),
@ -639,6 +626,7 @@ int DatabaseQueries::updateMessages(QSqlDatabase db,
updated_messages = 0; updated_messages = 0;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = true; *ok = true;
@ -655,19 +643,18 @@ bool DatabaseQueries::purgeMessagesFromBin(QSqlDatabase db, bool clear_only_read
if (clear_only_read) { if (clear_only_read) {
q.prepare(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_read = 1 AND is_deleted = 1 AND account_id = :account_id;")); q.prepare(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_read = 1 AND is_deleted = 1 AND account_id = :account_id;"));
} }
else { else {
q.prepare(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_deleted = 1 AND account_id = :account_id;")); q.prepare(QSL("UPDATE Messages SET is_pdeleted = 1 WHERE is_deleted = 1 AND account_id = :account_id;"));
} }
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
return q.exec(); return q.exec();
} }
bool DatabaseQueries::deleteAccount(QSqlDatabase db, int account_id) { bool DatabaseQueries::deleteAccount(QSqlDatabase db, int account_id) {
QSqlQuery query(db); QSqlQuery query(db);
query.setForwardOnly(true); query.setForwardOnly(true);
QStringList queries; QStringList queries;
queries << QSL("DELETE FROM Messages WHERE account_id = :account_id;") << queries << QSL("DELETE FROM Messages WHERE account_id = :account_id;") <<
QSL("DELETE FROM Feeds WHERE account_id = :account_id;") << QSL("DELETE FROM Feeds WHERE account_id = :account_id;") <<
@ -682,6 +669,7 @@ bool DatabaseQueries::deleteAccount(QSqlDatabase db, int account_id) {
qCritical("Removing of account from DB failed, this is critical: '%s'.", qPrintable(query.lastError().text())); qCritical("Removing of account from DB failed, this is critical: '%s'.", qPrintable(query.lastError().text()));
return false; return false;
} }
else { else {
query.finish(); query.finish();
} }
@ -698,20 +686,15 @@ bool DatabaseQueries::deleteAccountData(QSqlDatabase db, int account_id, bool de
if (delete_messages_too) { if (delete_messages_too) {
q.prepare(QSL("DELETE FROM Messages WHERE account_id = :account_id;")); q.prepare(QSL("DELETE FROM Messages WHERE account_id = :account_id;"));
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
result &= q.exec(); result &= q.exec();
} }
q.prepare(QSL("DELETE FROM Feeds WHERE account_id = :account_id;")); q.prepare(QSL("DELETE FROM Feeds WHERE account_id = :account_id;"));
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
result &= q.exec(); result &= q.exec();
q.prepare(QSL("DELETE FROM Categories WHERE account_id = :account_id;")); q.prepare(QSL("DELETE FROM Categories WHERE account_id = :account_id;"));
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
result &= q.exec(); result &= q.exec();
return result; return result;
} }
@ -724,6 +707,7 @@ bool DatabaseQueries::cleanFeeds(QSqlDatabase db, const QStringList &ids, bool c
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 1 AND account_id = :account_id;") "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND is_read = 1 AND account_id = :account_id;")
.arg(ids.join(QSL(", ")))); .arg(ids.join(QSL(", "))));
} }
else { else {
q.prepare(QString("UPDATE Messages SET is_deleted = :deleted " q.prepare(QString("UPDATE Messages SET is_deleted = :deleted "
"WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;") "WHERE feed IN (%1) AND is_deleted = 0 AND is_pdeleted = 0 AND account_id = :account_id;")
@ -737,6 +721,7 @@ bool DatabaseQueries::cleanFeeds(QSqlDatabase db, const QStringList &ids, bool c
qDebug("Cleaning of feeds failed: '%s'.", qPrintable(q.lastError().text())); qDebug("Cleaning of feeds failed: '%s'.", qPrintable(q.lastError().text()));
return false; return false;
} }
else { else {
return true; return true;
} }
@ -744,7 +729,6 @@ bool DatabaseQueries::cleanFeeds(QSqlDatabase db, const QStringList &ids, bool c
bool DatabaseQueries::purgeLeftoverMessages(QSqlDatabase db, int account_id) { bool DatabaseQueries::purgeLeftoverMessages(QSqlDatabase db, int account_id) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM Messages WHERE account_id = :account_id AND feed NOT IN (SELECT custom_id FROM Feeds WHERE account_id = :account_id);")); q.prepare(QSL("DELETE FROM Messages WHERE account_id = :account_id AND feed NOT IN (SELECT custom_id FROM Feeds WHERE account_id = :account_id);"));
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
@ -753,6 +737,7 @@ bool DatabaseQueries::purgeLeftoverMessages(QSqlDatabase db, int account_id) {
qWarning("Removing of left over messages failed: '%s'.", qPrintable(q.lastError().text())); qWarning("Removing of left over messages failed: '%s'.", qPrintable(q.lastError().text()));
return false; return false;
} }
else { else {
return true; return true;
} }
@ -779,13 +764,14 @@ bool DatabaseQueries::storeAccountTree(QSqlDatabase db, RootItem *tree_root, int
if (query_category.exec()) { if (query_category.exec()) {
child->setId(query_category.lastInsertId().toInt()); child->setId(query_category.lastInsertId().toInt());
} }
else { else {
return false; return false;
} }
} }
else if (child->kind() == RootItemKind::Feed) { else if (child->kind() == RootItemKind::Feed) {
Feed* feed = child->toFeed(); Feed* feed = child->toFeed();
query_feed.bindValue(QSL(":title"), feed->title()); query_feed.bindValue(QSL(":title"), feed->title());
query_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon())); query_feed.bindValue(QSL(":icon"), qApp->icons()->toByteArray(feed->icon()));
query_feed.bindValue(QSL(":category"), feed->parent()->customId()); query_feed.bindValue(QSL(":category"), feed->parent()->customId());
@ -798,6 +784,7 @@ bool DatabaseQueries::storeAccountTree(QSqlDatabase db, RootItem *tree_root, int
if (query_feed.exec()) { if (query_feed.exec()) {
feed->setId(query_feed.lastInsertId().toInt()); feed->setId(query_feed.lastInsertId().toInt());
} }
else { else {
return false; return false;
} }
@ -817,6 +804,7 @@ QStringList DatabaseQueries::customIdsOfMessagesFromAccount(QSqlDatabase db, int
if (ok != nullptr) { if (ok != nullptr) {
*ok = q.exec(); *ok = q.exec();
} }
else { else {
q.exec(); q.exec();
} }
@ -838,6 +826,7 @@ QStringList DatabaseQueries::customIdsOfMessagesFromBin(QSqlDatabase db, int acc
if (ok != nullptr) { if (ok != nullptr) {
*ok = q.exec(); *ok = q.exec();
} }
else { else {
q.exec(); q.exec();
} }
@ -860,6 +849,7 @@ QStringList DatabaseQueries::customIdsOfMessagesFromFeed(QSqlDatabase db, int fe
if (ok != nullptr) { if (ok != nullptr) {
*ok = q.exec(); *ok = q.exec();
} }
else { else {
q.exec(); q.exec();
} }
@ -884,7 +874,6 @@ QList<ServiceRoot*> DatabaseQueries::getOwnCloudAccounts(QSqlDatabase db, bool *
root->network()->setAuthPassword(TextFactory::decrypt(query.value(2).toString())); root->network()->setAuthPassword(TextFactory::decrypt(query.value(2).toString()));
root->network()->setUrl(query.value(3).toString()); root->network()->setUrl(query.value(3).toString());
root->network()->setForceServerSideUpdate(query.value(4).toBool()); root->network()->setForceServerSideUpdate(query.value(4).toBool());
root->updateTitle(); root->updateTitle();
roots.append(root); roots.append(root);
} }
@ -893,6 +882,7 @@ QList<ServiceRoot*> DatabaseQueries::getOwnCloudAccounts(QSqlDatabase db, bool *
*ok = true; *ok = true;
} }
} }
else { else {
qWarning("OwnCloud: Getting list of activated accounts failed: '%s'.", qPrintable(query.lastError().text())); qWarning("OwnCloud: Getting list of activated accounts failed: '%s'.", qPrintable(query.lastError().text()));
@ -920,7 +910,6 @@ QList<ServiceRoot*> DatabaseQueries::getTtRssAccounts(QSqlDatabase db, bool *ok)
root->network()->setAuthPassword(TextFactory::decrypt(query.value(5).toString())); root->network()->setAuthPassword(TextFactory::decrypt(query.value(5).toString()));
root->network()->setUrl(query.value(6).toString()); root->network()->setUrl(query.value(6).toString());
root->network()->setForceServerSideUpdate(query.value(7).toBool()); root->network()->setForceServerSideUpdate(query.value(7).toBool());
root->updateTitle(); root->updateTitle();
roots.append(root); roots.append(root);
} }
@ -929,6 +918,7 @@ QList<ServiceRoot*> DatabaseQueries::getTtRssAccounts(QSqlDatabase db, bool *ok)
*ok = true; *ok = true;
} }
} }
else { else {
qWarning("TT-RSS: Getting list of activated accounts failed: '%s'.", qPrintable(query.lastError().text())); qWarning("TT-RSS: Getting list of activated accounts failed: '%s'.", qPrintable(query.lastError().text()));
@ -942,18 +932,15 @@ QList<ServiceRoot*> DatabaseQueries::getTtRssAccounts(QSqlDatabase db, bool *ok)
bool DatabaseQueries::deleteOwnCloudAccount(QSqlDatabase db, int account_id) { bool DatabaseQueries::deleteOwnCloudAccount(QSqlDatabase db, int account_id) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM OwnCloudAccounts WHERE id = :id;")); q.prepare(QSL("DELETE FROM OwnCloudAccounts WHERE id = :id;"));
q.bindValue(QSL(":id"), account_id); q.bindValue(QSL(":id"), account_id);
return q.exec(); return q.exec();
} }
bool DatabaseQueries::overwriteOwnCloudAccount(QSqlDatabase db, const QString& username, const QString& password, bool DatabaseQueries::overwriteOwnCloudAccount(QSqlDatabase db, const QString& username, const QString& password,
const QString& url, bool force_server_side_feed_update, int account_id) { const QString& url, bool force_server_side_feed_update, int account_id) {
QSqlQuery query(db); QSqlQuery query(db);
query.prepare("UPDATE OwnCloudAccounts " query.prepare("UPDATE OwnCloudAccounts "
"SET username = :username, password = :password, url = :url, force_update = :force_update " "SET username = :username, password = :password, url = :url, force_update = :force_update "
"WHERE id = :id;"); "WHERE id = :id;");
@ -966,6 +953,7 @@ bool DatabaseQueries::overwriteOwnCloudAccount(QSqlDatabase db, const QString &u
if (query.exec()) { if (query.exec()) {
return true; return true;
} }
else { else {
qWarning("ownCloud: Updating account failed: '%s'.", qPrintable(query.lastError().text())); qWarning("ownCloud: Updating account failed: '%s'.", qPrintable(query.lastError().text()));
return false; return false;
@ -976,7 +964,6 @@ bool DatabaseQueries::createOwnCloudAccount(QSqlDatabase db, int id_to_assign, c
const QString& password, const QString& url, const QString& password, const QString& url,
bool force_server_side_feed_update) { bool force_server_side_feed_update) {
QSqlQuery q(db); QSqlQuery q(db);
q.prepare("INSERT INTO OwnCloudAccounts (id, username, password, url, force_update) " q.prepare("INSERT INTO OwnCloudAccounts (id, username, password, url, force_update) "
"VALUES (:id, :username, :password, :url, :force_update);"); "VALUES (:id, :username, :password, :url, :force_update);");
q.bindValue(QSL(":id"), id_to_assign); q.bindValue(QSL(":id"), id_to_assign);
@ -988,6 +975,7 @@ bool DatabaseQueries::createOwnCloudAccount(QSqlDatabase db, int id_to_assign, c
if (q.exec()) { if (q.exec()) {
return true; return true;
} }
else { else {
qWarning("ownCloud: Inserting of new account failed: '%s'.", qPrintable(q.lastError().text())); qWarning("ownCloud: Inserting of new account failed: '%s'.", qPrintable(q.lastError().text()));
return false; return false;
@ -1009,7 +997,6 @@ int DatabaseQueries::createAccount(QSqlDatabase db, const QString &code, bool *o
} }
int id_to_assign = q.value(0).toInt() + 1; int id_to_assign = q.value(0).toInt() + 1;
q.prepare(QSL("INSERT INTO Accounts (id, type) VALUES (:id, :type);")); q.prepare(QSL("INSERT INTO Accounts (id, type) VALUES (:id, :type);"));
q.bindValue(QSL(":id"), id_to_assign); q.bindValue(QSL(":id"), id_to_assign);
q.bindValue(QSL(":type"), code); q.bindValue(QSL(":type"), code);
@ -1021,6 +1008,7 @@ int DatabaseQueries::createAccount(QSqlDatabase db, const QString &code, bool *o
return id_to_assign; return id_to_assign;
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -1033,7 +1021,6 @@ int DatabaseQueries::createAccount(QSqlDatabase db, const QString &code, bool *o
Assignment DatabaseQueries::getOwnCloudCategories(QSqlDatabase db, int account_id, bool* ok) { Assignment DatabaseQueries::getOwnCloudCategories(QSqlDatabase db, int account_id, bool* ok) {
Assignment categories; Assignment categories;
// Obtain data for categories from the database. // Obtain data for categories from the database.
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
@ -1052,7 +1039,6 @@ Assignment DatabaseQueries::getOwnCloudCategories(QSqlDatabase db, int account_i
AssignmentItem pair; AssignmentItem pair;
pair.first = q.value(CAT_DB_PARENT_ID_INDEX).toInt(); pair.first = q.value(CAT_DB_PARENT_ID_INDEX).toInt();
pair.second = new OwnCloudCategory(q.record()); pair.second = new OwnCloudCategory(q.record());
categories << pair; categories << pair;
} }
@ -1065,7 +1051,6 @@ Assignment DatabaseQueries::getOwnCloudCategories(QSqlDatabase db, int account_i
Assignment DatabaseQueries::getOwnCloudFeeds(QSqlDatabase db, int account_id, bool* ok) { Assignment DatabaseQueries::getOwnCloudFeeds(QSqlDatabase db, int account_id, bool* ok) {
Assignment feeds; Assignment feeds;
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;"));
@ -1083,7 +1068,6 @@ Assignment DatabaseQueries::getOwnCloudFeeds(QSqlDatabase db, int account_id, bo
AssignmentItem pair; AssignmentItem pair;
pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt(); pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt();
pair.second = new OwnCloudFeed(q.record()); pair.second = new OwnCloudFeed(q.record());
feeds << pair; feeds << pair;
} }
@ -1097,7 +1081,6 @@ Assignment DatabaseQueries::getOwnCloudFeeds(QSqlDatabase db, int account_id, bo
bool DatabaseQueries::deleteFeed(QSqlDatabase db, int feed_custom_id, int account_id) { bool DatabaseQueries::deleteFeed(QSqlDatabase db, int feed_custom_id, int account_id) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
// Remove all messages from this feed. // Remove all messages from this feed.
q.prepare(QSL("DELETE FROM Messages WHERE feed = :feed AND account_id = :account_id;")); q.prepare(QSL("DELETE FROM Messages WHERE feed = :feed AND account_id = :account_id;"));
q.bindValue(QSL(":feed"), feed_custom_id); q.bindValue(QSL(":feed"), feed_custom_id);
@ -1111,18 +1094,15 @@ bool DatabaseQueries::deleteFeed(QSqlDatabase db, int feed_custom_id, int accoun
q.prepare(QSL("DELETE FROM Feeds WHERE custom_id = :feed AND account_id = :account_id;")); q.prepare(QSL("DELETE FROM Feeds WHERE custom_id = :feed AND account_id = :account_id;"));
q.bindValue(QSL(":feed"), feed_custom_id); q.bindValue(QSL(":feed"), feed_custom_id);
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
return q.exec(); return q.exec();
} }
bool DatabaseQueries::deleteCategory(QSqlDatabase db, int id) { bool DatabaseQueries::deleteCategory(QSqlDatabase db, int id) {
QSqlQuery q(db); QSqlQuery q(db);
// Remove this category from database. // Remove this category from database.
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM Categories WHERE id = :category;")); q.prepare(QSL("DELETE FROM Categories WHERE id = :category;"));
q.bindValue(QSL(":category"), id); q.bindValue(QSL(":category"), id);
return q.exec(); return q.exec();
} }
@ -1130,7 +1110,6 @@ int DatabaseQueries::addCategory(QSqlDatabase db, int parent_id, int account_id,
const QString& description, QDateTime creation_date, const QIcon& icon, const QString& description, QDateTime creation_date, const QIcon& icon,
bool* ok) { bool* ok) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare("INSERT INTO Categories " q.prepare("INSERT INTO Categories "
"(parent_id, title, description, date_created, icon, account_id) " "(parent_id, title, description, date_created, icon, account_id) "
@ -1152,19 +1131,18 @@ int DatabaseQueries::addCategory(QSqlDatabase db, int parent_id, int account_id,
// Query failed. // Query failed.
return 0; return 0;
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = true; *ok = true;
} }
int new_id = q.lastInsertId().toInt(); int new_id = q.lastInsertId().toInt();
// Now set custom ID in the DB. // Now set custom ID in the DB.
q.prepare(QSL("UPDATE Categories SET custom_id = :custom_id WHERE id = :id;")); q.prepare(QSL("UPDATE Categories SET custom_id = :custom_id WHERE id = :id;"));
q.bindValue(QSL(":custom_id"), QString::number(new_id)); q.bindValue(QSL(":custom_id"), QString::number(new_id));
q.bindValue(QSL(":id"), new_id); q.bindValue(QSL(":id"), new_id);
q.exec(); q.exec();
return new_id; return new_id;
} }
} }
@ -1172,7 +1150,6 @@ int DatabaseQueries::addCategory(QSqlDatabase db, int parent_id, int account_id,
bool DatabaseQueries::editCategory(QSqlDatabase db, int parent_id, int category_id, bool DatabaseQueries::editCategory(QSqlDatabase db, int parent_id, int category_id,
const QString& title, const QString& description, const QIcon& icon) { const QString& title, const QString& description, const QIcon& icon) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare("UPDATE Categories " q.prepare("UPDATE Categories "
"SET title = :title, description = :description, icon = :icon, parent_id = :parent_id " "SET title = :title, description = :description, icon = :icon, parent_id = :parent_id "
@ -1182,7 +1159,6 @@ bool DatabaseQueries::editCategory(QSqlDatabase db, int parent_id, int category_
q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon)); q.bindValue(QSL(":icon"), qApp->icons()->toByteArray(icon));
q.bindValue(QSL(":parent_id"), parent_id); q.bindValue(QSL(":parent_id"), parent_id);
q.bindValue(QSL(":id"), category_id); q.bindValue(QSL(":id"), category_id);
return q.exec(); return q.exec();
} }
@ -1193,9 +1169,7 @@ int DatabaseQueries::addFeed(QSqlDatabase db, int parent_id, int account_id, con
Feed::AutoUpdateType auto_update_type, Feed::AutoUpdateType auto_update_type,
int auto_update_interval, StandardFeed::Type feed_format, bool* ok) { int auto_update_interval, StandardFeed::Type feed_format, bool* ok) {
QSqlQuery q(db); QSqlQuery q(db);
qDebug() << "Adding feed with title '" << title.toUtf8() << "' to DB."; qDebug() << "Adding feed with title '" << title.toUtf8() << "' to DB.";
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare("INSERT INTO Feeds " q.prepare("INSERT INTO Feeds "
"(title, description, date_created, icon, category, encoding, url, protected, username, password, update_type, update_interval, type, account_id) " "(title, description, date_created, icon, category, encoding, url, protected, username, password, update_type, update_interval, type, account_id) "
@ -1214,6 +1188,7 @@ int DatabaseQueries::addFeed(QSqlDatabase db, int parent_id, int account_id, con
if (password.isEmpty()) { if (password.isEmpty()) {
q.bindValue(QSL(":password"), password); q.bindValue(QSL(":password"), password);
} }
else { else {
q.bindValue(QSL(":password"), TextFactory::encrypt(password)); q.bindValue(QSL(":password"), TextFactory::encrypt(password));
} }
@ -1224,7 +1199,6 @@ int DatabaseQueries::addFeed(QSqlDatabase db, int parent_id, int account_id, con
if (q.exec()) { if (q.exec()) {
int new_id = q.lastInsertId().toInt(); int new_id = q.lastInsertId().toInt();
// Now set custom ID in the DB. // Now set custom ID in the DB.
q.prepare(QSL("UPDATE Feeds SET custom_id = :custom_id WHERE id = :id;")); q.prepare(QSL("UPDATE Feeds SET custom_id = :custom_id WHERE id = :id;"));
q.bindValue(QSL(":custom_id"), QString::number(new_id)); q.bindValue(QSL(":custom_id"), QString::number(new_id));
@ -1237,6 +1211,7 @@ int DatabaseQueries::addFeed(QSqlDatabase db, int parent_id, int account_id, con
return new_id; return new_id;
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -1255,7 +1230,6 @@ bool DatabaseQueries::editFeed(QSqlDatabase db, int parent_id, int feed_id, cons
int auto_update_interval, StandardFeed::Type feed_format) { int auto_update_interval, StandardFeed::Type feed_format) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare("UPDATE Feeds " q.prepare("UPDATE Feeds "
"SET title = :title, description = :description, icon = :icon, category = :category, encoding = :encoding, url = :url, protected = :protected, username = :username, password = :password, update_type = :update_type, update_interval = :update_interval, type = :type " "SET title = :title, description = :description, icon = :icon, category = :category, encoding = :encoding, url = :url, protected = :protected, username = :username, password = :password, update_type = :update_type, update_interval = :update_interval, type = :type "
"WHERE id = :id;"); "WHERE id = :id;");
@ -1271,6 +1245,7 @@ bool DatabaseQueries::editFeed(QSqlDatabase db, int parent_id, int feed_id, cons
if (password.isEmpty()) { if (password.isEmpty()) {
q.bindValue(QSL(":password"), password); q.bindValue(QSL(":password"), password);
} }
else { else {
q.bindValue(QSL(":password"), TextFactory::encrypt(password)); q.bindValue(QSL(":password"), TextFactory::encrypt(password));
} }
@ -1279,30 +1254,25 @@ bool DatabaseQueries::editFeed(QSqlDatabase db, int parent_id, int feed_id, cons
q.bindValue(QSL(":update_interval"), auto_update_interval); q.bindValue(QSL(":update_interval"), auto_update_interval);
q.bindValue(QSL(":type"), feed_format); q.bindValue(QSL(":type"), feed_format);
q.bindValue(QSL(":id"), feed_id); q.bindValue(QSL(":id"), feed_id);
return q.exec(); return q.exec();
} }
bool DatabaseQueries::editBaseFeed(QSqlDatabase db, int feed_id, Feed::AutoUpdateType auto_update_type, bool DatabaseQueries::editBaseFeed(QSqlDatabase db, int feed_id, Feed::AutoUpdateType auto_update_type,
int auto_update_interval) { int auto_update_interval) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare("UPDATE Feeds " q.prepare("UPDATE Feeds "
"SET update_type = :update_type, update_interval = :update_interval " "SET update_type = :update_type, update_interval = :update_interval "
"WHERE id = :id;"); "WHERE id = :id;");
q.bindValue(QSL(":update_type"), (int) auto_update_type); q.bindValue(QSL(":update_type"), (int) auto_update_type);
q.bindValue(QSL(":update_interval"), auto_update_interval); q.bindValue(QSL(":update_interval"), auto_update_interval);
q.bindValue(QSL(":id"), feed_id); q.bindValue(QSL(":id"), feed_id);
return q.exec(); return q.exec();
} }
QList<ServiceRoot*> DatabaseQueries::getAccounts(QSqlDatabase db, bool* ok) { QList<ServiceRoot*> DatabaseQueries::getAccounts(QSqlDatabase db, bool* ok) {
QSqlQuery q(db); QSqlQuery q(db);
QList<ServiceRoot*> roots; QList<ServiceRoot*> roots;
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("SELECT id FROM Accounts WHERE type = :type;")); q.prepare(QSL("SELECT id FROM Accounts WHERE type = :type;"));
q.bindValue(QSL(":type"), SERVICE_CODE_STD_RSS); q.bindValue(QSL(":type"), SERVICE_CODE_STD_RSS);
@ -1318,6 +1288,7 @@ QList<ServiceRoot*> DatabaseQueries::getAccounts(QSqlDatabase db, bool *ok) {
*ok = true; *ok = true;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = false; *ok = false;
@ -1329,7 +1300,6 @@ QList<ServiceRoot*> DatabaseQueries::getAccounts(QSqlDatabase db, bool *ok) {
Assignment DatabaseQueries::getCategories(QSqlDatabase db, int account_id, bool* ok) { Assignment DatabaseQueries::getCategories(QSqlDatabase db, int account_id, bool* ok) {
Assignment categories; Assignment categories;
// Obtain data for categories from the database. // Obtain data for categories from the database.
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
@ -1344,6 +1314,7 @@ Assignment DatabaseQueries::getCategories(QSqlDatabase db, int account_id, bool
*ok = false; *ok = false;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = true; *ok = true;
@ -1354,7 +1325,6 @@ Assignment DatabaseQueries::getCategories(QSqlDatabase db, int account_id, bool
AssignmentItem pair; AssignmentItem pair;
pair.first = q.value(CAT_DB_PARENT_ID_INDEX).toInt(); pair.first = q.value(CAT_DB_PARENT_ID_INDEX).toInt();
pair.second = new StandardCategory(q.record()); pair.second = new StandardCategory(q.record());
categories << pair; categories << pair;
} }
@ -1364,7 +1334,6 @@ Assignment DatabaseQueries::getCategories(QSqlDatabase db, int account_id, bool
Assignment DatabaseQueries::getFeeds(QSqlDatabase db, int account_id, bool* ok) { Assignment DatabaseQueries::getFeeds(QSqlDatabase db, int account_id, bool* ok) {
Assignment feeds; Assignment feeds;
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;")); q.prepare(QSL("SELECT * FROM Feeds WHERE account_id = :account_id;"));
q.bindValue(QSL(":account_id"), account_id); q.bindValue(QSL(":account_id"), account_id);
@ -1395,7 +1364,6 @@ Assignment DatabaseQueries::getFeeds(QSqlDatabase db, int account_id, bool *ok)
pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt(); pair.first = q.value(FDS_DB_CATEGORY_INDEX).toInt();
pair.second = new StandardFeed(q.record()); pair.second = new StandardFeed(q.record());
qobject_cast<StandardFeed*>(pair.second)->setType(type); qobject_cast<StandardFeed*>(pair.second)->setType(type);
feeds << pair; feeds << pair;
break; break;
} }
@ -1410,11 +1378,9 @@ Assignment DatabaseQueries::getFeeds(QSqlDatabase db, int account_id, bool *ok)
bool DatabaseQueries::deleteTtRssAccount(QSqlDatabase db, int account_id) { bool DatabaseQueries::deleteTtRssAccount(QSqlDatabase db, int account_id) {
QSqlQuery q(db); QSqlQuery q(db);
q.setForwardOnly(true); q.setForwardOnly(true);
q.prepare(QSL("DELETE FROM TtRssAccounts WHERE id = :id;")); q.prepare(QSL("DELETE FROM TtRssAccounts WHERE id = :id;"));
q.bindValue(QSL(":id"), account_id); q.bindValue(QSL(":id"), account_id);
// Remove extra entry in "Tiny Tiny RSS accounts list" and then delete // Remove extra entry in "Tiny Tiny RSS accounts list" and then delete
// all the categories/feeds and messages. // all the categories/feeds and messages.
return q.exec(); return q.exec();
@ -1424,7 +1390,6 @@ bool DatabaseQueries::overwriteTtRssAccount(QSqlDatabase db, const QString &user
bool auth_protected, const QString& auth_username, const QString& auth_password, bool auth_protected, const QString& auth_username, const QString& auth_password,
const QString& url, bool force_server_side_feed_update, int account_id) { const QString& url, bool force_server_side_feed_update, int account_id) {
QSqlQuery q(db); QSqlQuery q(db);
q.prepare("UPDATE TtRssAccounts " q.prepare("UPDATE TtRssAccounts "
"SET username = :username, password = :password, url = :url, auth_protected = :auth_protected, " "SET username = :username, password = :password, url = :url, auth_protected = :auth_protected, "
"auth_username = :auth_username, auth_password = :auth_password, force_update = :force_update " "auth_username = :auth_username, auth_password = :auth_password, force_update = :force_update "
@ -1441,6 +1406,7 @@ bool DatabaseQueries::overwriteTtRssAccount(QSqlDatabase db, const QString &user
if (q.exec()) { if (q.exec()) {
return true; return true;
} }
else { else {
qWarning("TT-RSS: Updating account failed: '%s'.", qPrintable(q.lastError().text())); qWarning("TT-RSS: Updating account failed: '%s'.", qPrintable(q.lastError().text()));
return false; return false;
@ -1452,7 +1418,6 @@ bool DatabaseQueries::createTtRssAccount(QSqlDatabase db, int id_to_assign, cons
const QString& auth_password, const QString& url, const QString& auth_password, const QString& url,
bool force_server_side_feed_update) { bool force_server_side_feed_update) {
QSqlQuery q(db); QSqlQuery q(db);
q.prepare("INSERT INTO TtRssAccounts (id, username, password, auth_protected, auth_username, auth_password, url, force_update) " q.prepare("INSERT INTO TtRssAccounts (id, username, password, auth_protected, auth_username, auth_password, url, force_update) "
"VALUES (:id, :username, :password, :auth_protected, :auth_username, :auth_password, :url, :force_update);"); "VALUES (:id, :username, :password, :auth_protected, :auth_username, :auth_password, :url, :force_update);");
q.bindValue(QSL(":id"), id_to_assign); q.bindValue(QSL(":id"), id_to_assign);
@ -1467,6 +1432,7 @@ bool DatabaseQueries::createTtRssAccount(QSqlDatabase db, int id_to_assign, cons
if (q.exec()) { if (q.exec()) {
return true; return true;
} }
else { else {
qWarning("TT-RSS: Saving of new account failed: '%s'.", qPrintable(q.lastError().text())); qWarning("TT-RSS: Saving of new account failed: '%s'.", qPrintable(q.lastError().text()));
return false; return false;
@ -1475,7 +1441,6 @@ bool DatabaseQueries::createTtRssAccount(QSqlDatabase db, int id_to_assign, cons
Assignment DatabaseQueries::getTtRssCategories(QSqlDatabase db, int account_id, bool* ok) { Assignment DatabaseQueries::getTtRssCategories(QSqlDatabase db, int account_id, bool* ok) {
Assignment categories; Assignment categories;
// Obtain data for categories from the database. // Obtain data for categories from the database.
QSqlQuery query_categories(db); QSqlQuery query_categories(db);
query_categories.setForwardOnly(true); query_categories.setForwardOnly(true);
@ -1489,6 +1454,7 @@ Assignment DatabaseQueries::getTtRssCategories(QSqlDatabase db, int account_id,
*ok = false; *ok = false;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = true; *ok = true;
@ -1499,7 +1465,6 @@ Assignment DatabaseQueries::getTtRssCategories(QSqlDatabase db, int account_id,
AssignmentItem pair; AssignmentItem pair;
pair.first = query_categories.value(CAT_DB_PARENT_ID_INDEX).toInt(); pair.first = query_categories.value(CAT_DB_PARENT_ID_INDEX).toInt();
pair.second = new TtRssCategory(query_categories.record()); pair.second = new TtRssCategory(query_categories.record());
categories << pair; categories << pair;
} }
@ -1508,7 +1473,6 @@ Assignment DatabaseQueries::getTtRssCategories(QSqlDatabase db, int account_id,
Assignment DatabaseQueries::getTtRssFeeds(QSqlDatabase db, int account_id, bool* ok) { Assignment DatabaseQueries::getTtRssFeeds(QSqlDatabase db, int account_id, bool* ok) {
Assignment feeds; Assignment feeds;
// All categories are now loaded. // All categories are now loaded.
QSqlQuery query_feeds(db); QSqlQuery query_feeds(db);
query_feeds.setForwardOnly(true); query_feeds.setForwardOnly(true);
@ -1522,6 +1486,7 @@ Assignment DatabaseQueries::getTtRssFeeds(QSqlDatabase db, int account_id, bool
*ok = false; *ok = false;
} }
} }
else { else {
if (ok != nullptr) { if (ok != nullptr) {
*ok = true; *ok = true;
@ -1532,7 +1497,6 @@ Assignment DatabaseQueries::getTtRssFeeds(QSqlDatabase db, int account_id, bool
AssignmentItem pair; AssignmentItem pair;
pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt(); pair.first = query_feeds.value(FDS_DB_CATEGORY_INDEX).toInt();
pair.second = new TtRssFeed(query_feeds.record()); pair.second = new TtRssFeed(query_feeds.record());
feeds << pair; feeds << pair;
} }

View File

@ -32,16 +32,15 @@ Debugging::Debugging() {
void Debugging::performLog(const char* message, QtMsgType type, const char* file, const char* function, int line) { void Debugging::performLog(const char* message, QtMsgType type, const char* file, const char* function, int line) {
const char* type_string = typeToString(type); const char* type_string = typeToString(type);
std::time_t t = std::time(nullptr); std::time_t t = std::time(nullptr);
char mbstr[32]; char mbstr[32];
std::strftime(mbstr, sizeof(mbstr), "%y/%d/%m %H:%M:%S", std::localtime(&t)); std::strftime(mbstr, sizeof(mbstr), "%y/%d/%m %H:%M:%S", std::localtime(&t));
// Write to console. // Write to console.
if (file == 0 || function == 0 || line < 0) { if (file == 0 || function == 0 || line < 0) {
fprintf(stderr, "[%s] %s: %s (%s)\n", APP_LOW_NAME, type_string, message, mbstr); fprintf(stderr, "[%s] %s: %s (%s)\n", APP_LOW_NAME, type_string, message, mbstr);
} }
else { else {
fprintf(stderr, "[%s] %s (%s)\n Type: %s\n File: %s (line %d)\n Function: %s\n\n", fprintf(stderr, "[%s] %s (%s)\n Type: %s\n File: %s (line %d)\n Function: %s\n\n",
APP_LOW_NAME, message, mbstr, type_string, file, line, function); APP_LOW_NAME, message, mbstr, type_string, file, line, function);

View File

@ -45,7 +45,6 @@ FeedReader::FeedReader(QObject *parent)
m_feedsProxyModel = new FeedsProxyModel(m_feedsModel, this); m_feedsProxyModel = new FeedsProxyModel(m_feedsModel, this);
m_messagesModel = new MessagesModel(this); m_messagesModel = new MessagesModel(this);
m_messagesProxyModel = new MessagesProxyModel(m_messagesModel, this); m_messagesProxyModel = new MessagesProxyModel(m_messagesModel, this);
connect(m_cacheSaveFutureWatcher, &QFutureWatcher<void>::finished, this, &FeedReader::asyncCacheSaveFinished); connect(m_cacheSaveFutureWatcher, &QFutureWatcher<void>::finished, this, &FeedReader::asyncCacheSaveFinished);
connect(m_autoUpdateTimer, &QTimer::timeout, this, &FeedReader::executeNextAutoUpdate); connect(m_autoUpdateTimer, &QTimer::timeout, this, &FeedReader::executeNextAutoUpdate);
updateAutoUpdateStatus(); updateAutoUpdateStatus();
@ -84,17 +83,14 @@ void FeedReader::updateFeeds(const QList<Feed*> &feeds) {
if (m_feedDownloader == nullptr) { if (m_feedDownloader == nullptr) {
m_feedDownloader = new FeedDownloader(); m_feedDownloader = new FeedDownloader();
m_feedDownloaderThread = new QThread(); m_feedDownloaderThread = new QThread();
// Downloader setup. // Downloader setup.
qRegisterMetaType<QList<Feed*>>("QList<Feed*>"); qRegisterMetaType<QList<Feed*>>("QList<Feed*>");
m_feedDownloader->moveToThread(m_feedDownloaderThread); m_feedDownloader->moveToThread(m_feedDownloaderThread);
connect(m_feedDownloaderThread, &QThread::finished, m_feedDownloaderThread, &QThread::deleteLater); connect(m_feedDownloaderThread, &QThread::finished, m_feedDownloaderThread, &QThread::deleteLater);
connect(m_feedDownloader, &FeedDownloader::updateFinished, this, &FeedReader::feedUpdatesFinished); connect(m_feedDownloader, &FeedDownloader::updateFinished, this, &FeedReader::feedUpdatesFinished);
connect(m_feedDownloader, &FeedDownloader::updateProgress, this, &FeedReader::feedUpdatesProgress); connect(m_feedDownloader, &FeedDownloader::updateProgress, this, &FeedReader::feedUpdatesProgress);
connect(m_feedDownloader, &FeedDownloader::updateStarted, this, &FeedReader::feedUpdatesStarted); connect(m_feedDownloader, &FeedDownloader::updateStarted, this, &FeedReader::feedUpdatesStarted);
connect(m_feedDownloader, &FeedDownloader::updateFinished, qApp->feedUpdateLock(), &Mutex::unlock); connect(m_feedDownloader, &FeedDownloader::updateFinished, qApp->feedUpdateLock(), &Mutex::unlock);
// Connections are made, start the feed downloader thread. // Connections are made, start the feed downloader thread.
m_feedDownloaderThread->start(); m_feedDownloaderThread->start();
} }
@ -118,6 +114,7 @@ void FeedReader::updateAutoUpdateStatus() {
m_autoUpdateTimer->start(); m_autoUpdateTimer->start();
qDebug("Auto-update timer started with interval %d.", m_autoUpdateTimer->interval()); qDebug("Auto-update timer started with interval %d.", m_autoUpdateTimer->interval());
} }
else { else {
qDebug("Auto-update timer is already running."); qDebug("Auto-update timer is already running.");
} }
@ -153,12 +150,10 @@ DatabaseCleaner *FeedReader::databaseCleaner() {
if (m_dbCleaner == nullptr) { if (m_dbCleaner == nullptr) {
m_dbCleaner = new DatabaseCleaner(); m_dbCleaner = new DatabaseCleaner();
m_dbCleanerThread = new QThread(); m_dbCleanerThread = new QThread();
// Downloader setup. // Downloader setup.
qRegisterMetaType<CleanerOrders>("CleanerOrders"); qRegisterMetaType<CleanerOrders>("CleanerOrders");
m_dbCleaner->moveToThread(m_dbCleanerThread); m_dbCleaner->moveToThread(m_dbCleanerThread);
connect(m_dbCleanerThread, SIGNAL(finished()), m_dbCleanerThread, SLOT(deleteLater())); connect(m_dbCleanerThread, SIGNAL(finished()), m_dbCleanerThread, SLOT(deleteLater()));
// Connections are made, start the feed downloader thread. // Connections are made, start the feed downloader thread.
m_dbCleanerThread->start(); m_dbCleanerThread->start();
} }
@ -181,7 +176,6 @@ MessagesModel *FeedReader::messagesModel() const {
void FeedReader::executeNextAutoUpdate() { void FeedReader::executeNextAutoUpdate() {
if (!qApp->feedUpdateLock()->tryLock()) { if (!qApp->feedUpdateLock()->tryLock()) {
qDebug("Delaying scheduled feed auto-updates for one minute due to another running update."); qDebug("Delaying scheduled feed auto-updates for one minute due to another running update.");
// Cannot update, quit. // Cannot update, quit.
return; return;
} }
@ -194,12 +188,10 @@ void FeedReader::executeNextAutoUpdate() {
} }
qDebug("Starting auto-update event, pass %d/%d.", m_globalAutoUpdateRemainingInterval, m_globalAutoUpdateInitialInterval); qDebug("Starting auto-update event, pass %d/%d.", m_globalAutoUpdateRemainingInterval, m_globalAutoUpdateInitialInterval);
// Pass needed interval data and lets the model decide which feeds // Pass needed interval data and lets the model decide which feeds
// should be updated in this pass. // should be updated in this pass.
QList<Feed*> feeds_for_update = m_feedsModel->feedsForScheduledUpdate(m_globalAutoUpdateEnabled && QList<Feed*> feeds_for_update = m_feedsModel->feedsForScheduledUpdate(m_globalAutoUpdateEnabled &&
m_globalAutoUpdateRemainingInterval == 0); m_globalAutoUpdateRemainingInterval == 0);
qApp->feedUpdateLock()->unlock(); qApp->feedUpdateLock()->unlock();
if (!feeds_for_update.isEmpty()) { if (!feeds_for_update.isEmpty()) {
@ -230,6 +222,7 @@ void FeedReader::checkServicesForAsyncOperations(bool wait_for_future) {
qWarning("Waiting for previously started saving of cached service data."); qWarning("Waiting for previously started saving of cached service data.");
m_cacheSaveFutureWatcher->future().waitForFinished(); m_cacheSaveFutureWatcher->future().waitForFinished();
} }
else { else {
qWarning("Some cached service data are being saved now, so aborting this saving cycle."); qWarning("Some cached service data are being saved now, so aborting this saving cycle.");
// Some cache saving is now running. // Some cache saving is now running.
@ -248,6 +241,7 @@ void FeedReader::checkServicesForAsyncOperations(bool wait_for_future) {
qDebug("Waiting for saving of cached service data to finish."); qDebug("Waiting for saving of cached service data to finish.");
future.waitForFinished(); future.waitForFinished();
} }
else { else {
m_cacheSaveFutureWatcher->setFuture(future); m_cacheSaveFutureWatcher->setFuture(future);
} }
@ -255,7 +249,6 @@ void FeedReader::checkServicesForAsyncOperations(bool wait_for_future) {
void FeedReader::asyncCacheSaveFinished() { void FeedReader::asyncCacheSaveFinished() {
qDebug("I will start next check for cached service data in 30 seconds."); qDebug("I will start next check for cached service data in 30 seconds.");
QTimer::singleShot(30000, [&] { QTimer::singleShot(30000, [&] {
qDebug("Starting next check for cached service data in NOW."); qDebug("Starting next check for cached service data in NOW.");
checkServicesForAsyncOperations(false); checkServicesForAsyncOperations(false);

View File

@ -31,15 +31,12 @@ IconFactory::~IconFactory() {
QIcon IconFactory::fromByteArray(QByteArray array) { QIcon IconFactory::fromByteArray(QByteArray array) {
array = QByteArray::fromBase64(array); array = QByteArray::fromBase64(array);
QIcon icon; QIcon icon;
QBuffer buffer(&array); QBuffer buffer(&array);
buffer.open(QIODevice::ReadOnly); buffer.open(QIODevice::ReadOnly);
QDataStream in(&buffer); QDataStream in(&buffer);
in.setVersion(QDataStream::Qt_4_7); in.setVersion(QDataStream::Qt_4_7);
in >> icon; in >> icon;
buffer.close(); buffer.close();
return icon; return icon;
} }
@ -48,11 +45,9 @@ QByteArray IconFactory::toByteArray(const QIcon &icon) {
QByteArray array; QByteArray array;
QBuffer buffer(&array); QBuffer buffer(&array);
buffer.open(QIODevice::WriteOnly); buffer.open(QIODevice::WriteOnly);
QDataStream out(&buffer); QDataStream out(&buffer);
out.setVersion(QDataStream::Qt_4_7); out.setVersion(QDataStream::Qt_4_7);
out << icon; out << icon;
buffer.close(); buffer.close();
return array.toBase64(); return array.toBase64();
} }
@ -61,6 +56,7 @@ QPixmap IconFactory::pixmap(const QString &name) {
if (QIcon::themeName() == APP_NO_THEME) { if (QIcon::themeName() == APP_NO_THEME) {
return QPixmap(); return QPixmap();
} }
else { else {
return QIcon::fromTheme(name).pixmap(64, 64); return QIcon::fromTheme(name).pixmap(64, 64);
} }
@ -110,6 +106,7 @@ void IconFactory::loadCurrentIconTheme() {
qDebug("Loading icon theme '%s'.", qPrintable(theme_name_from_settings)); qDebug("Loading icon theme '%s'.", qPrintable(theme_name_from_settings));
QIcon::setThemeName(theme_name_from_settings); QIcon::setThemeName(theme_name_from_settings);
} }
else { else {
// Desired icon theme is not currently available. // Desired icon theme is not currently available.
// Install "default" icon theme instead. // Install "default" icon theme instead.
@ -120,12 +117,11 @@ void IconFactory::loadCurrentIconTheme() {
} }
QStringList IconFactory::installedIconThemes() const { QStringList IconFactory::installedIconThemes() const {
QStringList icon_theme_names; icon_theme_names << APP_NO_THEME; QStringList icon_theme_names;
icon_theme_names << APP_NO_THEME;
// Iterate all directories with icon themes. // Iterate all directories with icon themes.
QStringList icon_themes_paths = QIcon::themeSearchPaths(); QStringList icon_themes_paths = QIcon::themeSearchPaths();
QStringList filters_index; QStringList filters_index;
filters_index.append("index.theme"); filters_index.append("index.theme");
icon_themes_paths.removeDuplicates(); icon_themes_paths.removeDuplicates();
@ -146,6 +142,5 @@ QStringList IconFactory::installedIconThemes() const {
} }
icon_theme_names.removeDuplicates(); icon_theme_names.removeDuplicates();
return icon_theme_names; return icon_theme_names;
} }

View File

@ -39,7 +39,6 @@ bool IOFactory::isFolderWritable(const QString &folder) {
} }
real_file += "test-permissions-file"; real_file += "test-permissions-file";
return QTemporaryFile(real_file).open(); return QTemporaryFile(real_file).open();
} }
@ -63,6 +62,7 @@ QString IOFactory::ensureUniqueFilename(const QString &name, const QString &appe
if (index < 0) { if (index < 0) {
tmp_filename.append(append_string); tmp_filename.append(append_string);
} }
else { else {
tmp_filename = tmp_filename.left(index) + append_string + tmp_filename.mid(index); tmp_filename = tmp_filename.left(index) + append_string + tmp_filename.mid(index);
} }
@ -73,7 +73,6 @@ QString IOFactory::ensureUniqueFilename(const QString &name, const QString &appe
QString IOFactory::filterBadCharsFromFilename(const QString& name) { QString IOFactory::filterBadCharsFromFilename(const QString& name) {
QString value = name; QString value = name;
value.replace(QL1C('/'), QL1C('-')); value.replace(QL1C('/'), QL1C('-'));
value.remove(QL1C('\\')); value.remove(QL1C('\\'));
value.remove(QL1C(':')); value.remove(QL1C(':'));
@ -83,7 +82,6 @@ QString IOFactory::filterBadCharsFromFilename(const QString &name) {
value.remove(QL1C('<')); value.remove(QL1C('<'));
value.remove(QL1C('>')); value.remove(QL1C('>'));
value.remove(QL1C('|')); value.remove(QL1C('|'));
return value; return value;
} }
@ -96,6 +94,7 @@ QByteArray IOFactory::readTextFile(const QString &file_path) {
input_file.close(); input_file.close();
return input_data; return input_data;
} }
else { else {
throw IOException(tr("Cannot open file '%1' for reading.").arg(QDir::toNativeSeparators(file_path))); throw IOException(tr("Cannot open file '%1' for reading.").arg(QDir::toNativeSeparators(file_path)));
} }
@ -103,7 +102,6 @@ QByteArray IOFactory::readTextFile(const QString &file_path) {
void IOFactory::writeTextFile(const QString& file_path, const QByteArray& data, const QString& encoding) { void IOFactory::writeTextFile(const QString& file_path, const QByteArray& data, const QString& encoding) {
Q_UNUSED(encoding) Q_UNUSED(encoding)
QFile input_file(file_path); QFile input_file(file_path);
QTextStream stream(&input_file); QTextStream stream(&input_file);
@ -113,6 +111,7 @@ void IOFactory::writeTextFile(const QString &file_path, const QByteArray &data,
input_file.flush(); input_file.flush();
input_file.close(); input_file.close();
} }
else { else {
throw IOException(tr("Cannot open file '%1' for writting.").arg(QDir::toNativeSeparators(file_path))); throw IOException(tr("Cannot open file '%1' for writting.").arg(QDir::toNativeSeparators(file_path)));
} }

View File

@ -40,18 +40,17 @@ void Localization::loadActiveLanguage() {
QTranslator* qt_translator = new QTranslator(qApp); QTranslator* qt_translator = new QTranslator(qApp);
QTranslator* app_translator = new QTranslator(qApp); QTranslator* app_translator = new QTranslator(qApp);
QString desired_localization = desiredLanguage(); QString desired_localization = desiredLanguage();
qDebug("Starting to load active localization. Desired localization is '%s'.", qPrintable(desired_localization)); qDebug("Starting to load active localization. Desired localization is '%s'.", qPrintable(desired_localization));
if (app_translator->load(QLocale(desired_localization), "rssguard", QSL("_"), APP_LANG_PATH)) { if (app_translator->load(QLocale(desired_localization), "rssguard", QSL("_"), APP_LANG_PATH)) {
const QString real_loaded_locale = app_translator->translate("QObject", "LANG_ABBREV"); const QString real_loaded_locale = app_translator->translate("QObject", "LANG_ABBREV");
Application::installTranslator(app_translator); Application::installTranslator(app_translator);
qDebug("Application localization '%s' loaded successfully, specifically sublocalization '%s' was loaded.", qDebug("Application localization '%s' loaded successfully, specifically sublocalization '%s' was loaded.",
qPrintable(desired_localization), qPrintable(desired_localization),
qPrintable(real_loaded_locale)); qPrintable(real_loaded_locale));
desired_localization = real_loaded_locale; desired_localization = real_loaded_locale;
} }
else { else {
qWarning("Application localization '%s' was not loaded. Loading '%s' instead.", qWarning("Application localization '%s' was not loaded. Loading '%s' instead.",
qPrintable(desired_localization), qPrintable(desired_localization),
@ -63,6 +62,7 @@ void Localization::loadActiveLanguage() {
Application::installTranslator(qt_translator); Application::installTranslator(qt_translator);
qDebug("Qt localization '%s' loaded successfully.", qPrintable(desired_localization)); qDebug("Qt localization '%s' loaded successfully.", qPrintable(desired_localization));
} }
else { else {
qWarning("Qt localization '%s' was not loaded.", qPrintable(desired_localization)); qWarning("Qt localization '%s' was not loaded.", qPrintable(desired_localization));
} }
@ -85,7 +85,6 @@ QList<Language> Localization::installedLanguages() const {
new_language.m_author = translator.translate("QObject", "LANG_AUTHOR"); new_language.m_author = translator.translate("QObject", "LANG_AUTHOR");
new_language.m_email = translator.translate("QObject", "LANG_EMAIL"); new_language.m_email = translator.translate("QObject", "LANG_EMAIL");
new_language.m_name = QLocale(new_language.m_code).nativeLanguageName(); new_language.m_name = QLocale(new_language.m_code).nativeLanguageName();
languages << new_language; languages << new_language;
} }
} }

View File

@ -101,7 +101,8 @@ DKEY GUI::FeedsToolbarActions = "feeds_toolbar";
DVALUE(char*) GUI::FeedsToolbarActionsDef = "m_actionUpdateAllItems,m_actionStopRunningItemsUpdate,m_actionMarkAllItemsRead"; DVALUE(char*) GUI::FeedsToolbarActionsDef = "m_actionUpdateAllItems,m_actionStopRunningItemsUpdate,m_actionMarkAllItemsRead";
DKEY GUI::StatusbarActions = "status_bar"; DKEY GUI::StatusbarActions = "status_bar";
DVALUE(char*) GUI::StatusbarActionsDef = "m_lblProgressFeedsAction,m_barProgressFeedsAction,m_actionUpdateAllItems,m_actionUpdateSelectedItems,m_actionStopRunningItemsUpdate,m_actionFullscreen,m_actionQuit"; DVALUE(char*) GUI::StatusbarActionsDef =
"m_lblProgressFeedsAction,m_barProgressFeedsAction,m_actionUpdateAllItems,m_actionUpdateSelectedItems,m_actionStopRunningItemsUpdate,m_actionFullscreen,m_actionQuit";
DKEY GUI::MainWindowInitialSize = "window_size"; DKEY GUI::MainWindowInitialSize = "window_size";
DKEY GUI::MainWindowInitialPosition = "window_position"; DKEY GUI::MainWindowInitialPosition = "window_position";
@ -152,7 +153,8 @@ DKEY GUI::HideTabBarIfOnlyOneTab = "hide_tabbar_one_tab";
DVALUE(bool) GUI::HideTabBarIfOnlyOneTabDef = false; DVALUE(bool) GUI::HideTabBarIfOnlyOneTabDef = false;
DKEY GUI::MessagesToolbarDefaultButtons = "messages_toolbar"; DKEY GUI::MessagesToolbarDefaultButtons = "messages_toolbar";
DVALUE(char*) GUI::MessagesToolbarDefaultButtonsDef = "m_actionMarkSelectedMessagesAsRead,m_actionMarkSelectedMessagesAsUnread,m_actionSwitchImportanceOfSelectedMessages,separator,highlighter,spacer,search"; DVALUE(char*) GUI::MessagesToolbarDefaultButtonsDef =
"m_actionMarkSelectedMessagesAsRead,m_actionMarkSelectedMessagesAsUnread,m_actionSwitchImportanceOfSelectedMessages,separator,highlighter,spacer,search";
DKEY GUI::DefaultSortColumnFeeds = "default_sort_column_feeds"; DKEY GUI::DefaultSortColumnFeeds = "default_sort_column_feeds";
DVALUE(int) GUI::DefaultSortColumnFeedsDef = FDS_MODEL_TITLE_INDEX; DVALUE(int) GUI::DefaultSortColumnFeedsDef = FDS_MODEL_TITLE_INDEX;
@ -299,7 +301,6 @@ QString Settings::pathName() const {
QSettings::Status Settings::checkSettings() { QSettings::Status Settings::checkSettings() {
qDebug("Syncing settings."); qDebug("Syncing settings.");
sync(); sync();
return status(); return status();
} }
@ -321,6 +322,7 @@ void Settings::finishRestoration(const QString &desired_settings_file_path) {
QFile::remove(backup_settings_file); QFile::remove(backup_settings_file);
qDebug("Settings file was restored successully."); qDebug("Settings file was restored successully.");
} }
else { else {
qCritical("Settings file was NOT restored due to error when copying the file."); qCritical("Settings file was NOT restored due to error when copying the file.");
} }
@ -329,14 +331,11 @@ void Settings::finishRestoration(const QString &desired_settings_file_path) {
Settings* Settings::setupSettings(QObject* parent) { Settings* Settings::setupSettings(QObject* parent) {
Settings* new_settings; Settings* new_settings;
// If settings file exists (and is writable) in executable file working directory // If settings file exists (and is writable) in executable file working directory
// (in subdirectory APP_CFG_PATH), then use it (portable settings). // (in subdirectory APP_CFG_PATH), then use it (portable settings).
// Otherwise use settings file stored in home path. // Otherwise use settings file stored in home path.
const SettingsProperties properties = determineProperties(); const SettingsProperties properties = determineProperties();
finishRestoration(properties.m_absoluteSettingsFileName); finishRestoration(properties.m_absoluteSettingsFileName);
// Portable settings are available, use them. // Portable settings are available, use them.
new_settings = new Settings(properties.m_absoluteSettingsFileName, QSettings::IniFormat, properties.m_type, parent); new_settings = new Settings(properties.m_absoluteSettingsFileName, QSettings::IniFormat, properties.m_type, parent);
@ -344,6 +343,7 @@ Settings *Settings::setupSettings(QObject *parent) {
if (properties.m_type == SettingsProperties::Portable) { if (properties.m_type == SettingsProperties::Portable) {
qDebug("Initializing settings in '%s' (portable way).", qPrintable(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName))); qDebug("Initializing settings in '%s' (portable way).", qPrintable(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)));
} }
else { else {
qDebug("Initializing settings in '%s' (non-portable way).", qPrintable(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName))); qDebug("Initializing settings in '%s' (non-portable way).", qPrintable(QDir::toNativeSeparators(properties.m_absoluteSettingsFileName)));
} }
@ -353,12 +353,9 @@ Settings *Settings::setupSettings(QObject *parent) {
SettingsProperties Settings::determineProperties() { SettingsProperties Settings::determineProperties() {
SettingsProperties properties; SettingsProperties properties;
properties.m_settingsSuffix = QDir::separator() + QSL(APP_CFG_PATH) + QDir::separator() + QSL(APP_CFG_FILE); properties.m_settingsSuffix = QDir::separator() + QSL(APP_CFG_PATH) + QDir::separator() + QSL(APP_CFG_FILE);
const QString app_path = qApp->getUserDataAppPath(); const QString app_path = qApp->getUserDataAppPath();
const QString home_path = qApp->getUserDataHomePath(); const QString home_path = qApp->getUserDataHomePath();
// We will use PORTABLE settings only and only if it is available and NON-PORTABLE // We will use PORTABLE settings only and only if it is available and NON-PORTABLE
// settings was not initialized before. // settings was not initialized before.
#if defined (Q_OS_LINUX) || defined (Q_OS_MACOS) #if defined (Q_OS_LINUX) || defined (Q_OS_MACOS)
@ -376,12 +373,12 @@ SettingsProperties Settings::determineProperties() {
properties.m_type = SettingsProperties::Portable; properties.m_type = SettingsProperties::Portable;
properties.m_baseDirectory = app_path; properties.m_baseDirectory = app_path;
} }
else { else {
properties.m_type = SettingsProperties::NonPortable; properties.m_type = SettingsProperties::NonPortable;
properties.m_baseDirectory = home_path; properties.m_baseDirectory = home_path;
} }
properties.m_absoluteSettingsFileName = properties.m_baseDirectory + properties.m_settingsSuffix; properties.m_absoluteSettingsFileName = properties.m_baseDirectory + properties.m_settingsSuffix;
return properties; return properties;
} }

21
src/miscellaneous/simplecrypt/simplecrypt.cpp Normal file → Executable file
View File

@ -60,6 +60,7 @@ void SimpleCrypt::setKey(quint64 key) {
void SimpleCrypt::splitKey() { void SimpleCrypt::splitKey() {
m_keyParts.clear(); m_keyParts.clear();
m_keyParts.resize(8); m_keyParts.resize(8);
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
quint64 part = m_key; quint64 part = m_key;
@ -90,6 +91,7 @@ QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext) {
ba = qCompress(ba, 9); //maximum compression ba = qCompress(ba, 9); //maximum compression
flags |= CryptoFlagCompression; flags |= CryptoFlagCompression;
} }
else if (m_compressionMode == CompressionAuto) { else if (m_compressionMode == CompressionAuto) {
QByteArray compressed = qCompress(ba, 9); QByteArray compressed = qCompress(ba, 9);
@ -100,11 +102,13 @@ QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext) {
} }
QByteArray integrityProtection; QByteArray integrityProtection;
if (m_protectionMode == ProtectionChecksum) { if (m_protectionMode == ProtectionChecksum) {
flags |= CryptoFlagChecksum; flags |= CryptoFlagChecksum;
QDataStream s(&integrityProtection, QIODevice::WriteOnly); QDataStream s(&integrityProtection, QIODevice::WriteOnly);
s << qChecksum(ba.constData(), ba.length()); s << qChecksum(ba.constData(), ba.length());
} }
else if (m_protectionMode == ProtectionHash) { else if (m_protectionMode == ProtectionHash) {
flags |= CryptoFlagHash; flags |= CryptoFlagHash;
QCryptographicHash hash(QCryptographicHash::Sha1); QCryptographicHash hash(QCryptographicHash::Sha1);
@ -115,7 +119,6 @@ QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext) {
//prepend a random char to the string //prepend a random char to the string
char randomChar = char(qrand() & 0xFF); char randomChar = char(qrand() & 0xFF);
ba = randomChar + integrityProtection + ba; ba = randomChar + integrityProtection + ba;
int pos(0); int pos(0);
char lastChar(0); char lastChar(0);
int cnt = ba.count(); int cnt = ba.count();
@ -130,7 +133,6 @@ QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext) {
resultArray.append(char(0x03)); //version for future updates to algorithm resultArray.append(char(0x03)); //version for future updates to algorithm
resultArray.append(char(flags)); //encryption flags resultArray.append(char(flags)); //encryption flags
resultArray.append(ba); resultArray.append(ba);
m_lastError = ErrorNoError; m_lastError = ErrorNoError;
return resultArray; return resultArray;
} }
@ -152,21 +154,18 @@ QString SimpleCrypt::decryptToString(const QString &cyphertext) {
QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1()); QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1());
QByteArray plaintextArray = decryptToByteArray(cyphertextArray); QByteArray plaintextArray = decryptToByteArray(cyphertextArray);
QString plaintext = QString::fromUtf8(plaintextArray, plaintextArray.size()); QString plaintext = QString::fromUtf8(plaintextArray, plaintextArray.size());
return plaintext; return plaintext;
} }
QString SimpleCrypt::decryptToString(QByteArray cypher) { QString SimpleCrypt::decryptToString(QByteArray cypher) {
QByteArray ba = decryptToByteArray(cypher); QByteArray ba = decryptToByteArray(cypher);
QString plaintext = QString::fromUtf8(ba, ba.size()); QString plaintext = QString::fromUtf8(ba, ba.size());
return plaintext; return plaintext;
} }
QByteArray SimpleCrypt::decryptToByteArray(const QString& cyphertext) { QByteArray SimpleCrypt::decryptToByteArray(const QString& cyphertext) {
QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1()); QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1());
QByteArray ba = decryptToByteArray(cyphertextArray); QByteArray ba = decryptToByteArray(cyphertextArray);
return ba; return ba;
} }
@ -192,7 +191,6 @@ QByteArray SimpleCrypt::decryptToByteArray(QByteArray cypher) {
} }
CryptoFlags flags = CryptoFlags(ba.at(1)); CryptoFlags flags = CryptoFlags(ba.at(1));
ba = ba.mid(2); ba = ba.mid(2);
int pos(0); int pos(0);
int cnt(ba.count()); int cnt(ba.count());
@ -206,13 +204,14 @@ QByteArray SimpleCrypt::decryptToByteArray(QByteArray cypher) {
} }
ba = ba.mid(1); //chop off the random number at the start ba = ba.mid(1); //chop off the random number at the start
bool integrityOk(true); bool integrityOk(true);
if (flags.testFlag(CryptoFlagChecksum)) { if (flags.testFlag(CryptoFlagChecksum)) {
if (ba.length() < 2) { if (ba.length() < 2) {
m_lastError = ErrorIntegrityFailed; m_lastError = ErrorIntegrityFailed;
return QByteArray(); return QByteArray();
} }
quint16 storedChecksum; quint16 storedChecksum;
{ {
QDataStream s(&ba, QIODevice::ReadOnly); QDataStream s(&ba, QIODevice::ReadOnly);
@ -221,11 +220,14 @@ QByteArray SimpleCrypt::decryptToByteArray(QByteArray cypher) {
ba = ba.mid(2); ba = ba.mid(2);
quint16 checksum = qChecksum(ba.constData(), ba.length()); quint16 checksum = qChecksum(ba.constData(), ba.length());
integrityOk = (checksum == storedChecksum); integrityOk = (checksum == storedChecksum);
} else if (flags.testFlag(CryptoFlagHash)) { }
else if (flags.testFlag(CryptoFlagHash)) {
if (ba.length() < 20) { if (ba.length() < 20) {
m_lastError = ErrorIntegrityFailed; m_lastError = ErrorIntegrityFailed;
return QByteArray(); return QByteArray();
} }
QByteArray storedHash = ba.left(20); QByteArray storedHash = ba.left(20);
ba = ba.mid(20); ba = ba.mid(20);
QCryptographicHash hash(QCryptographicHash::Sha1); QCryptographicHash hash(QCryptographicHash::Sha1);
@ -238,8 +240,9 @@ QByteArray SimpleCrypt::decryptToByteArray(QByteArray cypher) {
return QByteArray(); return QByteArray();
} }
if (flags.testFlag(CryptoFlagCompression)) if (flags.testFlag(CryptoFlagCompression)) {
ba = qUncompress(ba); ba = qUncompress(ba);
}
m_lastError = ErrorNoError; m_lastError = ErrorNoError;
return ba; return ba;

24
src/miscellaneous/simplecrypt/simplecrypt.h Normal file → Executable file
View File

@ -110,7 +110,9 @@ class SimpleCrypt {
/** /**
Returns true if SimpleCrypt has been initialized with a key. Returns true if SimpleCrypt has been initialized with a key.
*/ */
bool hasKey() const {return !m_keyParts.isEmpty();} bool hasKey() const {
return !m_keyParts.isEmpty();
}
/** /**
Sets the compression mode to use when encrypting data. The default mode is Auto. Sets the compression mode to use when encrypting data. The default mode is Auto.
@ -118,11 +120,15 @@ class SimpleCrypt {
Note that decryption is not influenced by this mode, as the decryption recognizes Note that decryption is not influenced by this mode, as the decryption recognizes
what mode was used when encrypting. what mode was used when encrypting.
*/ */
void setCompressionMode(CompressionMode mode) {m_compressionMode = mode;} void setCompressionMode(CompressionMode mode) {
m_compressionMode = mode;
}
/** /**
Returns the CompressionMode that is currently in use. Returns the CompressionMode that is currently in use.
*/ */
CompressionMode compressionMode() const {return m_compressionMode;} CompressionMode compressionMode() const {
return m_compressionMode;
}
/** /**
Sets the integrity mode to use when encrypting data. The default mode is Checksum. Sets the integrity mode to use when encrypting data. The default mode is Checksum.
@ -130,16 +136,22 @@ class SimpleCrypt {
Note that decryption is not influenced by this mode, as the decryption recognizes Note that decryption is not influenced by this mode, as the decryption recognizes
what mode was used when encrypting. what mode was used when encrypting.
*/ */
void setIntegrityProtectionMode(IntegrityProtectionMode mode) {m_protectionMode = mode;} void setIntegrityProtectionMode(IntegrityProtectionMode mode) {
m_protectionMode = mode;
}
/** /**
Returns the IntegrityProtectionMode that is currently in use. Returns the IntegrityProtectionMode that is currently in use.
*/ */
IntegrityProtectionMode integrityProtectionMode() const {return m_protectionMode;} IntegrityProtectionMode integrityProtectionMode() const {
return m_protectionMode;
}
/** /**
Returns the last error that occurred. Returns the last error that occurred.
*/ */
Error lastError() const {return m_lastError;} Error lastError() const {
return m_lastError;
}
/** /**
Encrypts the @arg plaintext string with the key the class was initialized with, and returns Encrypts the @arg plaintext string with the key the class was initialized with, and returns

View File

@ -40,6 +40,7 @@ void SimpleRegExp::setMinimal(bool minimal) {
if (minimal) { if (minimal) {
opt = patternOptions() | QRegularExpression::InvertedGreedinessOption; opt = patternOptions() | QRegularExpression::InvertedGreedinessOption;
} }
else { else {
opt = patternOptions() & ~QRegularExpression::InvertedGreedinessOption; opt = patternOptions() & ~QRegularExpression::InvertedGreedinessOption;
} }
@ -56,6 +57,7 @@ int SimpleRegExp::indexIn(const QString &str, int offset) const {
that->m_capturedTexts.clear(); that->m_capturedTexts.clear();
return -1; return -1;
} }
else { else {
that->m_matchedLength = m.capturedLength(); that->m_matchedLength = m.capturedLength();
that->m_capturedTexts = m.capturedTexts(); that->m_capturedTexts = m.capturedTexts();
@ -71,6 +73,7 @@ QString SimpleRegExp::cap(int nth) const {
if (nth >= 0 && m_capturedTexts.size() > nth) { if (nth >= 0 && m_capturedTexts.size() > nth) {
return m_capturedTexts.at(nth); return m_capturedTexts.at(nth);
} }
else { else {
return QString(); return QString();
} }

View File

@ -33,10 +33,8 @@ SkinFactory::~SkinFactory() {
void SkinFactory::loadCurrentSkin() { void SkinFactory::loadCurrentSkin() {
QList<QString> skin_names_to_try; QList<QString> skin_names_to_try;
skin_names_to_try.append(selectedSkinName()); skin_names_to_try.append(selectedSkinName());
skin_names_to_try.append(APP_SKIN_DEFAULT); skin_names_to_try.append(APP_SKIN_DEFAULT);
bool skin_parsed; bool skin_parsed;
Skin skin_data; Skin skin_data;
QString skin_name; QString skin_name;
@ -47,13 +45,12 @@ void SkinFactory::loadCurrentSkin() {
if (skin_parsed) { if (skin_parsed) {
loadSkinFromData(skin_data); loadSkinFromData(skin_data);
// Set this 'Skin' object as active one. // Set this 'Skin' object as active one.
m_currentSkin = skin_data; m_currentSkin = skin_data;
qDebug("Skin '%s' loaded.", qPrintable(skin_name)); qDebug("Skin '%s' loaded.", qPrintable(skin_name));
return; return;
} }
else { else {
qWarning("Failed to load skin '%s'.", qPrintable(skin_name)); qWarning("Failed to load skin '%s'.", qPrintable(skin_name));
} }
@ -85,7 +82,6 @@ QString SkinFactory::selectedSkinName() const {
Skin SkinFactory::skinInfo(const QString& skin_name, bool* ok) const { Skin SkinFactory::skinInfo(const QString& skin_name, bool* ok) const {
Skin skin; Skin skin;
QStringList base_skin_folders; QStringList base_skin_folders;
base_skin_folders.append(APP_SKIN_PATH); base_skin_folders.append(APP_SKIN_PATH);
base_skin_folders.append(getUserSkinBaseFolder()); base_skin_folders.append(getUserSkinBaseFolder());
@ -95,7 +91,6 @@ Skin SkinFactory::skinInfo(const QString &skin_name, bool *ok) const {
if (QFile::exists(metadata_file)) { if (QFile::exists(metadata_file)) {
QFile skin_file(metadata_file); QFile skin_file(metadata_file);
QDomDocument dokument; QDomDocument dokument;
if (!skin_file.open(QIODevice::Text | QIODevice::ReadOnly) || !dokument.setContent(&skin_file, true)) { if (!skin_file.open(QIODevice::Text | QIODevice::ReadOnly) || !dokument.setContent(&skin_file, true)) {
@ -107,26 +102,19 @@ Skin SkinFactory::skinInfo(const QString &skin_name, bool *ok) const {
} }
const QDomNode skin_node = dokument.namedItem(QSL("skin")); const QDomNode skin_node = dokument.namedItem(QSL("skin"));
// Obtain visible skin name. // Obtain visible skin name.
skin.m_visibleName = skin_name; skin.m_visibleName = skin_name;
// Obtain author. // Obtain author.
skin.m_author = skin_node.namedItem(QSL("author")).namedItem(QSL("name")).toElement().text(); skin.m_author = skin_node.namedItem(QSL("author")).namedItem(QSL("name")).toElement().text();
// Obtain email. // Obtain email.
skin.m_email = skin_node.namedItem(QSL("author")).namedItem(QSL("email")).toElement().text(); skin.m_email = skin_node.namedItem(QSL("author")).namedItem(QSL("email")).toElement().text();
// Obtain version. // Obtain version.
skin.m_version = skin_node.attributes().namedItem(QSL("version")).toAttr().value(); skin.m_version = skin_node.attributes().namedItem(QSL("version")).toAttr().value();
// Obtain other information. // Obtain other information.
skin.m_baseName = skin_name; skin.m_baseName = skin_name;
// Free resources. // Free resources.
skin_file.close(); skin_file.close();
skin_file.deleteLater(); skin_file.deleteLater();
// Here we use "/" instead of QDir::separator() because CSS2.1 url field // Here we use "/" instead of QDir::separator() because CSS2.1 url field
// accepts '/' as path elements separator. // accepts '/' as path elements separator.
// //
@ -135,19 +123,14 @@ Skin SkinFactory::skinInfo(const QString &skin_name, bool *ok) const {
// So if one uses "##/images/border.png" in QSS then it is // So if one uses "##/images/border.png" in QSS then it is
// replaced by fully absolute path and target file can // replaced by fully absolute path and target file can
// be safely loaded. // be safely loaded.
skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_wrapper.html"))); skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_wrapper.html")));
skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name); skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_image.html"))); skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_image.html")));
skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name); skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_single_message.html"))); skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_single_message.html")));
skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name); skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_every.html"))); skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_every.html")));
skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name); skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("theme.css"))); skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("theme.css")));
skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name); skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);

View File

@ -59,6 +59,7 @@ SystemFactory::AutoStartStatus SystemFactory::getAutoStartStatus() const {
if (autostart_enabled) { if (autostart_enabled) {
return SystemFactory::Enabled; return SystemFactory::Enabled;
} }
else { else {
return SystemFactory::Disabled; return SystemFactory::Disabled;
} }
@ -79,9 +80,9 @@ SystemFactory::AutoStartStatus SystemFactory::getAutoStartStatus() const {
// File exists, we must read it and check if "Hidden" attribute is defined and what is its value. // File exists, we must read it and check if "Hidden" attribute is defined and what is its value.
QSettings desktop_settings(desktop_file_location, QSettings::IniFormat); QSettings desktop_settings(desktop_file_location, QSettings::IniFormat);
bool hidden_value = desktop_settings.value(QSL("Desktop Entry/Hidden"), false).toBool(); bool hidden_value = desktop_settings.value(QSL("Desktop Entry/Hidden"), false).toBool();
return hidden_value ? SystemFactory::Disabled : SystemFactory::Enabled; return hidden_value ? SystemFactory::Disabled : SystemFactory::Enabled;
} }
else { else {
return SystemFactory::Disabled; return SystemFactory::Disabled;
} }
@ -102,6 +103,7 @@ QString SystemFactory::getAutostartDesktopFileLocation() const {
// in 'autostart' subdirectory. // in 'autostart' subdirectory.
desktop_file_location = xdg_config_path + QSL("/autostart/") + APP_DESKTOP_ENTRY_FILE; desktop_file_location = xdg_config_path + QSL("/autostart/") + APP_DESKTOP_ENTRY_FILE;
} }
else { else {
// Desired variable is not set, look for the default 'autostart' subdirectory. // Desired variable is not set, look for the default 'autostart' subdirectory.
const QString home_directory(qgetenv("HOME")); const QString home_directory(qgetenv("HOME"));
@ -141,6 +143,7 @@ bool SystemFactory::setAutoStartStatus(const AutoStartStatus &new_status) {
default: default:
return false; return false;
} }
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
// Note that we expect here that no other program uses // Note that we expect here that no other program uses
// "rssguard.desktop" desktop file. // "rssguard.desktop" desktop file.
@ -160,7 +163,6 @@ bool SystemFactory::setAutoStartStatus(const AutoStartStatus &new_status) {
} }
const QString source_autostart_desktop_file = QString(APP_DESKTOP_ENTRY_PATH) + QDir::separator() + APP_DESKTOP_SOURCE_ENTRY_FILE; const QString source_autostart_desktop_file = QString(APP_DESKTOP_ENTRY_PATH) + QDir::separator() + APP_DESKTOP_SOURCE_ENTRY_FILE;
return QFile::copy(source_autostart_desktop_file, destination_file); return QFile::copy(source_autostart_desktop_file, destination_file);
} }
@ -170,6 +172,7 @@ bool SystemFactory::setAutoStartStatus(const AutoStartStatus &new_status) {
default: default:
return false; return false;
} }
#else #else
return false; return false;
#endif #endif
@ -179,12 +182,11 @@ bool SystemFactory::setAutoStartStatus(const AutoStartStatus &new_status) {
bool SystemFactory::removeTrolltechJunkRegistryKeys() { bool SystemFactory::removeTrolltechJunkRegistryKeys() {
if (qApp->settings()->value(GROUP(General), SETTING(General::RemoveTrolltechJunk)).toBool()) { if (qApp->settings()->value(GROUP(General), SETTING(General::RemoveTrolltechJunk)).toBool()) {
QSettings registry_key(QSL("HKEY_CURRENT_USER\\Software\\TrollTech"), QSettings::NativeFormat); QSettings registry_key(QSL("HKEY_CURRENT_USER\\Software\\TrollTech"), QSettings::NativeFormat);
registry_key.remove(QSL("")); registry_key.remove(QSL(""));
registry_key.sync(); registry_key.sync();
return registry_key.status() == QSettings::NoError; return registry_key.status() == QSettings::NoError;
} }
else { else {
return false; return false;
} }
@ -208,7 +210,6 @@ QString SystemFactory::getUsername() const {
QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> SystemFactory::checkForUpdates() const { QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> SystemFactory::checkForUpdates() const {
QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> result; QPair<QList<UpdateInfo>, QNetworkReply::NetworkError> result;
QByteArray releases_json; QByteArray releases_json;
result.second = NetworkFactory::performNetworkOperation(RELEASES_LIST, DOWNLOAD_TIMEOUT, QByteArray(), QString(), result.second = NetworkFactory::performNetworkOperation(RELEASES_LIST, DOWNLOAD_TIMEOUT, QByteArray(), QString(),
releases_json, QNetworkAccessManager::GetOperation).first; releases_json, QNetworkAccessManager::GetOperation).first;
@ -231,6 +232,7 @@ bool SystemFactory::isVersionNewer(const QString &new_version, const QString &ba
// New version is indeed higher thatn current version. // New version is indeed higher thatn current version.
return true; return true;
} }
else if (new_number < base_number) { else if (new_number < base_number) {
return false; return false;
} }
@ -241,10 +243,12 @@ bool SystemFactory::isVersionNewer(const QString &new_version, const QString &ba
// Versions are the same. // Versions are the same.
return false; return false;
} }
else { else {
if (new_version_tkn.isEmpty()) { if (new_version_tkn.isEmpty()) {
return false; return false;
} }
else { else {
return new_version_tkn.join(QString()).toInt() > 0; return new_version_tkn.join(QString()).toInt() > 0;
} }
@ -266,27 +270,22 @@ bool SystemFactory::openFolderFile(const QString &file_path) {
QList<UpdateInfo> SystemFactory::parseUpdatesFile(const QByteArray& updates_file) const { QList<UpdateInfo> SystemFactory::parseUpdatesFile(const QByteArray& updates_file) const {
QList<UpdateInfo> updates; QList<UpdateInfo> updates;
QJsonArray document = QJsonDocument::fromJson(updates_file).array(); QJsonArray document = QJsonDocument::fromJson(updates_file).array();
for (int i = 0; i < document.size(); i++) { for (int i = 0; i < document.size(); i++) {
QJsonObject release = document.at(i).toObject(); QJsonObject release = document.at(i).toObject();
UpdateInfo update; UpdateInfo update;
update.m_date = QDateTime::fromString(release["published_at"].toString(), QSL("yyyy-MM-ddTHH:mm:ssZ")); update.m_date = QDateTime::fromString(release["published_at"].toString(), QSL("yyyy-MM-ddTHH:mm:ssZ"));
update.m_availableVersion = release["tag_name"].toString(); update.m_availableVersion = release["tag_name"].toString();
update.m_changes = release["body"].toString(); update.m_changes = release["body"].toString();
QJsonArray assets = release["assets"].toArray(); QJsonArray assets = release["assets"].toArray();
for (int j = 0; j < assets.size(); j++) { for (int j = 0; j < assets.size(); j++) {
QJsonObject asset = assets.at(j).toObject(); QJsonObject asset = assets.at(j).toObject();
UpdateUrl url; UpdateUrl url;
url.m_fileUrl = asset["browser_download_url"].toString(); url.m_fileUrl = asset["browser_download_url"].toString();
url.m_name = asset["name"].toString(); url.m_name = asset["name"].toString();
url.m_size = asset["size"].toVariant().toString() + tr(" bytes"); url.m_size = asset["size"].toVariant().toString() + tr(" bytes");
update.m_urls.append(url); update.m_urls.append(url);
} }
@ -296,7 +295,6 @@ QList<UpdateInfo> SystemFactory::parseUpdatesFile(const QByteArray &updates_file
qSort(updates.begin(), updates.end(), [](const UpdateInfo & a, const UpdateInfo & b) -> bool { qSort(updates.begin(), updates.end(), [](const UpdateInfo & a, const UpdateInfo & b) -> bool {
return a.m_date > b.m_date; return a.m_date > b.m_date;
}); });
return updates; return updates;
} }

View File

@ -60,14 +60,14 @@ QDateTime TextFactory::parseDateTime(const QString &date_time) {
QTime time_zone_offset; QTime time_zone_offset;
const QLocale locale(QLocale::C); const QLocale locale(QLocale::C);
bool positive_time_zone_offset = false; bool positive_time_zone_offset = false;
QStringList date_patterns;
QStringList date_patterns; date_patterns << QSL("yyyy-MM-ddTHH:mm:ss") << QSL("MMM dd yyyy hh:mm:ss") << date_patterns << QSL("yyyy-MM-ddTHH:mm:ss") << QSL("MMM dd yyyy hh:mm:ss") <<
QSL("MMM d yyyy hh:mm:ss") << QSL("ddd, dd MMM yyyy HH:mm:ss") << QSL("MMM d yyyy hh:mm:ss") << QSL("ddd, dd MMM yyyy HH:mm:ss") <<
QSL("dd MMM yyyy") << QSL("yyyy-MM-dd HH:mm:ss.z") << QSL("yyyy-MM-dd") << QSL("dd MMM yyyy") << QSL("yyyy-MM-dd HH:mm:ss.z") << QSL("yyyy-MM-dd") <<
QSL("yyyy") << QSL("yyyy-MM") << QSL("yyyy-MM-dd") << QSL("yyyy-MM-ddThh:mm") << QSL("yyyy") << QSL("yyyy-MM") << QSL("yyyy-MM-dd") << QSL("yyyy-MM-ddThh:mm") <<
QSL("yyyy-MM-ddThh:mm:ss"); QSL("yyyy-MM-ddThh:mm:ss");
QStringList timezone_offset_patterns;
QStringList timezone_offset_patterns; timezone_offset_patterns << QSL("+hh:mm") << QSL("-hh:mm") << QSL("+hhmm") timezone_offset_patterns << QSL("+hh:mm") << QSL("-hh:mm") << QSL("+hhmm")
<< QSL("-hhmm") << QSL("+hh") << QSL("-hh"); << QSL("-hhmm") << QSL("+hh") << QSL("-hh");
if (input_date.size() >= TIMEZONE_OFFSET_LIMIT) { if (input_date.size() >= TIMEZONE_OFFSET_LIMIT) {
@ -96,11 +96,13 @@ QDateTime TextFactory::parseDateTime(const QString &date_time) {
// the original UTC. // the original UTC.
return dt.addSecs(- QTime(0, 0, 0, 0).secsTo(time_zone_offset)); return dt.addSecs(- QTime(0, 0, 0, 0).secsTo(time_zone_offset));
} }
else { else {
// Vice versa. // Vice versa.
return dt.addSecs(QTime(0, 0, 0, 0).secsTo(time_zone_offset)); return dt.addSecs(QTime(0, 0, 0, 0).secsTo(time_zone_offset));
} }
} }
else { else {
return dt; return dt;
} }
@ -127,6 +129,7 @@ QString TextFactory::shorten(const QString &input, int text_length_limit) {
if (input.size() > text_length_limit) { if (input.size() > text_length_limit) {
return input.left(text_length_limit - ELLIPSIS_LENGTH) + QString(ELLIPSIS_LENGTH, QL1C('.')); return input.left(text_length_limit - ELLIPSIS_LENGTH) + QString(ELLIPSIS_LENGTH, QL1C('.'));
} }
else { else {
return input; return input;
} }
@ -140,6 +143,7 @@ quint64 TextFactory::initializeSecretEncryptionKey() {
try { try {
s_encryptionKey = (quint64) QString(IOFactory::readTextFile(encryption_file_path)).toLongLong(); s_encryptionKey = (quint64) QString(IOFactory::readTextFile(encryption_file_path)).toLongLong();
} }
catch (ApplicationException) { catch (ApplicationException) {
// Well, key does not exist or is invalid, generate and save one. // Well, key does not exist or is invalid, generate and save one.
s_encryptionKey = generateSecretEncryptionKey(); s_encryptionKey = generateSecretEncryptionKey();

View File

@ -26,7 +26,6 @@
AdBlockAddSubscriptionDialog::AdBlockAddSubscriptionDialog(QWidget* parent) AdBlockAddSubscriptionDialog::AdBlockAddSubscriptionDialog(QWidget* parent)
: QDialog(parent), m_ui(new Ui::AdBlockAddSubscriptionDialog) { : QDialog(parent), m_ui(new Ui::AdBlockAddSubscriptionDialog) {
m_ui->setupUi(this); m_ui->setupUi(this);
m_knownSubscriptions << Subscription(QSL("EasyList (English)"), ADBLOCK_EASYLIST_URL) m_knownSubscriptions << Subscription(QSL("EasyList (English)"), ADBLOCK_EASYLIST_URL)
<< Subscription(QSL("BSI Lista Polska (Polish)"), QSL("http://www.bsi.info.pl/filtrABP.txt")) << Subscription(QSL("BSI Lista Polska (Polish)"), QSL("http://www.bsi.info.pl/filtrABP.txt"))
<< Subscription(QSL("EasyList Czech and Slovak (Czech)"), QSL("https://raw.githubusercontent.com/tomasko126/easylistczechandslovak/master/filters.txt")) << Subscription(QSL("EasyList Czech and Slovak (Czech)"), QSL("https://raw.githubusercontent.com/tomasko126/easylistczechandslovak/master/filters.txt"))
@ -70,6 +69,7 @@ void AdBlockAddSubscriptionDialog::indexChanged(int index) {
m_ui->title->clear(); m_ui->title->clear();
m_ui->url->clear(); m_ui->url->clear();
} }
else { else {
int pos = subscription.m_title.indexOf(QLatin1Char('(')); int pos = subscription.m_title.indexOf(QLatin1Char('('));
QString title = subscription.m_title; QString title = subscription.m_title;
@ -80,7 +80,6 @@ void AdBlockAddSubscriptionDialog::indexChanged(int index) {
m_ui->title->setText(title); m_ui->title->setText(title);
m_ui->title->setCursorPosition(0); m_ui->title->setCursorPosition(0);
m_ui->url->setText(subscription.m_url); m_ui->url->setText(subscription.m_url);
m_ui->url->setCursorPosition(0); m_ui->url->setCursorPosition(0);
} }

View File

@ -34,13 +34,10 @@ AdBlockDialog::AdBlockDialog(QWidget* parent)
: QWidget(parent), m_ui(new Ui::AdBlockDialog), m_manager(AdBlockManager::instance()), m_currentTreeWidget(0), m_currentSubscription(0), m_loaded(false) { : QWidget(parent), m_ui(new Ui::AdBlockDialog), m_manager(AdBlockManager::instance()), m_currentTreeWidget(0), m_currentSubscription(0), m_loaded(false) {
setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_DeleteOnClose);
m_ui->setupUi(this); m_ui->setupUi(this);
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
m_ui->tabWidget->setDocumentMode(false); m_ui->tabWidget->setDocumentMode(false);
#endif #endif
m_ui->adblockCheckBox->setChecked(m_manager->isEnabled()); m_ui->adblockCheckBox->setChecked(m_manager->isEnabled());
QMenu* menu = new QMenu(m_ui->buttonOptions); QMenu* menu = new QMenu(m_ui->buttonOptions);
m_actionAddRule = menu->addAction(tr("Add rule"), this, SLOT(addRule())); m_actionAddRule = menu->addAction(tr("Add rule"), this, SLOT(addRule()));
m_actionRemoveRule = menu->addAction(tr("Remove rule"), this, SLOT(removeRule())); m_actionRemoveRule = menu->addAction(tr("Remove rule"), this, SLOT(removeRule()));
@ -50,16 +47,12 @@ AdBlockDialog::AdBlockDialog(QWidget* parent)
menu->addAction(tr("Update subscriptions"), m_manager, SLOT(updateAllSubscriptions())); menu->addAction(tr("Update subscriptions"), m_manager, SLOT(updateAllSubscriptions()));
menu->addSeparator(); menu->addSeparator();
menu->addAction(tr("Learn about writing rules..."), this, SLOT(learnAboutRules())); menu->addAction(tr("Learn about writing rules..."), this, SLOT(learnAboutRules()));
m_ui->buttonOptions->setMenu(menu); m_ui->buttonOptions->setMenu(menu);
connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowMenu())); connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowMenu()));
connect(m_ui->adblockCheckBox, SIGNAL(toggled(bool)), this, SLOT(enableAdBlock(bool))); connect(m_ui->adblockCheckBox, SIGNAL(toggled(bool)), this, SLOT(enableAdBlock(bool)));
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int)));
connect(m_ui->buttonBox, &QDialogButtonBox::clicked, this, &AdBlockDialog::close); connect(m_ui->buttonBox, &QDialogButtonBox::clicked, this, &AdBlockDialog::close);
load(); load();
m_ui->buttonBox->setFocus(); m_ui->buttonBox->setFocus();
} }
@ -102,7 +95,6 @@ void AdBlockDialog::addSubscription() {
if (AdBlockSubscription* subscription = m_manager->addSubscription(title, url)) { if (AdBlockSubscription* subscription = m_manager->addSubscription(title, url)) {
AdBlockTreeWidget* tree = new AdBlockTreeWidget(subscription, m_ui->tabWidget); AdBlockTreeWidget* tree = new AdBlockTreeWidget(subscription, m_ui->tabWidget);
int index = m_ui->tabWidget->insertTab(m_ui->tabWidget->count() - 1, tree, subscription->title()); int index = m_ui->tabWidget->insertTab(m_ui->tabWidget->count() - 1, tree, subscription->title());
m_ui->tabWidget->setCurrentIndex(index); m_ui->tabWidget->setCurrentIndex(index);
} }
} }
@ -131,7 +123,6 @@ void AdBlockDialog::enableAdBlock(bool state) {
void AdBlockDialog::aboutToShowMenu() { void AdBlockDialog::aboutToShowMenu() {
bool subscriptionEditable = m_currentSubscription && m_currentSubscription->canEditRules(); bool subscriptionEditable = m_currentSubscription && m_currentSubscription->canEditRules();
bool subscriptionRemovable = m_currentSubscription && m_currentSubscription->canBeRemoved(); bool subscriptionRemovable = m_currentSubscription && m_currentSubscription->canBeRemoved();
m_actionAddRule->setEnabled(subscriptionEditable); m_actionAddRule->setEnabled(subscriptionEditable);
m_actionRemoveRule->setEnabled(subscriptionEditable); m_actionRemoveRule->setEnabled(subscriptionEditable);
m_actionRemoveSubscription->setEnabled(subscriptionRemovable); m_actionRemoveSubscription->setEnabled(subscriptionRemovable);
@ -159,6 +150,5 @@ void AdBlockDialog::load() {
} }
m_loaded = true; m_loaded = true;
QTimer::singleShot(50, this, SLOT(loadSubscriptions())); QTimer::singleShot(50, this, SLOT(loadSubscriptions()));
} }

View File

@ -37,10 +37,8 @@ AdBlockIcon::AdBlockIcon(QWidget* parent)
setCursor(Qt::PointingHandCursor); setCursor(Qt::PointingHandCursor);
setToolTip(tr("AdBlock lets you block unwanted content on web pages")); setToolTip(tr("AdBlock lets you block unwanted content on web pages"));
setFixedSize(16, 16); setFixedSize(16, 16);
connect(this, SIGNAL(clicked(QPoint)), this, SLOT(showMenu(QPoint))); connect(this, SIGNAL(clicked(QPoint)), this, SLOT(showMenu(QPoint)));
connect(AdBlockManager::instance(), SIGNAL(enabledChanged(bool)), this, SLOT(setEnabled(bool))); connect(AdBlockManager::instance(), SIGNAL(enabledChanged(bool)), this, SLOT(setEnabled(bool)));
m_enabled = AdBlockManager::instance()->isEnabled(); m_enabled = AdBlockManager::instance()->isEnabled();
} }
@ -52,10 +50,10 @@ AdBlockIcon::~AdBlockIcon() {
void AdBlockIcon::popupBlocked(const QString& ruleString, const QUrl& url) { void AdBlockIcon::popupBlocked(const QString& ruleString, const QUrl& url) {
int index = ruleString.lastIndexOf(QLatin1String(" (")); int index = ruleString.lastIndexOf(QLatin1String(" ("));
const QString subscriptionName = ruleString.left(index); const QString subscriptionName = ruleString.left(index);
const QString filter = ruleString.mid(index + 2, ruleString.size() - index - 3); const QString filter = ruleString.mid(index + 2, ruleString.size() - index - 3);
AdBlockSubscription* subscription = AdBlockManager::instance()->subscriptionByName(subscriptionName); AdBlockSubscription* subscription = AdBlockManager::instance()->subscriptionByName(subscriptionName);
if (filter.isEmpty() || !subscription) { if (filter.isEmpty() || !subscription) {
return; return;
} }
@ -64,7 +62,6 @@ void AdBlockIcon::popupBlocked(const QString &ruleString, const QUrl &url) {
pair.first = new AdBlockRule(filter, subscription); pair.first = new AdBlockRule(filter, subscription);
pair.second = url; pair.second = url;
m_blockedPopups.append(pair); m_blockedPopups.append(pair);
qApp->showGuiMessage(tr("Blocked popup window"), tr("AdBlock blocked unwanted popup window."), QSystemTrayIcon::Information); qApp->showGuiMessage(tr("Blocked popup window"), tr("AdBlock blocked unwanted popup window."), QSystemTrayIcon::Information);
if (!m_flashTimer) { if (!m_flashTimer) {
@ -77,7 +74,6 @@ void AdBlockIcon::popupBlocked(const QString &ruleString, const QUrl &url) {
m_flashTimer->setInterval(500); m_flashTimer->setInterval(500);
m_flashTimer->start(); m_flashTimer->start();
connect(m_flashTimer, &QTimer::timeout, this, &AdBlockIcon::animateIcon); connect(m_flashTimer, &QTimer::timeout, this, &AdBlockIcon::animateIcon);
} }
@ -103,13 +99,10 @@ void AdBlockIcon::createMenu(QMenu *menu) {
} }
menu->clear(); menu->clear();
AdBlockManager* manager = AdBlockManager::instance(); AdBlockManager* manager = AdBlockManager::instance();
AdBlockCustomList* customList = manager->customList(); AdBlockCustomList* customList = manager->customList();
WebPage* page = qApp->mainForm()->tabWidget()->currentWidget()->webBrowser()->viewer()->page(); WebPage* page = qApp->mainForm()->tabWidget()->currentWidget()->webBrowser()->viewer()->page();
const QUrl pageUrl = page->url(); const QUrl pageUrl = page->url();
menu->addAction(tr("Show AdBlock &settings"), manager, SLOT(showDialog())); menu->addAction(tr("Show AdBlock &settings"), manager, SLOT(showDialog()));
menu->addSeparator(); menu->addSeparator();
@ -117,19 +110,16 @@ void AdBlockIcon::createMenu(QMenu *menu) {
const QString host = page->url().host().contains(QLatin1String("www.")) ? pageUrl.host().mid(4) : pageUrl.host(); const QString host = page->url().host().contains(QLatin1String("www.")) ? pageUrl.host().mid(4) : pageUrl.host();
const QString hostFilter = QString("@@||%1^$document").arg(host); const QString hostFilter = QString("@@||%1^$document").arg(host);
const QString pageFilter = QString("@@|%1|$document").arg(pageUrl.toString()); const QString pageFilter = QString("@@|%1|$document").arg(pageUrl.toString());
QAction* act = menu->addAction(tr("Disable on %1").arg(host)); QAction* act = menu->addAction(tr("Disable on %1").arg(host));
act->setCheckable(true); act->setCheckable(true);
act->setChecked(customList->containsFilter(hostFilter)); act->setChecked(customList->containsFilter(hostFilter));
act->setData(hostFilter); act->setData(hostFilter);
connect(act, SIGNAL(triggered()), this, SLOT(toggleCustomFilter())); connect(act, SIGNAL(triggered()), this, SLOT(toggleCustomFilter()));
act = menu->addAction(tr("Disable only on this page")); act = menu->addAction(tr("Disable only on this page"));
act->setCheckable(true); act->setCheckable(true);
act->setChecked(customList->containsFilter(pageFilter)); act->setChecked(customList->containsFilter(pageFilter));
act->setData(pageFilter); act->setData(pageFilter);
connect(act, SIGNAL(triggered()), this, SLOT(toggleCustomFilter())); connect(act, SIGNAL(triggered()), this, SLOT(toggleCustomFilter()));
menu->addSeparator(); menu->addSeparator();
} }
@ -138,10 +128,8 @@ void AdBlockIcon::createMenu(QMenu *menu) {
for (int i = 0; i < m_blockedPopups.count(); i++) { for (int i = 0; i < m_blockedPopups.count(); i++) {
const QPair<AdBlockRule*, QUrl>& pair = m_blockedPopups.at(i); const QPair<AdBlockRule*, QUrl>& pair = m_blockedPopups.at(i);
QString address = pair.second.toString().right(55); QString address = pair.second.toString().right(55);
QString actionText = tr("%1 with (%2)").arg(address, pair.first->filter()).replace(QL1C('&'), QL1S("&&")); QString actionText = tr("%1 with (%2)").arg(address, pair.first->filter()).replace(QL1C('&'), QL1S("&&"));
QAction* action = menu->addAction(actionText, manager, SLOT(showRule())); QAction* action = menu->addAction(actionText, manager, SLOT(showRule()));
action->setData(QVariant::fromValue((void*)pair.first)); action->setData(QVariant::fromValue((void*)pair.first));
} }
@ -151,7 +139,6 @@ void AdBlockIcon::createMenu(QMenu *menu) {
void AdBlockIcon::showMenu(const QPoint& pos) { void AdBlockIcon::showMenu(const QPoint& pos) {
QMenu menu; QMenu menu;
createMenu(&menu); createMenu(&menu);
menu.exec(pos); menu.exec(pos);
} }
@ -169,6 +156,7 @@ void AdBlockIcon::toggleCustomFilter() {
if (customList->containsFilter(filter)) { if (customList->containsFilter(filter)) {
customList->removeFilter(filter); customList->removeFilter(filter);
} }
else { else {
AdBlockRule* rule = new AdBlockRule(filter, customList); AdBlockRule* rule = new AdBlockRule(filter, customList);
customList->addRule(rule); customList->addRule(rule);
@ -186,6 +174,7 @@ void AdBlockIcon::animateIcon() {
if (pixmap()->isNull()) { if (pixmap()->isNull()) {
setPixmap(qApp->icons()->miscIcon(ADBLOCK_ICON_ACTIVE).pixmap(16)); setPixmap(qApp->icons()->miscIcon(ADBLOCK_ICON_ACTIVE).pixmap(16));
} }
else { else {
setPixmap(QPixmap()); setPixmap(QPixmap());
} }
@ -195,7 +184,6 @@ void AdBlockIcon::stopAnimation() {
m_timerTicks = 0; m_timerTicks = 0;
m_flashTimer->stop(); m_flashTimer->stop();
disconnect(m_flashTimer, SIGNAL(timeout()), this, SLOT(animateIcon())); disconnect(m_flashTimer, SIGNAL(timeout()), this, SLOT(animateIcon()));
setEnabled(m_enabled); setEnabled(m_enabled);
} }
@ -203,6 +191,7 @@ void AdBlockIcon::setEnabled(bool enabled) {
if (enabled) { if (enabled) {
setPixmap(qApp->icons()->miscIcon(ADBLOCK_ICON_ACTIVE).pixmap(16)); setPixmap(qApp->icons()->miscIcon(ADBLOCK_ICON_ACTIVE).pixmap(16));
} }
else { else {
setPixmap(qApp->icons()->miscIcon(ADBLOCK_ICON_DISABLED).pixmap(16)); setPixmap(qApp->icons()->miscIcon(ADBLOCK_ICON_DISABLED).pixmap(16));
} }

View File

@ -46,9 +46,13 @@ AdBlockManager::AdBlockManager(QObject* parent)
load(); load();
} }
AdBlockManager::~AdBlockManager() { qDeleteAll(m_subscriptions); } AdBlockManager::~AdBlockManager() {
qDeleteAll(m_subscriptions);
}
AdBlockManager* AdBlockManager::instance() { return qz_adblock_manager(); } AdBlockManager* AdBlockManager::instance() {
return qz_adblock_manager();
}
void AdBlockManager::setEnabled(bool enabled) { void AdBlockManager::setEnabled(bool enabled) {
if (m_enabled == enabled) { if (m_enabled == enabled) {
@ -57,17 +61,16 @@ void AdBlockManager::setEnabled(bool enabled) {
m_enabled = enabled; m_enabled = enabled;
emit enabledChanged(enabled); emit enabledChanged(enabled);
qApp->settings()->setValue(GROUP(AdBlock), AdBlock::AdBlockEnabled, m_enabled); qApp->settings()->setValue(GROUP(AdBlock), AdBlock::AdBlockEnabled, m_enabled);
load(); load();
// TODO: Reload user stylesheet. // TODO: Reload user stylesheet.
// mApp->reloadUserStyleSheet(); // mApp->reloadUserStyleSheet();
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
if (m_enabled) { if (m_enabled) {
m_matcher->update(); m_matcher->update();
} }
else { else {
m_matcher->clear(); m_matcher->clear();
} }
@ -102,7 +105,6 @@ bool AdBlockManager::block(QWebEngineUrlRequestInfo& request) {
// We are blocking main URL frame, we can display "AdBlock error page" or // We are blocking main URL frame, we can display "AdBlock error page" or
// redirect to somewhere. // redirect to somewhere.
// TODO: dodělat lepší // TODO: dodělat lepší
// TODO request.redirect() přesměrovat na "chybovou stranku"; // TODO request.redirect() přesměrovat na "chybovou stranku";
// QUrl url(QSL("rssguard:adblock")); // QUrl url(QSL("rssguard:adblock"));
// QUrlQuery query; // QUrlQuery query;
@ -111,9 +113,9 @@ bool AdBlockManager::block(QWebEngineUrlRequestInfo& request) {
// blockedRule->subscription()->title()); // blockedRule->subscription()->title());
// url.setQuery(query); // url.setQuery(query);
// request.redirect(url); // request.redirect(url);
request.block(true); request.block(true);
} }
else { else {
request.block(true); request.block(true);
} }
@ -122,7 +124,9 @@ bool AdBlockManager::block(QWebEngineUrlRequestInfo& request) {
return res; return res;
} }
QStringList AdBlockManager::disabledRules() const { return m_disabledRules; } QStringList AdBlockManager::disabledRules() const {
return m_disabledRules;
}
void AdBlockManager::addDisabledRule(const QString& filter) { void AdBlockManager::addDisabledRule(const QString& filter) {
m_disabledRules.append(filter); m_disabledRules.append(filter);
@ -134,7 +138,6 @@ void AdBlockManager::removeDisabledRule(const QString& filter) {
bool AdBlockManager::addSubscriptionFromUrl(const QUrl& url) { bool AdBlockManager::addSubscriptionFromUrl(const QUrl& url) {
const QList<QPair<QString, QString>> queryItems = QUrlQuery(url).queryItems(QUrl::FullyDecoded); const QList<QPair<QString, QString>> queryItems = QUrlQuery(url).queryItems(QUrl::FullyDecoded);
QString subscriptionTitle; QString subscriptionTitle;
QString subscriptionUrl; QString subscriptionUrl;
@ -144,6 +147,7 @@ bool AdBlockManager::addSubscriptionFromUrl(const QUrl& url) {
if (pair.first == QL1S("location")) { if (pair.first == QL1S("location")) {
subscriptionUrl = pair.second; subscriptionUrl = pair.second;
} }
else if (pair.first == QL1S("title")) { else if (pair.first == QL1S("title")) {
subscriptionTitle = pair.second; subscriptionTitle = pair.second;
} }
@ -154,7 +158,6 @@ bool AdBlockManager::addSubscriptionFromUrl(const QUrl& url) {
} }
const QString message = tr("Do you want to add <b>%1</b> subscription?").arg(subscriptionTitle); const QString message = tr("Do you want to add <b>%1</b> subscription?").arg(subscriptionTitle);
QMessageBox::StandardButton result = QMessageBox::question(nullptr, tr("Add AdBlock subscription"), message, QMessageBox::StandardButton result = QMessageBox::question(nullptr, tr("Add AdBlock subscription"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
@ -174,8 +177,8 @@ AdBlockSubscription* AdBlockManager::addSubscription(const QString& title, const
QString fileName = title + QSL(".txt"); QString fileName = title + QSL(".txt");
QString filePath = storedListsPath() + QDir::separator() + fileName; QString filePath = storedListsPath() + QDir::separator() + fileName;
QByteArray data = QString("Title: %1\nUrl: %2\n[Adblock Plus 1.1.1]").arg(title, url).toLatin1(); QByteArray data = QString("Title: %1\nUrl: %2\n[Adblock Plus 1.1.1]").arg(title, url).toLatin1();
QSaveFile file(filePath); QSaveFile file(filePath);
if (!file.open(QFile::WriteOnly)) { if (!file.open(QFile::WriteOnly)) {
qWarning("Cannot save AdBlock subscription to file '%s'.", qPrintable(filePath)); qWarning("Cannot save AdBlock subscription to file '%s'.", qPrintable(filePath));
return 0; return 0;
@ -183,19 +186,15 @@ AdBlockSubscription* AdBlockManager::addSubscription(const QString& title, const
file.write(data); file.write(data);
file.commit(); file.commit();
AdBlockSubscription* subscription = new AdBlockSubscription(title, this); AdBlockSubscription* subscription = new AdBlockSubscription(title, this);
subscription->setUrl(QUrl(url)); subscription->setUrl(QUrl(url));
subscription->setFilePath(filePath); subscription->setFilePath(filePath);
subscription->loadSubscription(m_disabledRules); subscription->loadSubscription(m_disabledRules);
m_subscriptions.insert(m_subscriptions.count() - 1, subscription); m_subscriptions.insert(m_subscriptions.count() - 1, subscription);
// TODO: po změně subskripce přehrat user css? // TODO: po změně subskripce přehrat user css?
// connect(subscription, SIGNAL(subscriptionUpdated()), mApp, // connect(subscription, SIGNAL(subscriptionUpdated()), mApp,
// SLOT(reloadUserStyleSheet())); // SLOT(reloadUserStyleSheet()));
connect(subscription, SIGNAL(subscriptionChanged()), this, SLOT(updateMatcher())); connect(subscription, SIGNAL(subscriptionChanged()), this, SLOT(updateMatcher()));
return subscription; return subscription;
} }
@ -208,10 +207,8 @@ bool AdBlockManager::removeSubscription(AdBlockSubscription *subscription) {
QFile(subscription->filePath()).remove(); QFile(subscription->filePath()).remove();
m_subscriptions.removeOne(subscription); m_subscriptions.removeOne(subscription);
m_matcher->update(); m_matcher->update();
delete subscription; delete subscription;
return true; return true;
} }
@ -278,7 +275,6 @@ void AdBlockManager::load() {
AdBlockSubscription* subscription = new AdBlockSubscription(title, this); AdBlockSubscription* subscription = new AdBlockSubscription(title, this);
subscription->setUrl(url); subscription->setUrl(url);
subscription->setFilePath(absolutePath); subscription->setFilePath(absolutePath);
m_subscriptions.append(subscription); m_subscriptions.append(subscription);
} }
@ -289,7 +285,6 @@ void AdBlockManager::load() {
// Load all subscriptions // Load all subscriptions
foreach (AdBlockSubscription* subscription, m_subscriptions) { foreach (AdBlockSubscription* subscription, m_subscriptions) {
subscription->loadSubscription(m_disabledRules); subscription->loadSubscription(m_disabledRules);
// TODO: po zmene subskripce prehrat user css? // TODO: po zmene subskripce prehrat user css?
// connect(subscription, SIGNAL(subscriptionUpdated()), mApp, // connect(subscription, SIGNAL(subscriptionUpdated()), mApp,
// SLOT(reloadUserStyleSheet())); // SLOT(reloadUserStyleSheet()));
@ -302,13 +297,11 @@ void AdBlockManager::load() {
m_matcher->update(); m_matcher->update();
m_loaded = true; m_loaded = true;
qApp->urlIinterceptor()->installUrlInterceptor(m_interceptor); qApp->urlIinterceptor()->installUrlInterceptor(m_interceptor);
} }
void AdBlockManager::updateMatcher() { void AdBlockManager::updateMatcher() {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
m_matcher->update(); m_matcher->update();
} }
@ -333,7 +326,9 @@ void AdBlockManager::save() {
qApp->settings()->setValue(GROUP(AdBlock), AdBlock::DisabledRules, m_disabledRules); qApp->settings()->setValue(GROUP(AdBlock), AdBlock::DisabledRules, m_disabledRules);
} }
bool AdBlockManager::isEnabled() const { return m_enabled; } bool AdBlockManager::isEnabled() const {
return m_enabled;
}
bool AdBlockManager::canRunOnScheme(const QString& scheme) const { bool AdBlockManager::canRunOnScheme(const QString& scheme) const {
return !(scheme == QSL("file") || scheme == QSL("qrc") || scheme == QSL("data") || scheme == QSL("abp")); return !(scheme == QSL("file") || scheme == QSL("qrc") || scheme == QSL("data") || scheme == QSL("abp"));
@ -347,6 +342,7 @@ QString AdBlockManager::elementHidingRules(const QUrl& url) const {
if (!isEnabled() || !canRunOnScheme(url.scheme()) || !canBeBlocked(url)) { if (!isEnabled() || !canRunOnScheme(url.scheme()) || !canBeBlocked(url)) {
return QString(); return QString();
} }
else { else {
return m_matcher->elementHidingRules(); return m_matcher->elementHidingRules();
} }
@ -356,6 +352,7 @@ QString AdBlockManager::elementHidingRulesForDomain(const QUrl& url) const {
if (!isEnabled() || !canRunOnScheme(url.scheme()) || !canBeBlocked(url)) { if (!isEnabled() || !canRunOnScheme(url.scheme()) || !canBeBlocked(url)) {
return QString(); return QString();
} }
else { else {
return m_matcher->elementHidingRulesForDomain(url.host()); return m_matcher->elementHidingRulesForDomain(url.host());
} }
@ -379,7 +376,6 @@ AdBlockDialog *AdBlockManager::showDialog() {
m_adBlockDialog.data()->show(); m_adBlockDialog.data()->show();
m_adBlockDialog.data()->raise(); m_adBlockDialog.data()->raise();
m_adBlockDialog.data()->activateWindow(); m_adBlockDialog.data()->activateWindow();
return m_adBlockDialog.data(); return m_adBlockDialog.data();
} }

View File

@ -61,8 +61,7 @@ class AdBlockManager : public QObject {
bool addSubscriptionFromUrl(const QUrl& url); bool addSubscriptionFromUrl(const QUrl& url);
AdBlockSubscription *addSubscription(const QString& title, AdBlockSubscription* addSubscription(const QString& title, const QString& url);
const QString &url);
bool removeSubscription(AdBlockSubscription* subscription); bool removeSubscription(AdBlockSubscription* subscription);
AdBlockCustomList* customList() const; AdBlockCustomList* customList() const;

View File

@ -115,6 +115,7 @@ QString AdBlockMatcher::elementHidingRulesForDomain(const QString &domain) const
rules.append(QSL("{display:none !important;}\n")); rules.append(QSL("{display:none !important;}\n"));
addedRulesCount = 0; addedRulesCount = 0;
} }
else { else {
rules.append(rule->cssSelector() + QLatin1Char(',')); rules.append(rule->cssSelector() + QLatin1Char(','));
addedRulesCount++; addedRulesCount++;
@ -131,7 +132,6 @@ QString AdBlockMatcher::elementHidingRulesForDomain(const QString &domain) const
void AdBlockMatcher::update() { void AdBlockMatcher::update() {
clear(); clear();
QHash<QString, const AdBlockRule*> cssRulesHash; QHash<QString, const AdBlockRule*> cssRulesHash;
QVector<const AdBlockRule*> exceptionCssRules; QVector<const AdBlockRule*> exceptionCssRules;
@ -152,21 +152,26 @@ void AdBlockMatcher::update() {
if (rule->isException()) { if (rule->isException()) {
exceptionCssRules.append(rule); exceptionCssRules.append(rule);
} }
else { else {
cssRulesHash.insert(rule->cssSelector(), rule); cssRulesHash.insert(rule->cssSelector(), rule);
} }
} }
else if (rule->isDocument()) { else if (rule->isDocument()) {
m_documentRules.append(rule); m_documentRules.append(rule);
} }
else if (rule->isElemhide()) { else if (rule->isElemhide()) {
m_elemhideRules.append(rule); m_elemhideRules.append(rule);
} }
else if (rule->isException()) { else if (rule->isException()) {
if (!m_networkExceptionTree.add(rule)) { if (!m_networkExceptionTree.add(rule)) {
m_networkExceptionRules.append(rule); m_networkExceptionRules.append(rule);
} }
} }
else { else {
if (!m_networkBlockTree.add(rule)) { if (!m_networkBlockTree.add(rule)) {
m_networkBlockRules.append(rule); m_networkBlockRules.append(rule);
@ -186,7 +191,6 @@ void AdBlockMatcher::update() {
AdBlockRule* copiedRule = originalRule->copy(); AdBlockRule* copiedRule = originalRule->copy();
copiedRule->m_options |= AdBlockRule::DomainRestrictedOption; copiedRule->m_options |= AdBlockRule::DomainRestrictedOption;
copiedRule->m_blockedDomains.append(rule->m_allowedDomains); copiedRule->m_blockedDomains.append(rule->m_allowedDomains);
cssRulesHash[rule->cssSelector()] = copiedRule; cssRulesHash[rule->cssSelector()] = copiedRule;
m_createdRules.append(copiedRule); m_createdRules.append(copiedRule);
} }
@ -204,11 +208,13 @@ void AdBlockMatcher::update() {
if (rule->isDomainRestricted()) { if (rule->isDomainRestricted()) {
m_domainRestrictedCssRules.append(rule); m_domainRestrictedCssRules.append(rule);
} }
else if (Q_UNLIKELY(hidingRulesCount == 1000)) { else if (Q_UNLIKELY(hidingRulesCount == 1000)) {
m_elementHidingRules.append(rule->cssSelector()); m_elementHidingRules.append(rule->cssSelector());
m_elementHidingRules.append(QL1S("{display:none !important;} ")); m_elementHidingRules.append(QL1S("{display:none !important;} "));
hidingRulesCount = 0; hidingRulesCount = 0;
} }
else { else {
m_elementHidingRules.append(rule->cssSelector() + QLatin1Char(',')); m_elementHidingRules.append(rule->cssSelector() + QLatin1Char(','));
hidingRulesCount++; hidingRulesCount++;

View File

@ -91,7 +91,6 @@ AdBlockRule::~AdBlockRule() {
AdBlockRule* AdBlockRule::copy() const { AdBlockRule* AdBlockRule::copy() const {
AdBlockRule* rule = new AdBlockRule(); AdBlockRule* rule = new AdBlockRule();
rule->m_subscription = m_subscription; rule->m_subscription = m_subscription;
rule->m_type = m_type; rule->m_type = m_type;
rule->m_options = m_options; rule->m_options = m_options;
@ -179,10 +178,10 @@ bool AdBlockRule::urlMatch(const QUrl &url) const {
if (!hasOption(DocumentOption) && !hasOption(ElementHideOption)) { if (!hasOption(DocumentOption) && !hasOption(ElementHideOption)) {
return false; return false;
} }
else { else {
const QString encodedUrl = url.toEncoded(); const QString encodedUrl = url.toEncoded();
const QString domain = url.host(); const QString domain = url.host();
return stringMatch(domain, encodedUrl); return stringMatch(domain, encodedUrl);
} }
} }
@ -260,6 +259,7 @@ bool AdBlockRule::matchDomain(const QString &domain) const {
} }
} }
} }
else if (m_allowedDomains.isEmpty()) { else if (m_allowedDomains.isEmpty()) {
foreach (const QString& d, m_blockedDomains) { foreach (const QString& d, m_blockedDomains) {
if (isMatchingDomain(domain, d)) { if (isMatchingDomain(domain, d)) {
@ -269,6 +269,7 @@ bool AdBlockRule::matchDomain(const QString &domain) const {
return true; return true;
} }
else { else {
foreach (const QString& d, m_blockedDomains) { foreach (const QString& d, m_blockedDomains) {
if (isMatchingDomain(domain, d)) { if (isMatchingDomain(domain, d)) {
@ -290,51 +291,42 @@ bool AdBlockRule::matchThirdParty(const QWebEngineUrlRequestInfo &request) const
// Third-party matching should be performed on second-level domains. // Third-party matching should be performed on second-level domains.
const QString firstPartyHost = toSecondLevelDomain(request.firstPartyUrl()); const QString firstPartyHost = toSecondLevelDomain(request.firstPartyUrl());
const QString host = toSecondLevelDomain(request.requestUrl()); const QString host = toSecondLevelDomain(request.requestUrl());
bool match = firstPartyHost != host; bool match = firstPartyHost != host;
return hasException(ThirdPartyOption) ? !match : match; return hasException(ThirdPartyOption) ? !match : match;
} }
bool AdBlockRule::matchObject(const QWebEngineUrlRequestInfo& request) const { bool AdBlockRule::matchObject(const QWebEngineUrlRequestInfo& request) const {
bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeObject; bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeObject;
return hasException(ObjectOption) ? !match : match; return hasException(ObjectOption) ? !match : match;
} }
bool AdBlockRule::matchSubdocument(const QWebEngineUrlRequestInfo& request) const { bool AdBlockRule::matchSubdocument(const QWebEngineUrlRequestInfo& request) const {
bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeSubFrame; bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeSubFrame;
return hasException(SubdocumentOption) ? !match : match; return hasException(SubdocumentOption) ? !match : match;
} }
bool AdBlockRule::matchXmlHttpRequest(const QWebEngineUrlRequestInfo& request) const { bool AdBlockRule::matchXmlHttpRequest(const QWebEngineUrlRequestInfo& request) const {
bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeXhr; bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeXhr;
return hasException(XMLHttpRequestOption) ? !match : match; return hasException(XMLHttpRequestOption) ? !match : match;
} }
bool AdBlockRule::matchImage(const QWebEngineUrlRequestInfo& request) const { bool AdBlockRule::matchImage(const QWebEngineUrlRequestInfo& request) const {
bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeImage; bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeImage;
return hasException(ImageOption) ? !match : match; return hasException(ImageOption) ? !match : match;
} }
bool AdBlockRule::matchScript(const QWebEngineUrlRequestInfo& request) const { bool AdBlockRule::matchScript(const QWebEngineUrlRequestInfo& request) const {
bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeScript; bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeScript;
return hasException(ScriptOption) ? !match : match; return hasException(ScriptOption) ? !match : match;
} }
bool AdBlockRule::matchStyleSheet(const QWebEngineUrlRequestInfo& request) const { bool AdBlockRule::matchStyleSheet(const QWebEngineUrlRequestInfo& request) const {
bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeStylesheet; bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeStylesheet;
return hasException(StyleSheetOption) ? !match : match; return hasException(StyleSheetOption) ? !match : match;
} }
bool AdBlockRule::matchObjectSubrequest(const QWebEngineUrlRequestInfo& request) const { bool AdBlockRule::matchObjectSubrequest(const QWebEngineUrlRequestInfo& request) const {
bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeSubResource; bool match = request.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeSubResource;
return hasException(ObjectSubrequestOption) ? !match : match; return hasException(ObjectSubrequestOption) ? !match : match;
} }
@ -364,7 +356,6 @@ void AdBlockRule::parseFilter() {
m_isException = parsedLine.at(pos + 1) == QL1C('@'); m_isException = parsedLine.at(pos + 1) == QL1C('@');
m_matchString = parsedLine.mid(m_isException ? pos + 3 : pos + 2); m_matchString = parsedLine.mid(m_isException ? pos + 3 : pos + 2);
// CSS rule cannot have more options -> stop parsing. // CSS rule cannot have more options -> stop parsing.
return; return;
} }
@ -387,58 +378,70 @@ void AdBlockRule::parseFilter() {
parseDomains(option.mid(7), QL1C('|')); parseDomains(option.mid(7), QL1C('|'));
++handledOptions; ++handledOptions;
} }
else if (option == QL1S("match-case")) { else if (option == QL1S("match-case")) {
m_caseSensitivity = Qt::CaseSensitive; m_caseSensitivity = Qt::CaseSensitive;
++handledOptions; ++handledOptions;
} }
else if (option.endsWith(QL1S("third-party"))) { else if (option.endsWith(QL1S("third-party"))) {
setOption(ThirdPartyOption); setOption(ThirdPartyOption);
setException(ThirdPartyOption, option.startsWith(QL1C('~'))); setException(ThirdPartyOption, option.startsWith(QL1C('~')));
++handledOptions; ++handledOptions;
} }
else if (option.endsWith(QL1S("object"))) { else if (option.endsWith(QL1S("object"))) {
setOption(ObjectOption); setOption(ObjectOption);
setException(ObjectOption, option.startsWith(QL1C('~'))); setException(ObjectOption, option.startsWith(QL1C('~')));
++handledOptions; ++handledOptions;
} }
else if (option.endsWith(QL1S("subdocument"))) { else if (option.endsWith(QL1S("subdocument"))) {
setOption(SubdocumentOption); setOption(SubdocumentOption);
setException(SubdocumentOption, option.startsWith(QL1C('~'))); setException(SubdocumentOption, option.startsWith(QL1C('~')));
++handledOptions; ++handledOptions;
} }
else if (option.endsWith(QL1S("xmlhttprequest"))) { else if (option.endsWith(QL1S("xmlhttprequest"))) {
setOption(XMLHttpRequestOption); setOption(XMLHttpRequestOption);
setException(XMLHttpRequestOption, option.startsWith(QL1C('~'))); setException(XMLHttpRequestOption, option.startsWith(QL1C('~')));
++handledOptions; ++handledOptions;
} }
else if (option.endsWith(QL1S("image"))) { else if (option.endsWith(QL1S("image"))) {
setOption(ImageOption); setOption(ImageOption);
setException(ImageOption, option.startsWith(QL1C('~'))); setException(ImageOption, option.startsWith(QL1C('~')));
++handledOptions; ++handledOptions;
} }
else if (option.endsWith(QL1S("script"))) { else if (option.endsWith(QL1S("script"))) {
setOption(ScriptOption); setOption(ScriptOption);
setException(ScriptOption, option.startsWith(QL1C('~'))); setException(ScriptOption, option.startsWith(QL1C('~')));
++handledOptions; ++handledOptions;
} }
else if (option.endsWith(QL1S("stylesheet"))) { else if (option.endsWith(QL1S("stylesheet"))) {
setOption(StyleSheetOption); setOption(StyleSheetOption);
setException(StyleSheetOption, option.startsWith(QL1C('~'))); setException(StyleSheetOption, option.startsWith(QL1C('~')));
++handledOptions; ++handledOptions;
} }
else if (option.endsWith(QL1S("object-subrequest"))) { else if (option.endsWith(QL1S("object-subrequest"))) {
setOption(ObjectSubrequestOption); setOption(ObjectSubrequestOption);
setException(ObjectSubrequestOption, option.startsWith(QL1C('~'))); setException(ObjectSubrequestOption, option.startsWith(QL1C('~')));
++handledOptions; ++handledOptions;
} }
else if (option == QL1S("document") && m_isException) { else if (option == QL1S("document") && m_isException) {
setOption(DocumentOption); setOption(DocumentOption);
++handledOptions; ++handledOptions;
} }
else if (option == QL1S("elemhide") && m_isException) { else if (option == QL1S("elemhide") && m_isException) {
setOption(ElementHideOption); setOption(ElementHideOption);
++handledOptions; ++handledOptions;
} }
else if (option == QL1S("collapse")) { else if (option == QL1S("collapse")) {
// Hiding placeholders of blocked elements is enabled by default. // Hiding placeholders of blocked elements is enabled by default.
++handledOptions; ++handledOptions;
@ -459,7 +462,6 @@ void AdBlockRule::parseFilter() {
if (parsedLine.startsWith(QL1C('/')) && parsedLine.endsWith(QL1C('/'))) { if (parsedLine.startsWith(QL1C('/')) && parsedLine.endsWith(QL1C('/'))) {
parsedLine = parsedLine.mid(1); parsedLine = parsedLine.mid(1);
parsedLine = parsedLine.left(parsedLine.size() - 1); parsedLine = parsedLine.left(parsedLine.size() - 1);
m_type = RegExpMatchRule; m_type = RegExpMatchRule;
m_regExp = new RegExp; m_regExp = new RegExp;
m_regExp->regExp = SimpleRegExp(parsedLine, m_caseSensitivity); m_regExp->regExp = SimpleRegExp(parsedLine, m_caseSensitivity);
@ -480,7 +482,6 @@ void AdBlockRule::parseFilter() {
if (filterIsOnlyDomain(parsedLine)) { if (filterIsOnlyDomain(parsedLine)) {
parsedLine = parsedLine.mid(2); parsedLine = parsedLine.mid(2);
parsedLine = parsedLine.left(parsedLine.size() - 1); parsedLine = parsedLine.left(parsedLine.size() - 1);
m_type = DomainMatchRule; m_type = DomainMatchRule;
m_matchString = parsedLine; m_matchString = parsedLine;
return; return;
@ -489,7 +490,6 @@ void AdBlockRule::parseFilter() {
// If rule contains only | at end, we can also use string matching. // If rule contains only | at end, we can also use string matching.
if (filterIsOnlyEndsMatch(parsedLine)) { if (filterIsOnlyEndsMatch(parsedLine)) {
parsedLine = parsedLine.left(parsedLine.size() - 1); parsedLine = parsedLine.left(parsedLine.size() - 1);
m_type = StringEndsMatchRule; m_type = StringEndsMatchRule;
m_matchString = parsedLine; m_matchString = parsedLine;
return; return;
@ -517,9 +517,11 @@ void AdBlockRule::parseDomains(const QString &domains, const QChar &separator) {
if (domain.isEmpty()) { if (domain.isEmpty()) {
continue; continue;
} }
if (domain.startsWith(QL1C('~'))) { if (domain.startsWith(QL1C('~'))) {
m_blockedDomains.append(domain.mid(1)); m_blockedDomains.append(domain.mid(1));
} }
else { else {
m_allowedDomains.append(domain); m_allowedDomains.append(domain);
} }
@ -578,11 +580,11 @@ static bool wordCharacter(const QChar &c) {
QString AdBlockRule::createRegExpFromFilter(const QString& filter) const { QString AdBlockRule::createRegExpFromFilter(const QString& filter) const {
QString parsed; QString parsed;
parsed.reserve(filter.size()); parsed.reserve(filter.size());
bool hadWildcard = false; // Filter multiple wildcards. bool hadWildcard = false; // Filter multiple wildcards.
for (int i = 0; i < filter.size(); ++i) { for (int i = 0; i < filter.size(); ++i) {
const QChar c = filter.at(i); const QChar c = filter.at(i);
switch (c.toLatin1()) { switch (c.toLatin1()) {
case '^': case '^':
parsed.append(QL1S("(?:[^\\w\\d\\-.%]|$)")); parsed.append(QL1S("(?:[^\\w\\d\\-.%]|$)"));
@ -592,6 +594,7 @@ QString AdBlockRule::createRegExpFromFilter(const QString &filter) const {
if (!hadWildcard) { if (!hadWildcard) {
parsed.append(QL1S(".*")); parsed.append(QL1S(".*"));
} }
break; break;
case '|': case '|':
@ -600,21 +603,26 @@ QString AdBlockRule::createRegExpFromFilter(const QString &filter) const {
parsed.append(QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?")); parsed.append(QL1S("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?"));
i++; i++;
} }
else { else {
parsed.append('^'); parsed.append('^');
} }
break; break;
} }
else if (i == filter.size() - 1) { else if (i == filter.size() - 1) {
parsed.append(QL1C('$')); parsed.append(QL1C('$'));
break; break;
} }
// fallthrough // fallthrough
default: default:
if (!wordCharacter(c)) { if (!wordCharacter(c)) {
parsed.append(QL1C('\\') + c); parsed.append(QL1C('\\') + c);
} }
else { else {
parsed.append(c); parsed.append(c);
} }
@ -641,16 +649,20 @@ bool AdBlockRule::stringMatch(const QString &domain, const QString &encodedUrl)
if (m_type == StringContainsMatchRule) { if (m_type == StringContainsMatchRule) {
return encodedUrl.contains(m_matchString, m_caseSensitivity); return encodedUrl.contains(m_matchString, m_caseSensitivity);
} }
else if (m_type == DomainMatchRule) { else if (m_type == DomainMatchRule) {
return isMatchingDomain(domain, m_matchString); return isMatchingDomain(domain, m_matchString);
} }
else if (m_type == StringEndsMatchRule) { else if (m_type == StringEndsMatchRule) {
return encodedUrl.endsWith(m_matchString, m_caseSensitivity); return encodedUrl.endsWith(m_matchString, m_caseSensitivity);
} }
else if (m_type == RegExpMatchRule) { else if (m_type == RegExpMatchRule) {
if (!isMatchingRegExpStrings(encodedUrl)) { if (!isMatchingRegExpStrings(encodedUrl)) {
return false; return false;
} }
else { else {
return (m_regExp->regExp.indexIn(encodedUrl) != -1); return (m_regExp->regExp.indexIn(encodedUrl) != -1);
} }
@ -669,7 +681,6 @@ bool AdBlockRule::matchDomain(const QString &pattern, const QString &domain) con
} }
int index = domain.indexOf(pattern); int index = domain.indexOf(pattern);
return index > 0 && domain[index - 1] == QLatin1Char('.'); return index > 0 && domain[index - 1] == QLatin1Char('.');
} }
@ -717,7 +728,6 @@ QStringList AdBlockRule::parseRegExpFilter(const QString &filter) const {
} }
list.removeDuplicates(); list.removeDuplicates();
return list; return list;
} }

View File

@ -63,7 +63,6 @@ bool AdBlockSearchTree::add(const AdBlockRule *rule) {
} }
node->rule = rule; node->rule = rule;
return true; return true;
} }
@ -93,7 +92,6 @@ const AdBlockRule *AdBlockSearchTree::prefixSearch(const QWebEngineUrlRequestInf
} }
QChar c = string[0]; QChar c = string[0];
Node* node = m_root->children.value(c); Node* node = m_root->children.value(c);
if (!node) { if (!node) {

View File

@ -101,7 +101,6 @@ void AdBlockSubscription::loadSubscription(const QStringList &disabledRules) {
QTextStream textStream(&file); QTextStream textStream(&file);
textStream.setCodec("UTF-8"); textStream.setCodec("UTF-8");
// Header is on 3rd line. // Header is on 3rd line.
textStream.readLine(1024); textStream.readLine(1024);
textStream.readLine(1024); textStream.readLine(1024);
@ -140,7 +139,6 @@ void AdBlockSubscription::updateSubscription() {
} }
SilentNetworkAccessManager* mgs = new SilentNetworkAccessManager(this); SilentNetworkAccessManager* mgs = new SilentNetworkAccessManager(this);
m_reply = mgs->get(QNetworkRequest(m_url)); m_reply = mgs->get(QNetworkRequest(m_url));
connect(m_reply, &QNetworkReply::finished, this, &AdBlockSubscription::subscriptionDownloaded); connect(m_reply, &QNetworkReply::finished, this, &AdBlockSubscription::subscriptionDownloaded);
} }
@ -167,7 +165,6 @@ void AdBlockSubscription::subscriptionDownloaded() {
} }
loadSubscription(AdBlockManager::instance()->disabledRules()); loadSubscription(AdBlockManager::instance()->disabledRules());
emit subscriptionUpdated(); emit subscriptionUpdated();
emit subscriptionChanged(); emit subscriptionChanged();
} }
@ -179,6 +176,7 @@ bool AdBlockSubscription::saveDownloadedData(const QByteArray &data) {
qWarning("Unable to open AdBlock file '%s' for writing.", qPrintable(m_filePath)); qWarning("Unable to open AdBlock file '%s' for writing.", qPrintable(m_filePath));
return false; return false;
} }
else { else {
// Write subscription header // Write subscription header
file.write(QString("Title: %1\nUrl: %2\n").arg(title(), url().toString()).toUtf8()); file.write(QString("Title: %1\nUrl: %2\n").arg(title(), url().toString()).toUtf8());
@ -192,6 +190,7 @@ const AdBlockRule *AdBlockSubscription::rule(int offset) const {
if (IS_IN_ARRAY(offset, m_rules)) { if (IS_IN_ARRAY(offset, m_rules)) {
return m_rules[offset]; return m_rules[offset];
} }
else { else {
return 0; return 0;
} }
@ -206,7 +205,6 @@ const AdBlockRule *AdBlockSubscription::enableRule(int offset) {
AdBlockRule* rule = m_rules[offset]; AdBlockRule* rule = m_rules[offset];
rule->setEnabled(true); rule->setEnabled(true);
AdBlockManager::instance()->removeDisabledRule(rule->filter()); AdBlockManager::instance()->removeDisabledRule(rule->filter());
emit subscriptionChanged(); emit subscriptionChanged();
if (rule->isCssRule()) { if (rule->isCssRule()) {
@ -216,6 +214,7 @@ const AdBlockRule *AdBlockSubscription::enableRule(int offset) {
return rule; return rule;
} }
else { else {
return 0; return 0;
} }
@ -229,7 +228,6 @@ const AdBlockRule *AdBlockSubscription::disableRule(int offset) {
AdBlockRule* rule = m_rules[offset]; AdBlockRule* rule = m_rules[offset];
rule->setEnabled(false); rule->setEnabled(false);
AdBlockManager::instance()->addDisabledRule(rule->filter()); AdBlockManager::instance()->addDisabledRule(rule->filter());
emit subscriptionChanged(); emit subscriptionChanged();
if (rule->isCssRule()) { if (rule->isCssRule()) {
@ -279,7 +277,6 @@ void AdBlockCustomList::loadSubscription(const QStringList &disabledRules) {
// DuckDuckGo ad whitelist rules // DuckDuckGo ad whitelist rules
// They cannot be removed, but can be disabled. // They cannot be removed, but can be disabled.
// Please consider not disabling them. Thanks! // Please consider not disabling them. Thanks!
const QString ddg1 = QSL("@@||duckduckgo.com^$document"); const QString ddg1 = QSL("@@||duckduckgo.com^$document");
const QString ddg2 = QSL("duckduckgo.com#@#.has-ad"); const QString ddg2 = QSL("duckduckgo.com#@#.has-ad");
QString rules; QString rules;
@ -287,8 +284,8 @@ void AdBlockCustomList::loadSubscription(const QStringList &disabledRules) {
try { try {
rules = QString::fromUtf8(IOFactory::readTextFile(filePath())); rules = QString::fromUtf8(IOFactory::readTextFile(filePath()));
} }
catch (ApplicationException&) {
catch (ApplicationException&) {
} }
QFile file(filePath()); QFile file(filePath());
@ -301,15 +298,16 @@ void AdBlockCustomList::loadSubscription(const QStringList &disabledRules) {
QTextStream stream(&file); QTextStream stream(&file);
stream.setCodec("UTF-8"); stream.setCodec("UTF-8");
if (!rules.contains(ddg1 + QL1S("\n"))) if (!rules.contains(ddg1 + QL1S("\n"))) {
stream << ddg1 << endl; stream << ddg1 << endl;
}
if (!rules.contains(QL1S("\n") + ddg2)) if (!rules.contains(QL1S("\n") + ddg2)) {
stream << ddg2 << endl; stream << ddg2 << endl;
} }
}
file.close(); file.close();
AdBlockSubscription::loadSubscription(disabledRules); AdBlockSubscription::loadSubscription(disabledRules);
} }
@ -322,7 +320,6 @@ void AdBlockCustomList::saveSubscription() {
} }
QTextStream textStream(&file); QTextStream textStream(&file);
textStream.setCodec("UTF-8"); textStream.setCodec("UTF-8");
textStream << "Title: " << title() << endl; textStream << "Title: " << title() << endl;
textStream << "Url: " << url().toString() << endl; textStream << "Url: " << url().toString() << endl;
@ -367,7 +364,6 @@ bool AdBlockCustomList::removeFilter(const QString &filter) {
int AdBlockCustomList::addRule(AdBlockRule* rule) { int AdBlockCustomList::addRule(AdBlockRule* rule) {
m_rules.append(rule); m_rules.append(rule);
emit subscriptionChanged(); emit subscriptionChanged();
if (rule->isCssRule()) { if (rule->isCssRule()) {
@ -385,9 +381,7 @@ bool AdBlockCustomList::removeRule(int offset) {
AdBlockRule* rule = m_rules.at(offset); AdBlockRule* rule = m_rules.at(offset);
const QString filter = rule->filter(); const QString filter = rule->filter();
m_rules.remove(offset); m_rules.remove(offset);
emit subscriptionChanged(); emit subscriptionChanged();
if (rule->isCssRule()) { if (rule->isCssRule()) {
@ -396,7 +390,6 @@ bool AdBlockCustomList::removeRule(int offset) {
} }
AdBlockManager::instance()->removeDisabledRule(filter); AdBlockManager::instance()->removeDisabledRule(filter);
delete rule; delete rule;
return true; return true;
} }
@ -408,7 +401,6 @@ const AdBlockRule *AdBlockCustomList::replaceRule(AdBlockRule *rule, int offset)
AdBlockRule* oldRule = m_rules.at(offset); AdBlockRule* oldRule = m_rules.at(offset);
m_rules[offset] = rule; m_rules[offset] = rule;
emit subscriptionChanged(); emit subscriptionChanged();
if (rule->isCssRule() || oldRule->isCssRule()) { if (rule->isCssRule() || oldRule->isCssRule()) {

View File

@ -34,7 +34,6 @@ AdBlockTreeWidget::AdBlockTreeWidget(AdBlockSubscription *subscription, QWidget
setHeaderHidden(true); setHeaderHidden(true);
setAlternatingRowColors(true); setAlternatingRowColors(true);
setLayoutDirection(Qt::LeftToRight); setLayoutDirection(Qt::LeftToRight);
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint))); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint)));
connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(itemChanged(QTreeWidgetItem*))); connect(this, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(itemChanged(QTreeWidgetItem*)));
connect(m_subscription, SIGNAL(subscriptionUpdated()), this, SLOT(subscriptionUpdated())); connect(m_subscription, SIGNAL(subscriptionUpdated()), this, SLOT(subscriptionUpdated()));
@ -49,12 +48,12 @@ void AdBlockTreeWidget::showRule(const AdBlockRule *rule) {
if (!m_topItem && rule) { if (!m_topItem && rule) {
m_ruleToBeSelected = rule->filter(); m_ruleToBeSelected = rule->filter();
} }
else if (!m_ruleToBeSelected.isEmpty()) { else if (!m_ruleToBeSelected.isEmpty()) {
QList<QTreeWidgetItem*> items = findItems(m_ruleToBeSelected, Qt::MatchRecursive); QList<QTreeWidgetItem*> items = findItems(m_ruleToBeSelected, Qt::MatchRecursive);
if (!items.isEmpty()) { if (!items.isEmpty()) {
QTreeWidgetItem* item = items.at(0); QTreeWidgetItem* item = items.at(0);
setCurrentItem(item); setCurrentItem(item);
scrollToItem(item, QAbstractItemView::PositionAtCenter); scrollToItem(item, QAbstractItemView::PositionAtCenter);
} }
@ -92,27 +91,25 @@ void AdBlockTreeWidget::itemChanged(QTreeWidgetItem *item) {
} }
m_itemChangingBlock = true; m_itemChangingBlock = true;
int offset = item->data(0, Qt::UserRole + 10).toInt(); int offset = item->data(0, Qt::UserRole + 10).toInt();
const AdBlockRule* oldRule = m_subscription->rule(offset); const AdBlockRule* oldRule = m_subscription->rule(offset);
if (item->checkState(0) == Qt::Unchecked && oldRule->isEnabled()) { if (item->checkState(0) == Qt::Unchecked && oldRule->isEnabled()) {
// Disable rule. // Disable rule.
const AdBlockRule* rule = m_subscription->disableRule(offset); const AdBlockRule* rule = m_subscription->disableRule(offset);
adjustItemFeatures(item, rule); adjustItemFeatures(item, rule);
} }
else if (item->checkState(0) == Qt::Checked && !oldRule->isEnabled()) { else if (item->checkState(0) == Qt::Checked && !oldRule->isEnabled()) {
// Enable rule. // Enable rule.
const AdBlockRule* rule = m_subscription->enableRule(offset); const AdBlockRule* rule = m_subscription->enableRule(offset);
adjustItemFeatures(item, rule); adjustItemFeatures(item, rule);
} }
else if (m_subscription->canEditRules()) { else if (m_subscription->canEditRules()) {
// Custom rule has been changed. // Custom rule has been changed.
AdBlockRule* newRule = new AdBlockRule(item->text(0), m_subscription); AdBlockRule* newRule = new AdBlockRule(item->text(0), m_subscription);
const AdBlockRule* rule = m_subscription->replaceRule(newRule, offset); const AdBlockRule* rule = m_subscription->replaceRule(newRule, offset);
adjustItemFeatures(item, rule); adjustItemFeatures(item, rule);
} }
@ -142,16 +139,13 @@ void AdBlockTreeWidget::addRule() {
AdBlockRule* rule = new AdBlockRule(newRule, m_subscription); AdBlockRule* rule = new AdBlockRule(newRule, m_subscription);
int offset = m_subscription->addRule(rule); int offset = m_subscription->addRule(rule);
QTreeWidgetItem* item = new QTreeWidgetItem(); QTreeWidgetItem* item = new QTreeWidgetItem();
item->setText(0, newRule); item->setText(0, newRule);
item->setData(0, Qt::UserRole + 10, offset); item->setData(0, Qt::UserRole + 10, offset);
item->setFlags(item->flags() | Qt::ItemIsEditable); item->setFlags(item->flags() | Qt::ItemIsEditable);
m_itemChangingBlock = true; m_itemChangingBlock = true;
m_topItem->addChild(item); m_topItem->addChild(item);
m_itemChangingBlock = false; m_itemChangingBlock = false;
adjustItemFeatures(item, rule); adjustItemFeatures(item, rule);
} }
@ -163,14 +157,12 @@ void AdBlockTreeWidget::removeRule() {
} }
int offset = item->data(0, Qt::UserRole + 10).toInt(); int offset = item->data(0, Qt::UserRole + 10).toInt();
m_subscription->removeRule(offset); m_subscription->removeRule(offset);
deleteItem(item); deleteItem(item);
} }
void AdBlockTreeWidget::subscriptionUpdated() { void AdBlockTreeWidget::subscriptionUpdated() {
refresh(); refresh();
m_itemChangingBlock = true; m_itemChangingBlock = true;
m_topItem->setText(0, tr("%1 (recently updated)").arg(m_subscription->title())); m_topItem->setText(0, tr("%1 (recently updated)").arg(m_subscription->title()));
m_itemChangingBlock = false; m_itemChangingBlock = false;
@ -178,7 +170,6 @@ void AdBlockTreeWidget::subscriptionUpdated() {
void AdBlockTreeWidget::subscriptionError(const QString& message) { void AdBlockTreeWidget::subscriptionError(const QString& message) {
refresh(); refresh();
m_itemChangingBlock = true; m_itemChangingBlock = true;
m_topItem->setText(0, tr("%1 (Error: %2)").arg(m_subscription->title(), message)); m_topItem->setText(0, tr("%1 (Error: %2)").arg(m_subscription->title(), message));
m_itemChangingBlock = false; m_itemChangingBlock = false;
@ -206,6 +197,7 @@ void AdBlockTreeWidget::adjustItemFeatures(QTreeWidgetItem* item, const AdBlockR
item->setForeground(0, QColor(Qt::darkGreen)); item->setForeground(0, QColor(Qt::darkGreen));
item->setFont(0, QFont()); item->setFont(0, QFont());
} }
else if (rule->isCssRule()) { else if (rule->isCssRule()) {
item->setForeground(0, QColor(Qt::darkBlue)); item->setForeground(0, QColor(Qt::darkBlue));
item->setFont(0, QFont()); item->setFont(0, QFont());
@ -227,19 +219,16 @@ void AdBlockTreeWidget::keyPressEvent(QKeyEvent* event) {
void AdBlockTreeWidget::refresh() { void AdBlockTreeWidget::refresh() {
m_itemChangingBlock = true; m_itemChangingBlock = true;
clear(); clear();
QFont boldFont; QFont boldFont;
boldFont.setBold(true); boldFont.setBold(true);
m_topItem = new QTreeWidgetItem(this); m_topItem = new QTreeWidgetItem(this);
m_topItem->setText(0, m_subscription->title()); m_topItem->setText(0, m_subscription->title());
m_topItem->setFont(0, boldFont); m_topItem->setFont(0, boldFont);
m_topItem->setExpanded(true); m_topItem->setExpanded(true);
addTopLevelItem(m_topItem); addTopLevelItem(m_topItem);
const QVector<AdBlockRule*>& allRules = m_subscription->allRules(); const QVector<AdBlockRule*>& allRules = m_subscription->allRules();
int index = 0; int index = 0;
foreach (const AdBlockRule* rule, allRules) { foreach (const AdBlockRule* rule, allRules) {
QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem); QTreeWidgetItem* item = new QTreeWidgetItem(m_topItem);
item->setText(0, rule->filter()); item->setText(0, rule->filter());

View File

@ -43,12 +43,13 @@ void BaseNetworkAccessManager::loadSettings() {
// No extra setting is needed, set new proxy and exit this method. // No extra setting is needed, set new proxy and exit this method.
setProxy(QNetworkProxy::NoProxy); setProxy(QNetworkProxy::NoProxy);
} }
else if (selected_proxy_type == QNetworkProxy::DefaultProxy) { else if (selected_proxy_type == QNetworkProxy::DefaultProxy) {
setProxy(QNetworkProxy::applicationProxy()); setProxy(QNetworkProxy::applicationProxy());
} }
else { else {
const Settings* settings = qApp->settings(); const Settings* settings = qApp->settings();
// Custom proxy is selected, set it up. // Custom proxy is selected, set it up.
new_proxy.setType(selected_proxy_type); new_proxy.setType(selected_proxy_type);
new_proxy.setHostName(settings->value(GROUP(Proxy), SETTING(Proxy::Host)).toString()); new_proxy.setHostName(settings->value(GROUP(Proxy), SETTING(Proxy::Host)).toString());
@ -70,13 +71,10 @@ QNetworkReply *BaseNetworkAccessManager::createRequest(QNetworkAccessManager::Op
const QNetworkRequest& request, const QNetworkRequest& request,
QIODevice* outgoingData) { QIODevice* outgoingData) {
QNetworkRequest new_request = request; QNetworkRequest new_request = request;
// This rapidly speeds up loading of web sites. // This rapidly speeds up loading of web sites.
// NOTE: https://en.wikipedia.org/wiki/HTTP_pipelining // NOTE: https://en.wikipedia.org/wiki/HTTP_pipelining
new_request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); new_request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
// Setup custom user-agent. // Setup custom user-agent.
new_request.setRawHeader(USER_AGENT_HTTP_HEADER, QString(APP_USERAGENT).toLocal8Bit()); new_request.setRawHeader(USER_AGENT_HTTP_HEADER, QString(APP_USERAGENT).toLocal8Bit());
return QNetworkAccessManager::createRequest(op, new_request, outgoingData); return QNetworkAccessManager::createRequest(op, new_request, outgoingData);
} }

View File

@ -27,10 +27,8 @@ Downloader::Downloader(QObject *parent)
m_timer(new QTimer(this)), m_customHeaders(QHash<QByteArray, QByteArray>()), m_inputData(QByteArray()), m_timer(new QTimer(this)), m_customHeaders(QHash<QByteArray, QByteArray>()), m_inputData(QByteArray()),
m_targetProtected(false), m_targetUsername(QString()), m_targetPassword(QString()), m_targetProtected(false), m_targetUsername(QString()), m_targetPassword(QString()),
m_lastOutputData(QByteArray()), m_lastOutputError(QNetworkReply::NoError), m_lastContentType(QVariant()) { m_lastOutputData(QByteArray()), m_lastOutputError(QNetworkReply::NoError), m_lastContentType(QVariant()) {
m_timer->setInterval(DOWNLOAD_TIMEOUT); m_timer->setInterval(DOWNLOAD_TIMEOUT);
m_timer->setSingleShot(true); m_timer->setSingleShot(true);
connect(m_timer, &QTimer::timeout, this, &Downloader::cancel); connect(m_timer, &QTimer::timeout, this, &Downloader::cancel);
} }
@ -52,7 +50,6 @@ void Downloader::manipulateData(const QString &url, QNetworkAccessManager::Opera
int timeout, bool protected_contents, const QString& username, const QString& password) { int timeout, bool protected_contents, const QString& username, const QString& password) {
QNetworkRequest request; QNetworkRequest request;
QString non_const_url = url; QString non_const_url = url;
QHashIterator<QByteArray, QByteArray> i(m_customHeaders); QHashIterator<QByteArray, QByteArray> i(m_customHeaders);
while (i.hasNext()) { while (i.hasNext()) {
@ -61,7 +58,6 @@ void Downloader::manipulateData(const QString &url, QNetworkAccessManager::Opera
} }
m_inputData = data; m_inputData = data;
// Set url for this request and fire it up. // Set url for this request and fire it up.
m_timer->setInterval(timeout); m_timer->setInterval(timeout);
@ -69,6 +65,7 @@ void Downloader::manipulateData(const QString &url, QNetworkAccessManager::Opera
qDebug("Replacing URI schemes for '%s'.", qPrintable(non_const_url)); qDebug("Replacing URI schemes for '%s'.", qPrintable(non_const_url));
request.setUrl(non_const_url.replace(QRegExp(QString('^') + URI_SCHEME_FEED), QString(URI_SCHEME_HTTP))); request.setUrl(non_const_url.replace(QRegExp(QString('^') + URI_SCHEME_FEED), QString(URI_SCHEME_HTTP)));
} }
else { else {
request.setUrl(non_const_url); request.setUrl(non_const_url);
} }
@ -80,12 +77,15 @@ void Downloader::manipulateData(const QString &url, QNetworkAccessManager::Opera
if (operation == QNetworkAccessManager::PostOperation) { if (operation == QNetworkAccessManager::PostOperation) {
runPostRequest(request, m_inputData); runPostRequest(request, m_inputData);
} }
else if (operation == QNetworkAccessManager::GetOperation) { else if (operation == QNetworkAccessManager::GetOperation) {
runGetRequest(request); runGetRequest(request);
} }
else if (operation == QNetworkAccessManager::PutOperation) { else if (operation == QNetworkAccessManager::PutOperation) {
runPutRequest(request, m_inputData); runPutRequest(request, m_inputData);
} }
else if (operation == QNetworkAccessManager::DeleteOperation) { else if (operation == QNetworkAccessManager::DeleteOperation) {
runDeleteRequest(request); runDeleteRequest(request);
} }
@ -94,9 +94,7 @@ void Downloader::manipulateData(const QString &url, QNetworkAccessManager::Opera
void Downloader::finished() { void Downloader::finished() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender()); QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
QNetworkAccessManager::Operation reply_operation = reply->operation(); QNetworkAccessManager::Operation reply_operation = reply->operation();
m_timer->stop(); m_timer->stop();
// In this phase, some part of downloading process is completed. // In this phase, some part of downloading process is completed.
const QUrl redirection_url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); const QUrl redirection_url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
@ -108,6 +106,7 @@ void Downloader::finished() {
if (redirection_url.host().isEmpty()) { if (redirection_url.host().isEmpty()) {
request.setUrl(QUrl(reply->request().url().scheme() + QSL("://") + reply->request().url().host() + redirection_url.toString())); request.setUrl(QUrl(reply->request().url().scheme() + QSL("://") + reply->request().url().host() + redirection_url.toString()));
} }
else { else {
request.setUrl(redirection_url); request.setUrl(redirection_url);
} }
@ -118,26 +117,28 @@ void Downloader::finished() {
if (reply_operation == QNetworkAccessManager::GetOperation) { if (reply_operation == QNetworkAccessManager::GetOperation) {
runGetRequest(request); runGetRequest(request);
} }
else if (reply_operation == QNetworkAccessManager::PostOperation) { else if (reply_operation == QNetworkAccessManager::PostOperation) {
runPostRequest(request, m_inputData); runPostRequest(request, m_inputData);
} }
else if (reply_operation == QNetworkAccessManager::PutOperation) { else if (reply_operation == QNetworkAccessManager::PutOperation) {
runPutRequest(request, m_inputData); runPutRequest(request, m_inputData);
} }
else if (reply_operation == QNetworkAccessManager::DeleteOperation) { else if (reply_operation == QNetworkAccessManager::DeleteOperation) {
runDeleteRequest(request); runDeleteRequest(request);
} }
} }
else { else {
// No redirection is indicated. Final file is obtained in our "reply" object. // No redirection is indicated. Final file is obtained in our "reply" object.
// Read the data into output buffer. // Read the data into output buffer.
m_lastOutputData = reply->readAll(); m_lastOutputData = reply->readAll();
m_lastContentType = reply->header(QNetworkRequest::ContentTypeHeader); m_lastContentType = reply->header(QNetworkRequest::ContentTypeHeader);
m_lastOutputError = reply->error(); m_lastOutputError = reply->error();
m_activeReply->deleteLater(); m_activeReply->deleteLater();
m_activeReply = nullptr; m_activeReply = nullptr;
emit completed(m_lastOutputError, m_lastOutputData); emit completed(m_lastOutputError, m_lastOutputData);
} }
} }
@ -153,11 +154,9 @@ void Downloader::progressInternal(qint64 bytes_received, qint64 bytes_total) {
void Downloader::runDeleteRequest(const QNetworkRequest& request) { void Downloader::runDeleteRequest(const QNetworkRequest& request) {
m_timer->start(); m_timer->start();
m_activeReply = m_downloadManager->deleteResource(request); m_activeReply = m_downloadManager->deleteResource(request);
m_activeReply->setProperty("protected", m_targetProtected); m_activeReply->setProperty("protected", m_targetProtected);
m_activeReply->setProperty("username", m_targetUsername); m_activeReply->setProperty("username", m_targetUsername);
m_activeReply->setProperty("password", m_targetPassword); m_activeReply->setProperty("password", m_targetPassword);
connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal); connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal);
connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished); connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished);
} }
@ -165,11 +164,9 @@ void Downloader::runDeleteRequest(const QNetworkRequest &request) {
void Downloader::runPutRequest(const QNetworkRequest& request, const QByteArray& data) { void Downloader::runPutRequest(const QNetworkRequest& request, const QByteArray& data) {
m_timer->start(); m_timer->start();
m_activeReply = m_downloadManager->put(request, data); m_activeReply = m_downloadManager->put(request, data);
m_activeReply->setProperty("protected", m_targetProtected); m_activeReply->setProperty("protected", m_targetProtected);
m_activeReply->setProperty("username", m_targetUsername); m_activeReply->setProperty("username", m_targetUsername);
m_activeReply->setProperty("password", m_targetPassword); m_activeReply->setProperty("password", m_targetPassword);
connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal); connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal);
connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished); connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished);
} }
@ -177,11 +174,9 @@ void Downloader::runPutRequest(const QNetworkRequest &request, const QByteArray
void Downloader::runPostRequest(const QNetworkRequest& request, const QByteArray& data) { void Downloader::runPostRequest(const QNetworkRequest& request, const QByteArray& data) {
m_timer->start(); m_timer->start();
m_activeReply = m_downloadManager->post(request, data); m_activeReply = m_downloadManager->post(request, data);
m_activeReply->setProperty("protected", m_targetProtected); m_activeReply->setProperty("protected", m_targetProtected);
m_activeReply->setProperty("username", m_targetUsername); m_activeReply->setProperty("username", m_targetUsername);
m_activeReply->setProperty("password", m_targetPassword); m_activeReply->setProperty("password", m_targetPassword);
connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal); connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal);
connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished); connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished);
} }
@ -189,11 +184,9 @@ void Downloader::runPostRequest(const QNetworkRequest &request, const QByteArray
void Downloader::runGetRequest(const QNetworkRequest& request) { void Downloader::runGetRequest(const QNetworkRequest& request) {
m_timer->start(); m_timer->start();
m_activeReply = m_downloadManager->get(request); m_activeReply = m_downloadManager->get(request);
m_activeReply->setProperty("protected", m_targetProtected); m_activeReply->setProperty("protected", m_targetProtected);
m_activeReply->setProperty("username", m_targetUsername); m_activeReply->setProperty("username", m_targetUsername);
m_activeReply->setProperty("password", m_targetPassword); m_activeReply->setProperty("password", m_targetPassword);
connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal); connect(m_activeReply, &QNetworkReply::downloadProgress, this, &Downloader::progressInternal);
connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished); connect(m_activeReply, &QNetworkReply::finished, this, &Downloader::finished);
} }

View File

@ -46,9 +46,7 @@ DownloadItem::DownloadItem(QNetworkReply *reply, QWidget *parent) : QWidget(pare
m_gettingFileName(false), m_canceledFileSelect(false) { m_gettingFileName(false), m_canceledFileSelect(false) {
m_ui->setupUi(this); m_ui->setupUi(this);
m_ui->m_btnTryAgain->hide(); m_ui->m_btnTryAgain->hide();
m_requestFileName = qApp->settings()->value(GROUP(Downloads), SETTING(Downloads::AlwaysPromptForFilename)).toBool(); m_requestFileName = qApp->settings()->value(GROUP(Downloads), SETTING(Downloads::AlwaysPromptForFilename)).toBool();
connect(m_ui->m_btnStopDownload, &QToolButton::clicked, this, &DownloadItem::stop); connect(m_ui->m_btnStopDownload, &QToolButton::clicked, this, &DownloadItem::stop);
connect(m_ui->m_btnOpenFile, &QToolButton::clicked, this, &DownloadItem::openFile); connect(m_ui->m_btnOpenFile, &QToolButton::clicked, this, &DownloadItem::openFile);
connect(m_ui->m_btnTryAgain, &QToolButton::clicked, this, &DownloadItem::tryAgain); connect(m_ui->m_btnTryAgain, &QToolButton::clicked, this, &DownloadItem::tryAgain);
@ -71,18 +69,15 @@ void DownloadItem::init() {
m_ui->m_btnOpenFolder->setEnabled(false); m_ui->m_btnOpenFolder->setEnabled(false);
m_url = m_reply->url(); m_url = m_reply->url();
m_reply->setParent(this); m_reply->setParent(this);
connect(m_reply, &QNetworkReply::readyRead, this, &DownloadItem::downloadReadyRead); connect(m_reply, &QNetworkReply::readyRead, this, &DownloadItem::downloadReadyRead);
connect(m_reply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), this, &DownloadItem::error); connect(m_reply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), this, &DownloadItem::error);
connect(m_reply, &QNetworkReply::downloadProgress, this, &DownloadItem::downloadProgress); connect(m_reply, &QNetworkReply::downloadProgress, this, &DownloadItem::downloadProgress);
connect(m_reply, &QNetworkReply::metaDataChanged, this, &DownloadItem::metaDataChanged); connect(m_reply, &QNetworkReply::metaDataChanged, this, &DownloadItem::metaDataChanged);
connect(m_reply, &QNetworkReply::finished, this, &DownloadItem::finished); connect(m_reply, &QNetworkReply::finished, this, &DownloadItem::finished);
// Reset info. // Reset info.
m_ui->m_lblInfoDownload->clear(); m_ui->m_lblInfoDownload->clear();
m_ui->m_progressDownload->setValue(0); m_ui->m_progressDownload->setValue(0);
getFileName(); getFileName();
// Start timer for the download estimation. // Start timer for the download estimation.
m_downloadTime.start(); m_downloadTime.start();
@ -111,7 +106,6 @@ void DownloadItem::getFileName() {
if (chosen_filename.isEmpty()) { if (chosen_filename.isEmpty()) {
stop(); stop();
m_ui->m_progressDownload->setVisible(false); m_ui->m_progressDownload->setVisible(false);
m_ui->m_lblLocalFilename->setText(tr("Selection of local file cancelled.")); m_ui->m_lblLocalFilename->setText(tr("Selection of local file cancelled."));
m_canceledFileSelect = true; m_canceledFileSelect = true;
@ -119,20 +113,17 @@ void DownloadItem::getFileName() {
} }
const QFileInfo file_info = QFileInfo(chosen_filename); const QFileInfo file_info = QFileInfo(chosen_filename);
qApp->settings()->setValue(GROUP(Downloads), Downloads::TargetExplicitDirectory, qApp->settings()->setValue(GROUP(Downloads), Downloads::TargetExplicitDirectory,
QDir::toNativeSeparators(QFileInfo(chosen_filename).absolutePath())); QDir::toNativeSeparators(QFileInfo(chosen_filename).absolutePath()));
qApp->downloadManager()->setDownloadDirectory(file_info.absoluteDir().absolutePath()); qApp->downloadManager()->setDownloadDirectory(file_info.absoluteDir().absolutePath());
} }
m_output.setFileName(chosen_filename); m_output.setFileName(chosen_filename);
// Check file path for saving. // Check file path for saving.
const QDir save_dir = QFileInfo(m_output.fileName()).dir(); const QDir save_dir = QFileInfo(m_output.fileName()).dir();
if (!save_dir.exists() && !save_dir.mkpath(save_dir.absolutePath())) { if (!save_dir.exists() && !save_dir.mkpath(save_dir.absolutePath())) {
stop(); stop();
m_ui->m_progressDownload->setVisible(false); m_ui->m_progressDownload->setVisible(false);
m_ui->m_lblInfoDownload->setText(tr("Download directory couldn't be created")); m_ui->m_lblInfoDownload->setText(tr("Download directory couldn't be created"));
return; return;
@ -186,7 +177,8 @@ QString DownloadItem::saveFileName(const QString &directory) const {
do { do {
name = directory + base_name + QL1C('-') + QString::number(i++) + end_name; name = directory + base_name + QL1C('-') + QString::number(i++) + end_name;
} while (QFile::exists(name)); }
while (QFile::exists(name));
} }
return name; return name;
@ -199,7 +191,6 @@ void DownloadItem::stop() {
m_ui->m_btnTryAgain->setEnabled(true); m_ui->m_btnTryAgain->setEnabled(true);
m_ui->m_btnTryAgain->show(); m_ui->m_btnTryAgain->show();
setUpdatesEnabled(true); setUpdatesEnabled(true);
m_reply->abort(); m_reply->abort();
emit downloadFinished(); emit downloadFinished();
} }
@ -234,7 +225,6 @@ void DownloadItem::tryAgain() {
m_ui->m_btnStopDownload->setEnabled(true); m_ui->m_btnStopDownload->setEnabled(true);
m_ui->m_btnStopDownload->setVisible(true); m_ui->m_btnStopDownload->setVisible(true);
m_ui->m_progressDownload->setVisible(true); m_ui->m_progressDownload->setVisible(true);
QNetworkReply* new_download = qApp->downloadManager()->networkManager()->get(QNetworkRequest(m_url)); QNetworkReply* new_download = qApp->downloadManager()->networkManager()->get(QNetworkRequest(m_url));
if (m_reply) { if (m_reply) {
@ -246,7 +236,6 @@ void DownloadItem::tryAgain() {
} }
m_reply = new_download; m_reply = new_download;
init(); init();
emit statusChanged(); emit statusChanged();
} }
@ -264,7 +253,6 @@ void DownloadItem::downloadReadyRead() {
if (!m_output.open(QIODevice::WriteOnly)) { if (!m_output.open(QIODevice::WriteOnly)) {
m_ui->m_lblInfoDownload->setText(tr("Error opening output file: %1").arg(m_output.errorString())); m_ui->m_lblInfoDownload->setText(tr("Error opening output file: %1").arg(m_output.errorString()));
stop(); stop();
emit statusChanged(); emit statusChanged();
return; return;
} }
@ -276,6 +264,7 @@ void DownloadItem::downloadReadyRead() {
m_ui->m_lblInfoDownload->setText(tr("Error when saving file: %1").arg(m_output.errorString())); m_ui->m_lblInfoDownload->setText(tr("Error when saving file: %1").arg(m_output.errorString()));
m_ui->m_btnStopDownload->click(); m_ui->m_btnStopDownload->click();
} }
else { else {
m_startedSaving = true; m_startedSaving = true;
@ -287,11 +276,9 @@ void DownloadItem::downloadReadyRead() {
void DownloadItem::error(QNetworkReply::NetworkError code) { void DownloadItem::error(QNetworkReply::NetworkError code) {
Q_UNUSED(code) Q_UNUSED(code)
m_ui->m_lblInfoDownload->setText(tr("Error: %1").arg(m_reply->errorString())); m_ui->m_lblInfoDownload->setText(tr("Error: %1").arg(m_reply->errorString()));
m_ui->m_btnTryAgain->setEnabled(true); m_ui->m_btnTryAgain->setEnabled(true);
m_ui->m_btnTryAgain->setVisible(true); m_ui->m_btnTryAgain->setVisible(true);
emit downloadFinished(); emit downloadFinished();
} }
@ -302,7 +289,6 @@ void DownloadItem::metaDataChanged() {
m_url = locationHeader.toUrl(); m_url = locationHeader.toUrl();
m_reply->deleteLater(); m_reply->deleteLater();
m_reply = qApp->downloadManager()->networkManager()->get(QNetworkRequest(m_url)); m_reply = qApp->downloadManager()->networkManager()->get(QNetworkRequest(m_url));
init(); init();
return; return;
} }
@ -317,7 +303,6 @@ void DownloadItem::downloadProgress(qint64 bytes_received, qint64 bytes_total) {
m_lastProgressTime = now; m_lastProgressTime = now;
m_bytesReceived = bytes_received; m_bytesReceived = bytes_received;
qint64 currentValue = 0; qint64 currentValue = 0;
qint64 totalValue = 0; qint64 totalValue = 0;
@ -328,7 +313,6 @@ void DownloadItem::downloadProgress(qint64 bytes_received, qint64 bytes_total) {
m_ui->m_progressDownload->setValue(currentValue); m_ui->m_progressDownload->setValue(currentValue);
m_ui->m_progressDownload->setMaximum(totalValue); m_ui->m_progressDownload->setMaximum(totalValue);
emit progress(currentValue, totalValue); emit progress(currentValue, totalValue);
updateDownloadInfoLabel(); updateDownloadInfoLabel();
} }
@ -360,6 +344,7 @@ double DownloadItem::currentSpeed() const {
if (!downloading()) { if (!downloading()) {
return -1.0; return -1.0;
} }
else { else {
return m_bytesReceived * 1000.0 / m_downloadTime.elapsed(); return m_bytesReceived * 1000.0 / m_downloadTime.elapsed();
} }
@ -374,7 +359,6 @@ void DownloadItem::updateDownloadInfoLabel() {
bool running = !downloadedSuccessfully(); bool running = !downloadedSuccessfully();
double speed = currentSpeed(); double speed = currentSpeed();
double time_remaining = remainingTime(); double time_remaining = remainingTime();
QString info; QString info;
if (running) { if (running) {
@ -389,10 +373,12 @@ void DownloadItem::updateDownloadInfoLabel() {
DownloadManager::dataString((int)speed), DownloadManager::dataString((int)speed),
remaining); remaining);
} }
else { else {
if (m_bytesReceived == bytes_total) { if (m_bytesReceived == bytes_total) {
info = DownloadManager::dataString(m_output.size()); info = DownloadManager::dataString(m_output.size());
} }
else { else {
info = tr("%1 of %2 - download completed").arg(DownloadManager::dataString(m_bytesReceived), info = tr("%1 of %2 - download completed").arg(DownloadManager::dataString(m_bytesReceived),
DownloadManager::dataString(m_bytesReceived)); DownloadManager::dataString(m_bytesReceived));
@ -424,7 +410,6 @@ void DownloadItem::finished() {
m_ui->m_btnOpenFolder->setEnabled(true); m_ui->m_btnOpenFolder->setEnabled(true);
m_output.close(); m_output.close();
updateDownloadInfoLabel(); updateDownloadInfoLabel();
emit statusChanged(); emit statusChanged();
emit downloadFinished(); emit downloadFinished();
@ -450,7 +435,6 @@ DownloadManager::DownloadManager(QWidget *parent) : TabContent(parent), m_ui(new
m_ui->m_viewDownloads->setAlternatingRowColors(true); m_ui->m_viewDownloads->setAlternatingRowColors(true);
m_ui->m_viewDownloads->horizontalHeader()->setStretchLastSection(true); m_ui->m_viewDownloads->horizontalHeader()->setStretchLastSection(true);
m_ui->m_viewDownloads->setModel(m_model); m_ui->m_viewDownloads->setModel(m_model);
setDownloadDirectory(qApp->settings()->value(GROUP(Downloads), SETTING(Downloads::TargetDirectory)).toString()); setDownloadDirectory(qApp->settings()->value(GROUP(Downloads), SETTING(Downloads::TargetDirectory)).toString());
connect(m_ui->m_btnCleanup, &QPushButton::clicked, this, &DownloadManager::cleanup); connect(m_ui->m_btnCleanup, &QPushButton::clicked, this, &DownloadManager::cleanup);
load(); load();
@ -459,7 +443,6 @@ DownloadManager::DownloadManager(QWidget *parent) : TabContent(parent), m_ui(new
DownloadManager::~DownloadManager() { DownloadManager::~DownloadManager() {
m_autoSaver->changeOccurred(); m_autoSaver->changeOccurred();
m_autoSaver->saveIfNeccessary(); m_autoSaver->saveIfNeccessary();
qDebug("Destroying DownloadManager instance."); qDebug("Destroying DownloadManager instance.");
} }
@ -489,6 +472,7 @@ int DownloadManager::downloadProgress() const {
if (bytes_total <= 0) { if (bytes_total <= 0) {
return -1; return -1;
} }
else { else {
return (bytes_received * 100.0) / bytes_total; return (bytes_received * 100.0) / bytes_total;
} }
@ -530,17 +514,14 @@ void DownloadManager::addItem(DownloadItem *item) {
connect(item, &DownloadItem::statusChanged, this, static_cast<void (DownloadManager::*)()>(&DownloadManager::updateRow)); connect(item, &DownloadItem::statusChanged, this, static_cast<void (DownloadManager::*)()>(&DownloadManager::updateRow));
connect(item, &DownloadItem::progress, this, &DownloadManager::itemProgress); connect(item, &DownloadItem::progress, this, &DownloadManager::itemProgress);
connect(item, &DownloadItem::downloadFinished, this, &DownloadManager::itemFinished); connect(item, &DownloadItem::downloadFinished, this, &DownloadManager::itemFinished);
const int row = m_downloads.count(); const int row = m_downloads.count();
m_model->beginInsertRows(QModelIndex(), row, row); m_model->beginInsertRows(QModelIndex(), row, row);
m_downloads.append(item); m_downloads.append(item);
m_model->endInsertRows(); m_model->endInsertRows();
m_ui->m_viewDownloads->setIndexWidget(m_model->index(row, 0), item); m_ui->m_viewDownloads->setIndexWidget(m_model->index(row, 0), item);
QIcon icon = style()->standardIcon(QStyle::SP_FileIcon); QIcon icon = style()->standardIcon(QStyle::SP_FileIcon);
item->m_ui->m_lblFileIcon->setPixmap(icon.pixmap(DOWNLOADER_ICON_SIZE, DOWNLOADER_ICON_SIZE)); item->m_ui->m_lblFileIcon->setPixmap(icon.pixmap(DOWNLOADER_ICON_SIZE, DOWNLOADER_ICON_SIZE));
m_ui->m_viewDownloads->setRowHeight(row, item->sizeHint().height()); m_ui->m_viewDownloads->setRowHeight(row, item->sizeHint().height());
// Just in case of download finishes before it is actually added. // Just in case of download finishes before it is actually added.
updateRow(item); updateRow(item);
} }
@ -569,6 +550,7 @@ void DownloadManager::itemProgress() {
if (progress < 0) { if (progress < 0) {
emit downloadFinished(); emit downloadFinished();
} }
else { else {
emit downloadProgressed(progress, tr("Downloading %n file(s)...", "", activeDownloads())); emit downloadProgressed(progress, tr("Downloading %n file(s)...", "", activeDownloads()));
} }
@ -592,10 +574,8 @@ void DownloadManager::updateRow(DownloadItem *item) {
} }
item->m_ui->m_lblFileIcon->setPixmap(icon.pixmap(DOWNLOADER_ICON_SIZE, DOWNLOADER_ICON_SIZE)); item->m_ui->m_lblFileIcon->setPixmap(icon.pixmap(DOWNLOADER_ICON_SIZE, DOWNLOADER_ICON_SIZE));
int old_height = m_ui->m_viewDownloads->rowHeight(row); int old_height = m_ui->m_viewDownloads->rowHeight(row);
m_ui->m_viewDownloads->setRowHeight(row, qMax(old_height, item->minimumSizeHint().height())); m_ui->m_viewDownloads->setRowHeight(row, qMax(old_height, item->minimumSizeHint().height()));
// Remove the item if: // Remove the item if:
// a) It is not downloading and private browsing is enabled. // a) It is not downloading and private browsing is enabled.
// OR // OR
@ -644,7 +624,6 @@ void DownloadManager::save() const {
settings->remove(GROUP(Downloads), key); settings->remove(GROUP(Downloads), key);
settings->remove(GROUP(Downloads), QString(Downloads::ItemLocation).arg(i)); settings->remove(GROUP(Downloads), QString(Downloads::ItemLocation).arg(i));
settings->remove(GROUP(Downloads), QString(Downloads::ItemDone).arg(i)); settings->remove(GROUP(Downloads), QString(Downloads::ItemDone).arg(i));
i++; i++;
} }
} }
@ -652,7 +631,6 @@ void DownloadManager::save() const {
void DownloadManager::load() { void DownloadManager::load() {
const Settings* settings = qApp->settings(); const Settings* settings = qApp->settings();
int i = 0; int i = 0;
// Restore the policy. // Restore the policy.
m_removePolicy = static_cast<RemovePolicy>(settings->value(GROUP(Downloads), SETTING(Downloads::RemovePolicy)).toInt()); m_removePolicy = static_cast<RemovePolicy>(settings->value(GROUP(Downloads), SETTING(Downloads::RemovePolicy)).toInt());
@ -666,9 +644,7 @@ void DownloadManager::load() {
DownloadItem* item = new DownloadItem(0, this); DownloadItem* item = new DownloadItem(0, this);
item->m_output.setFileName(file_name); item->m_output.setFileName(file_name);
item->m_url = url; item->m_url = url;
item->updateInfoAndUrlLabel(); item->updateInfoAndUrlLabel();
item->m_ui->m_btnStopDownload->setVisible(false); item->m_ui->m_btnStopDownload->setVisible(false);
item->m_ui->m_btnStopDownload->setEnabled(false); item->m_ui->m_btnStopDownload->setEnabled(false);
item->m_ui->m_btnTryAgain->setVisible(!done); item->m_ui->m_btnTryAgain->setVisible(!done);
@ -710,6 +686,7 @@ QString DownloadManager::timeString(double time_remaining) {
time_remaining = floor(time_remaining); time_remaining = floor(time_remaining);
remaining = tr("%n minutes remaining", "", (int) time_remaining); remaining = tr("%n minutes remaining", "", (int) time_remaining);
} }
else { else {
time_remaining = floor(time_remaining); time_remaining = floor(time_remaining);
remaining = tr("%n seconds remaining", "", (int) time_remaining); remaining = tr("%n seconds remaining", "", (int) time_remaining);
@ -726,14 +703,17 @@ QString DownloadManager::dataString(qint64 size) {
new_size = size; new_size = size;
unit = tr("bytes"); unit = tr("bytes");
} }
else if (size < 1024 * 1024) { else if (size < 1024 * 1024) {
new_size = (double)size / (double)1024; new_size = (double)size / (double)1024;
unit = tr("kB"); unit = tr("kB");
} }
else if (size < 1024 * 1024 * 1024) { else if (size < 1024 * 1024 * 1024) {
new_size = (double)size / (double)(1024 * 1024); new_size = (double)size / (double)(1024 * 1024);
unit = tr("MB"); unit = tr("MB");
} }
else { else {
new_size = (double)size / (double)(1024 * 1024 * 1024); new_size = (double)size / (double)(1024 * 1024 * 1024);
unit = tr("GB"); unit = tr("GB");

View File

@ -69,11 +69,9 @@ GoogleSuggest::GoogleSuggest(LocationLineEdit *editor, QObject *parent)
popup->setFrameStyle(QFrame::Box | QFrame::Plain); popup->setFrameStyle(QFrame::Box | QFrame::Plain);
popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
popup->installEventFilter(this); popup->installEventFilter(this);
timer = new QTimer(this); timer = new QTimer(this);
timer->setSingleShot(true); timer->setSingleShot(true);
timer->setInterval(500); timer->setInterval(500);
connect(popup.data(), &QListWidget::itemClicked, this, &GoogleSuggest::doneCompletion); connect(popup.data(), &QListWidget::itemClicked, this, &GoogleSuggest::doneCompletion);
connect(timer, &QTimer::timeout, this, &GoogleSuggest::autoSuggest); connect(timer, &QTimer::timeout, this, &GoogleSuggest::autoSuggest);
connect(editor, &LocationLineEdit::textEdited, timer, static_cast<void (QTimer::*)()>(&QTimer::start)); connect(editor, &LocationLineEdit::textEdited, timer, static_cast<void (QTimer::*)()>(&QTimer::start));
@ -154,7 +152,6 @@ void GoogleSuggest::doneCompletion() {
timer->stop(); timer->stop();
popup->hide(); popup->hide();
editor->setFocus(); editor->setFocus();
QListWidgetItem* item = popup->currentItem(); QListWidgetItem* item = popup->currentItem();
if (item != nullptr) { if (item != nullptr) {
@ -169,7 +166,6 @@ void GoogleSuggest::preventSuggest() {
void GoogleSuggest::autoSuggest() { void GoogleSuggest::autoSuggest() {
m_enteredText = QUrl::toPercentEncoding(editor->text()); m_enteredText = QUrl::toPercentEncoding(editor->text());
QString url = QString(GOOGLE_SUGGEST_URL).arg(m_enteredText); QString url = QString(GOOGLE_SUGGEST_URL).arg(m_enteredText);
connect(SilentNetworkAccessManager::instance()->get(QNetworkRequest(QString(url))), &QNetworkReply::finished, connect(SilentNetworkAccessManager::instance()->get(QNetworkRequest(QString(url))), &QNetworkReply::finished,
this, &GoogleSuggest::handleNetworkData); this, &GoogleSuggest::handleNetworkData);
} }
@ -181,10 +177,8 @@ void GoogleSuggest::handleNetworkData() {
QStringList choices; QStringList choices;
QDomDocument xml; QDomDocument xml;
QByteArray response = reply->readAll(); QByteArray response = reply->readAll();
const QTextCodec* c = QTextCodec::codecForUtfText(response); const QTextCodec* c = QTextCodec::codecForUtfText(response);
xml.setContent(c->toUnicode(response)); xml.setContent(c->toUnicode(response));
QDomNodeList suggestions = xml.elementsByTagName(QSL("suggestion")); QDomNodeList suggestions = xml.elementsByTagName(QSL("suggestion"));
for (int i = 0; i < suggestions.size(); i++) { for (int i = 0; i < suggestions.size(); i++) {

View File

@ -47,6 +47,7 @@ QStringList NetworkFactory::extractFeedLinksFromHtmlPage(const QUrl &url, const
if (feed_link.startsWith(QL1S("//"))) { if (feed_link.startsWith(QL1S("//"))) {
feed_link = QString(URI_SCHEME_HTTP) + feed_link.mid(2); feed_link = QString(URI_SCHEME_HTTP) + feed_link.mid(2);
} }
else if (feed_link.startsWith(QL1C('/'))) { else if (feed_link.startsWith(QL1C('/'))) {
feed_link = url.toString(QUrl::RemovePath | QUrl::RemoveQuery | QUrl::StripTrailingSlash) + feed_link; feed_link = url.toString(QUrl::RemovePath | QUrl::RemoveQuery | QUrl::StripTrailingSlash) + feed_link;
} }
@ -163,19 +164,16 @@ NetworkResult NetworkFactory::performNetworkOperation(const QString &url, int ti
if (set_basic_header) { if (set_basic_header) {
QString basic_value = username + ":" + password; QString basic_value = username + ":" + password;
QString header_value = QString("Basic ") + QString(basic_value.toUtf8().toBase64()); QString header_value = QString("Basic ") + QString(basic_value.toUtf8().toBase64());
downloader.appendRawHeader("Authorization", header_value.toLocal8Bit()); downloader.appendRawHeader("Authorization", header_value.toLocal8Bit());
} }
// We need to quit event loop when the download finishes. // We need to quit event loop when the download finishes.
QObject::connect(&downloader, &Downloader::completed, &loop, &QEventLoop::quit); QObject::connect(&downloader, &Downloader::completed, &loop, &QEventLoop::quit);
downloader.manipulateData(url, operation, input_data, timeout, protected_contents, username, password); downloader.manipulateData(url, operation, input_data, timeout, protected_contents, username, password);
loop.exec(); loop.exec();
output = downloader.lastOutputData(); output = downloader.lastOutputData();
result.first = downloader.lastOutputError(); result.first = downloader.lastOutputError();
result.second = downloader.lastContentType(); result.second = downloader.lastContentType();
return result; return result;
} }
@ -187,17 +185,13 @@ NetworkResult NetworkFactory::downloadFeedFile(const QString &url, int timeout,
Downloader downloader; Downloader downloader;
QEventLoop loop; QEventLoop loop;
NetworkResult result; NetworkResult result;
downloader.appendRawHeader("Accept", ACCEPT_HEADER_FOR_FEED_DOWNLOADER); downloader.appendRawHeader("Accept", ACCEPT_HEADER_FOR_FEED_DOWNLOADER);
// We need to quit event loop when the download finishes. // We need to quit event loop when the download finishes.
QObject::connect(&downloader, &Downloader::completed, &loop, &QEventLoop::quit); QObject::connect(&downloader, &Downloader::completed, &loop, &QEventLoop::quit);
downloader.downloadFile(url, timeout, protected_contents, username, password); downloader.downloadFile(url, timeout, protected_contents, username, password);
loop.exec(); loop.exec();
output = downloader.lastOutputData(); output = downloader.lastOutputData();
result.first = downloader.lastOutputError(); result.first = downloader.lastOutputError();
result.second = downloader.lastContentType(); result.second = downloader.lastContentType();
return result; return result;
} }

View File

@ -49,12 +49,11 @@ void SilentNetworkAccessManager::onAuthenticationRequired(QNetworkReply *reply,
authenticator->setUser(reply->property("username").toString()); authenticator->setUser(reply->property("username").toString());
authenticator->setPassword(reply->property("password").toString()); authenticator->setPassword(reply->property("password").toString());
reply->setProperty("authentication-given", true); reply->setProperty("authentication-given", true);
qDebug("Item '%s' requested authentication and got it.", qPrintable(reply->url().toString())); qDebug("Item '%s' requested authentication and got it.", qPrintable(reply->url().toString()));
} }
else { else {
reply->setProperty("authentication-given", false); reply->setProperty("authentication-given", false);
// Authentication is required but this feed does not contain it. // Authentication is required but this feed does not contain it.
qWarning("Item '%s' requested authentication but username/password is not available.", qPrintable(reply->url().toString())); qWarning("Item '%s' requested authentication but username/password is not available.", qPrintable(reply->url().toString()));
} }

View File

@ -39,10 +39,10 @@ bool WebFactory::sendMessageViaEmail(const Message &message) {
if (qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailEnabled)).toBool()) { if (qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailEnabled)).toBool()) {
const QString browser = qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailExecutable)).toString(); const QString browser = qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailExecutable)).toString();
const QString arguments = qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailArguments)).toString(); const QString arguments = qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalEmailArguments)).toString();
return QProcess::startDetached(QString("\"") + browser + QSL("\" ") + arguments.arg(message.m_title, return QProcess::startDetached(QString("\"") + browser + QSL("\" ") + arguments.arg(message.m_title,
stripTags(message.m_contents))); stripTags(message.m_contents)));
} }
else { else {
// Send it via mailto protocol. // Send it via mailto protocol.
// NOTE: http://en.wikipedia.org/wiki/Mailto // NOTE: http://en.wikipedia.org/wiki/Mailto
@ -55,11 +55,8 @@ bool WebFactory::openUrlInExternalBrowser(const QString &url) {
if (qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool()) { if (qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserEnabled)).toBool()) {
const QString browser = qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserExecutable)).toString(); const QString browser = qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserExecutable)).toString();
const QString arguments = qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserArguments)).toString(); const QString arguments = qApp->settings()->value(GROUP(Browser), SETTING(Browser::CustomExternalBrowserArguments)).toString();
const QString call_line = "\"" + browser + "\" \"" + arguments.arg(url) + "\""; const QString call_line = "\"" + browser + "\" \"" + arguments.arg(url) + "\"";
qDebug("Running command '%s'.", qPrintable(call_line)); qDebug("Running command '%s'.", qPrintable(call_line));
const bool result = QProcess::startDetached(call_line); const bool result = QProcess::startDetached(call_line);
if (!result) { if (!result) {
@ -68,6 +65,7 @@ bool WebFactory::openUrlInExternalBrowser(const QString &url) {
return result; return result;
} }
else { else {
return QDesktopServices::openUrl(url); return QDesktopServices::openUrl(url);
} }

View File

@ -42,19 +42,24 @@ void WebPage::javaScriptAlert(const QUrl &securityOrigin, const QString &msg) {
if (action == QSL("read")) { if (action == QSL("read")) {
emit messageStatusChangeRequested(message_id, MarkRead); emit messageStatusChangeRequested(message_id, MarkRead);
} }
else if (action == QSL("unread")) { else if (action == QSL("unread")) {
emit messageStatusChangeRequested(message_id, MarkUnread); emit messageStatusChangeRequested(message_id, MarkUnread);
} }
else if (action == QSL("starred")) { else if (action == QSL("starred")) {
emit messageStatusChangeRequested(message_id, MarkStarred); emit messageStatusChangeRequested(message_id, MarkStarred);
} }
else if (action == QSL("unstarred")) { else if (action == QSL("unstarred")) {
emit messageStatusChangeRequested(message_id, MarkUnstarred); emit messageStatusChangeRequested(message_id, MarkUnstarred);
} }
else { else {
QWebEnginePage::javaScriptAlert(securityOrigin, msg); QWebEnginePage::javaScriptAlert(securityOrigin, msg);
} }
} }
else { else {
QWebEnginePage::javaScriptAlert(securityOrigin, msg); QWebEnginePage::javaScriptAlert(securityOrigin, msg);
} }
@ -65,6 +70,7 @@ bool WebPage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool
setHtml(view()->messageContents(), QUrl(INTERNAL_URL_MESSAGE)); setHtml(view()->messageContents(), QUrl(INTERNAL_URL_MESSAGE));
return true; return true;
} }
else { else {
return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame); return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame);
} }

View File

@ -68,9 +68,9 @@ namespace QtLP_Private {
const char* QtLocalPeer::ack = "ack"; const char* QtLocalPeer::ack = "ack";
QtLocalPeer::QtLocalPeer(QObject* parent, const QString& appId) QtLocalPeer::QtLocalPeer(QObject* parent, const QString& appId)
: QObject(parent), id(appId) : QObject(parent), id(appId) {
{
QString prefix = id; QString prefix = id;
if (id.isEmpty()) { if (id.isEmpty()) {
id = QCoreApplication::applicationFilePath(); id = QCoreApplication::applicationFilePath();
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
@ -78,28 +78,29 @@ QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
#endif #endif
prefix = id.section(QLatin1Char('/'), -1); prefix = id.section(QLatin1Char('/'), -1);
} }
prefix.remove(QRegExp("[^a-zA-Z]")); prefix.remove(QRegExp("[^a-zA-Z]"));
prefix.truncate(6); prefix.truncate(6);
QByteArray idc = id.toUtf8(); QByteArray idc = id.toUtf8();
quint16 idNum = qChecksum(idc.constData(), idc.size()); quint16 idNum = qChecksum(idc.constData(), idc.size());
socketName = QLatin1String("qtsingleapp-") + prefix socketName = QLatin1String("qtsingleapp-") + prefix
+ QLatin1Char('-') + QString::number(idNum, 16); + QLatin1Char('-') + QString::number(idNum, 16);
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
if (!pProcessIdToSessionId) { if (!pProcessIdToSessionId) {
QLibrary lib("kernel32"); QLibrary lib("kernel32");
pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
} }
if (pProcessIdToSessionId) { if (pProcessIdToSessionId) {
DWORD sessionId = 0; DWORD sessionId = 0;
pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
socketName += QLatin1Char('-') + QString::number(sessionId, 16); socketName += QLatin1Char('-') + QString::number(sessionId, 16);
} }
#else #else
socketName += QLatin1Char('-') + QString::number(::getuid(), 16); socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
#endif #endif
server = new QLocalServer(this); server = new QLocalServer(this);
QString lockName = QDir(QDir::tempPath()).absolutePath() QString lockName = QDir(QDir::tempPath()).absolutePath()
+ QLatin1Char('/') + socketName + QLatin1Char('/') + socketName
@ -116,42 +117,52 @@ QtLocalPeer::~QtLocalPeer() {
bool QtLocalPeer::isClient() bool QtLocalPeer::isClient() {
{ if (lockFile.isLocked()) {
if (lockFile.isLocked())
return false; return false;
}
if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) {
return true; return true;
}
bool res = server->listen(socketName); bool res = server->listen(socketName);
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) #if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
// ### Workaround // ### Workaround
if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName); QFile::remove(QDir::cleanPath(QDir::tempPath()) + QLatin1Char('/') + socketName);
res = server->listen(socketName); res = server->listen(socketName);
} }
#endif #endif
if (!res)
if (!res) {
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
}
QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection); QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
return false; return false;
} }
bool QtLocalPeer::sendMessage(const QString &message, int timeout) bool QtLocalPeer::sendMessage(const QString& message, int timeout) {
{ if (!isClient()) {
if (!isClient())
return false; return false;
}
QLocalSocket socket; QLocalSocket socket;
bool connOk = false; bool connOk = false;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
// Try twice, in case the other instance is just starting up // Try twice, in case the other instance is just starting up
socket.connectToServer(socketName); socket.connectToServer(socketName);
connOk = socket.waitForConnected(timeout / 2); connOk = socket.waitForConnected(timeout / 2);
if (connOk || i)
if (connOk || i) {
break; break;
}
int ms = 250; int ms = 250;
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
Sleep(DWORD(ms)); Sleep(DWORD(ms));
@ -160,30 +171,39 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout)
nanosleep(&ts, nullptr); nanosleep(&ts, nullptr);
#endif #endif
} }
if (!connOk)
if (!connOk) {
return false; return false;
}
QByteArray uMsg(message.toUtf8()); QByteArray uMsg(message.toUtf8());
QDataStream ds(&socket); QDataStream ds(&socket);
ds.writeBytes(uMsg.constData(), uMsg.size()); ds.writeBytes(uMsg.constData(), uMsg.size());
bool res = socket.waitForBytesWritten(timeout); bool res = socket.waitForBytesWritten(timeout);
if (res) { if (res) {
res &= socket.waitForReadyRead(timeout); // wait for ack res &= socket.waitForReadyRead(timeout); // wait for ack
if (res)
if (res) {
res &= (socket.read(qstrlen(ack)) == ack); res &= (socket.read(qstrlen(ack)) == ack);
} }
}
return res; return res;
} }
void QtLocalPeer::receiveConnection() void QtLocalPeer::receiveConnection() {
{
QLocalSocket* socket = server->nextPendingConnection(); QLocalSocket* socket = server->nextPendingConnection();
if (!socket)
return;
while (socket->bytesAvailable() < (int)sizeof(quint32)) if (!socket) {
return;
}
while (socket->bytesAvailable() < (int)sizeof(quint32)) {
socket->waitForReadyRead(); socket->waitForReadyRead();
}
QDataStream ds(socket); QDataStream ds(socket);
QByteArray uMsg; QByteArray uMsg;
quint32 remaining; quint32 remaining;
@ -191,16 +211,20 @@ void QtLocalPeer::receiveConnection()
uMsg.resize(remaining); uMsg.resize(remaining);
int got = 0; int got = 0;
char* uMsgBuf = uMsg.data(); char* uMsgBuf = uMsg.data();
do { do {
got = ds.readRawData(uMsgBuf, remaining); got = ds.readRawData(uMsgBuf, remaining);
remaining -= got; remaining -= got;
uMsgBuf += got; uMsgBuf += got;
} while (remaining && got >= 0 && socket->waitForReadyRead(2000)); }
while (remaining && got >= 0 && socket->waitForReadyRead(2000));
if (got < 0) { if (got < 0) {
qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData()); qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
delete socket; delete socket;
return; return;
} }
QString message(QString::fromUtf8(uMsg)); QString message(QString::fromUtf8(uMsg));
socket->write(ack, qstrlen(ack)); socket->write(ack, qstrlen(ack));
socket->waitForBytesWritten(1000); socket->waitForBytesWritten(1000);

8
src/qtsingleapplication/qtlocalpeer.h Normal file → Executable file
View File

@ -47,8 +47,7 @@
#include "qtlockedfile.h" #include "qtlockedfile.h"
class QtLocalPeer : public QObject class QtLocalPeer : public QObject {
{
Q_OBJECT Q_OBJECT
public: public:
@ -56,8 +55,9 @@ public:
~QtLocalPeer(); ~QtLocalPeer();
bool isClient(); bool isClient();
bool sendMessage(const QString& message, int timeout); bool sendMessage(const QString& message, int timeout);
QString applicationId() const QString applicationId() const {
{ return id; } return id;
}
Q_SIGNALS: Q_SIGNALS:
void messageReceived(const QString& message); void messageReceived(const QString& message);

16
src/qtsingleapplication/qtlockedfile.cpp Normal file → Executable file
View File

@ -81,8 +81,7 @@
\sa QFile::QFile() \sa QFile::QFile()
*/ */
QtLockedFile::QtLockedFile() QtLockedFile::QtLockedFile()
: QFile() : QFile() {
{
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
wmutex = 0; wmutex = 0;
rmutex = 0; rmutex = 0;
@ -98,8 +97,7 @@ QtLockedFile::QtLockedFile()
\sa QFile::QFile() \sa QFile::QFile()
*/ */
QtLockedFile::QtLockedFile(const QString& name) QtLockedFile::QtLockedFile(const QString& name)
: QFile(name) : QFile(name) {
{
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
wmutex = 0; wmutex = 0;
rmutex = 0; rmutex = 0;
@ -120,12 +118,12 @@ QtLockedFile::QtLockedFile(const QString &name)
\sa QFile::open(), QFile::resize() \sa QFile::open(), QFile::resize()
*/ */
bool QtLockedFile::open(OpenMode mode) bool QtLockedFile::open(OpenMode mode) {
{
if (mode & QIODevice::Truncate) { if (mode & QIODevice::Truncate) {
qWarning("QtLockedFile::open(): Truncate mode not allowed."); qWarning("QtLockedFile::open(): Truncate mode not allowed.");
return false; return false;
} }
return QFile::open(mode); return QFile::open(mode);
} }
@ -135,8 +133,7 @@ bool QtLockedFile::open(OpenMode mode)
\sa lockMode() \sa lockMode()
*/ */
bool QtLockedFile::isLocked() const bool QtLockedFile::isLocked() const {
{
return m_lock_mode != NoLock; return m_lock_mode != NoLock;
} }
@ -146,8 +143,7 @@ bool QtLockedFile::isLocked() const
\sa isLocked() \sa isLocked()
*/ */
QtLockedFile::LockMode QtLockedFile::lockMode() const QtLockedFile::LockMode QtLockedFile::lockMode() const {
{
return m_lock_mode; return m_lock_mode;
} }

3
src/qtsingleapplication/qtlockedfile.h Normal file → Executable file
View File

@ -64,8 +64,7 @@
namespace QtLP_Private { namespace QtLP_Private {
class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile {
{
Q_OBJECT Q_OBJECT
public: public:

40
src/qtsingleapplication/qtlockedfile_unix.cpp Normal file → Executable file
View File

@ -45,57 +45,71 @@
#include "qtlockedfile.h" #include "qtlockedfile.h"
bool QtLockedFile::lock(LockMode mode, bool block) bool QtLockedFile::lock(LockMode mode, bool block) {
{
if (!isOpen()) { if (!isOpen()) {
qWarning("QtLockedFile::lock(): file is not opened"); qWarning("QtLockedFile::lock(): file is not opened");
return false; return false;
} }
if (mode == NoLock) if (mode == NoLock) {
return unlock(); return unlock();
}
if (mode == m_lock_mode) if (mode == m_lock_mode) {
return true; return true;
}
if (m_lock_mode != NoLock) if (m_lock_mode != NoLock) {
unlock(); unlock();
}
struct flock fl; struct flock fl;
fl.l_whence = SEEK_SET; fl.l_whence = SEEK_SET;
fl.l_start = 0; fl.l_start = 0;
fl.l_len = 0; fl.l_len = 0;
fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
int cmd = block ? F_SETLKW : F_SETLK; int cmd = block ? F_SETLKW : F_SETLK;
int ret = fcntl(handle(), cmd, &fl); int ret = fcntl(handle(), cmd, &fl);
if (ret == -1) { if (ret == -1) {
if (errno != EINTR && errno != EAGAIN) if (errno != EINTR && errno != EAGAIN) {
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
return false;
} }
return false;
}
m_lock_mode = mode; m_lock_mode = mode;
return true; return true;
} }
bool QtLockedFile::unlock() bool QtLockedFile::unlock() {
{
if (!isOpen()) { if (!isOpen()) {
qWarning("QtLockedFile::unlock(): file is not opened"); qWarning("QtLockedFile::unlock(): file is not opened");
return false; return false;
} }
if (!isLocked()) if (!isLocked()) {
return true; return true;
}
struct flock fl; struct flock fl;
fl.l_whence = SEEK_SET; fl.l_whence = SEEK_SET;
fl.l_start = 0; fl.l_start = 0;
fl.l_len = 0; fl.l_len = 0;
fl.l_type = F_UNLCK; fl.l_type = F_UNLCK;
int ret = fcntl(handle(), F_SETLKW, &fl); int ret = fcntl(handle(), F_SETLKW, &fl);
if (ret == -1) { if (ret == -1) {
@ -107,9 +121,9 @@ bool QtLockedFile::unlock()
return true; return true;
} }
QtLockedFile::~QtLockedFile() QtLockedFile::~QtLockedFile() {
{ if (isOpen()) {
if (isOpen())
unlock(); unlock();
} }
}

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