Finalized uncrustify config, will reformat it all.
This commit is contained in:
parent
7b62a456a6
commit
dd4a96f51f
@ -3,6 +3,10 @@
|
|||||||
set FOR foreach
|
set FOR foreach
|
||||||
set FOR forever
|
set FOR forever
|
||||||
|
|
||||||
|
# SIGNAL/SLOT Qt macros have special formatting options. See options_for_QT.cpp for details.
|
||||||
|
# Default=True
|
||||||
|
use_options_overriding_for_qt_macros = true # false/true
|
||||||
|
|
||||||
## General.
|
## General.
|
||||||
|
|
||||||
newlines = auto # auto/lf/crlf/cr
|
newlines = auto # auto/lf/crlf/cr
|
||||||
@ -13,10 +17,270 @@ input_tab_size = 2 # number
|
|||||||
# The size of tabs in the output (only used if align_with_tabs=true)
|
# The size of tabs in the output (only used if align_with_tabs=true)
|
||||||
output_tab_size = 2 # number
|
output_tab_size = 2 # number
|
||||||
|
|
||||||
|
# Control what to do with the UTF-8 BOM (recommend 'remove')
|
||||||
|
utf8_bom = remove # ignore/add/remove/force
|
||||||
|
|
||||||
## Spaces.
|
## Spaces.
|
||||||
|
|
||||||
|
# Add or remove space around arithmetic operator '+', '-', '/', '*', etc
|
||||||
|
# also '>>>' '<<' '>>' '%' '|'
|
||||||
|
sp_arith = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space around assignment operator '=', '+=', etc
|
||||||
|
sp_assign = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space after ','
|
||||||
|
sp_after_comma = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign
|
||||||
|
sp_cpp_lambda_assign = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space after the capture specification in C++11 lambda.
|
||||||
|
sp_cpp_lambda_paren = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space around assignment operator '=' in a prototype
|
||||||
|
sp_assign_default = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space around assignment '=' in enum
|
||||||
|
sp_enum_assign = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space before pointer star '*'
|
||||||
|
sp_before_ptr_star = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space before pointer star '*' that isn't followed by a variable name
|
||||||
|
# If set to 'ignore', sp_before_ptr_star is used instead.
|
||||||
|
sp_before_unnamed_ptr_star = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space between pointer stars '*'
|
||||||
|
sp_between_ptr_star = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space after pointer star '*', if followed by a word.
|
||||||
|
sp_after_ptr_star = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space after pointer star '*', if followed by a qualifier.
|
||||||
|
sp_after_ptr_star_qualifier = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space after a pointer star '*', if followed by a func proto/def.
|
||||||
|
sp_after_ptr_star_func = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space after a pointer star '*', if followed by an open paren (function types).
|
||||||
|
sp_ptr_star_paren = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space before a pointer star '*', if followed by a func proto/def.
|
||||||
|
sp_before_ptr_star_func = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space before a reference sign '&'
|
||||||
|
sp_before_byref = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space before a reference sign '&' that isn't followed by a variable name
|
||||||
|
# If set to 'ignore', sp_before_byref is used instead.
|
||||||
|
sp_before_unnamed_byref = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space after reference sign '&', if followed by a word.
|
||||||
|
sp_after_byref = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space after a reference sign '&', if followed by a func proto/def.
|
||||||
|
sp_after_byref_func = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space before a reference sign '&', if followed by a func proto/def.
|
||||||
|
sp_before_byref_func = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add
|
||||||
|
sp_angle_shift = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Permit removal of the space between '>>' in 'foo<bar<int> >' (C++11 only). Default=False
|
||||||
|
# sp_angle_shift cannot remove the space without this option.
|
||||||
|
sp_permit_cpp11_shift = true # false/true
|
||||||
|
|
||||||
## Indents.
|
## Indents.
|
||||||
|
|
||||||
|
# The number of columns to indent per level.
|
||||||
|
# Usually 2, 3, 4, or 8. Default=8
|
||||||
|
indent_columns = 2 # unsigned number
|
||||||
|
|
||||||
|
# How to use tabs when indenting code
|
||||||
|
# 0=spaces only
|
||||||
|
# 1=indent with tabs to brace level, align with spaces (default)
|
||||||
|
# 2=indent and align with tabs, using spaces when not on a tabstop
|
||||||
|
indent_with_tabs = 0 # number
|
||||||
|
|
||||||
|
# Whether to indent strings broken by '\' so that they line up
|
||||||
|
indent_align_string = true # false/true
|
||||||
|
|
||||||
|
# Whether the 'namespace' body is indented
|
||||||
|
indent_namespace = true # false/true
|
||||||
|
|
||||||
|
# Whether the 'class' body is indented
|
||||||
|
indent_class = true # false/true
|
||||||
|
|
||||||
|
# Same as indent_label, but for access specifiers that are followed by a colon. Default=1
|
||||||
|
indent_access_spec = 2 # number
|
||||||
|
|
||||||
|
# Indent the code after an access specifier by one level.
|
||||||
|
# If set, this option forces 'indent_access_spec=0'
|
||||||
|
indent_access_spec_body = true # false/true
|
||||||
|
|
||||||
|
# Spaces to indent 'case' from 'switch'
|
||||||
|
# Usually 0 or indent_columns.
|
||||||
|
indent_switch_case = 2 # unsigned number
|
||||||
|
|
||||||
|
# indent the continuation of ternary operator.
|
||||||
|
# 0: (Default) off
|
||||||
|
# 1: When the `if_false` is a continuation, indent it under `if_false`
|
||||||
|
# 2: When the `:` is a continuation, indent it under `?`
|
||||||
|
indent_ternary_operator = 2 # unsigned number
|
||||||
|
|
||||||
|
## Newlines.
|
||||||
|
|
||||||
|
# Whether to collapse empty blocks between '{' and '}'
|
||||||
|
nl_collapse_empty_body = true # false/true
|
||||||
|
|
||||||
|
# Add or remove newlines at the start of the file
|
||||||
|
nl_start_of_file = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# The number of blank lines after a block of variable definitions at the top of a function body
|
||||||
|
# 0 = No change (default)
|
||||||
|
nl_func_var_def_blk = 1 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines before a block of typedefs
|
||||||
|
# 0 = No change (default)
|
||||||
|
# the option 'nl_after_access_spec' takes preference over 'nl_typedef_blk_start'
|
||||||
|
nl_typedef_blk_start = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines after a block of typedefs
|
||||||
|
# 0 = No change (default)
|
||||||
|
nl_typedef_blk_end = 2 # unsigned number
|
||||||
|
|
||||||
|
# The maximum consecutive newlines within a block of typedefs
|
||||||
|
# 0 = No change (default)
|
||||||
|
nl_typedef_blk_in = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines after a block of variable definitions not at the top of a function body
|
||||||
|
# 0 = No change (default)
|
||||||
|
nl_var_def_blk_end = 2 # unsigned number
|
||||||
|
|
||||||
|
# The maximum consecutive newlines within a block of variable definitions
|
||||||
|
# 0 = No change (default)
|
||||||
|
nl_var_def_blk_in = 1 # unsigned number
|
||||||
|
|
||||||
|
# Add or remove newline between 'enum' and '{'
|
||||||
|
nl_enum_brace = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove newline between 'enum' and 'class'
|
||||||
|
nl_enum_class = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove newline between 'enum class' and the identifier
|
||||||
|
nl_enum_class_identifier = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove newline between 'if' and '{'
|
||||||
|
nl_if_brace = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove newline between '}' and 'else'
|
||||||
|
nl_brace_else = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove newline between 'else' and '{'
|
||||||
|
nl_else_brace = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove newline between 'else' and 'if'
|
||||||
|
nl_else_if = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove newline before 'if'/'else if' closing parenthesis
|
||||||
|
nl_before_if_closing_paren = remove # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Whether to put a newline after 'case' statement
|
||||||
|
nl_after_case = false # false/true
|
||||||
|
|
||||||
|
# Whether to put a newline before 'case' statement, not after the first 'case'
|
||||||
|
nl_before_case = true # false/true
|
||||||
|
|
||||||
|
# Whether to remove blanks after '#ifxx' and '#elxx', or before '#elxx' and '#endif'. Does not affect top-level #ifdefs.
|
||||||
|
nl_squeeze_ifdef = true # false/true
|
||||||
|
|
||||||
|
# Add or remove blank line after 'if' statement.
|
||||||
|
# Add/Force work only if the next token is not a closing brace
|
||||||
|
nl_after_if = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove blank line after 'for' statement
|
||||||
|
nl_after_for = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove blank line after 'while' statement
|
||||||
|
nl_after_while = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove blank line after 'switch' statement
|
||||||
|
nl_after_switch = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
# Add or remove blank line after 'do/while' statement
|
||||||
|
nl_after_do = force # ignore/add/remove/force
|
||||||
|
|
||||||
|
## Blank line options
|
||||||
|
|
||||||
|
# The maximum consecutive newlines (3 = 2 blank lines)
|
||||||
|
nl_max = 2 # unsigned number
|
||||||
|
|
||||||
|
# The minimum number of newlines before a multi-line comment.
|
||||||
|
# Doesn't apply if after a brace open or another multi-line comment.
|
||||||
|
nl_before_block_comment = 2 # unsigned number
|
||||||
|
|
||||||
|
# The minimum number of newlines before a single-line C comment.
|
||||||
|
# Doesn't apply if after a brace open or other single-line C comments.
|
||||||
|
nl_before_c_comment = 2 # unsigned number
|
||||||
|
|
||||||
|
# The minimum number of newlines before a CPP comment.
|
||||||
|
# Doesn't apply if after a brace open or other CPP comments.
|
||||||
|
nl_before_cpp_comment = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines before a class definition
|
||||||
|
nl_before_class = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines after '}' or ';' of a class definition
|
||||||
|
nl_after_class = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines after '}' of a multi-line function body
|
||||||
|
nl_after_func_body = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines after '}' of a multi-line function body in a class declaration
|
||||||
|
nl_after_func_body_class = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines after '}' of a single line function body
|
||||||
|
nl_after_func_body_one_liner = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
|
||||||
|
# Will not change the newline count if after a brace open.
|
||||||
|
# 0 = No change.
|
||||||
|
nl_before_access_spec = 2 # unsigned number
|
||||||
|
|
||||||
|
# The number of newlines after a try-catch-finally block that isn't followed by a brace close.
|
||||||
|
# 0 = No change.
|
||||||
|
nl_after_try_catch_finally = 2 # unsigned number
|
||||||
|
|
||||||
|
# How aggressively to remove extra newlines not in preproc.
|
||||||
|
# 0: No change
|
||||||
|
# 1: Remove most newlines not handled by other config
|
||||||
|
# 2: Remove all newlines and reformat completely by config
|
||||||
|
nl_remove_extra_newlines = 0 # unsigned number
|
||||||
|
|
||||||
|
## Splitting.
|
||||||
|
|
||||||
|
# Try to limit code width to N number of columns
|
||||||
|
code_width = 140 # unsigned number
|
||||||
|
|
||||||
|
# Whether to fully split long function protos/calls at commas
|
||||||
|
ls_func_split_full = true # false/true
|
||||||
|
|
||||||
|
## Comments.
|
||||||
|
|
||||||
|
# Set the comment reflow mode (Default=0)
|
||||||
|
# 0: no reflowing (apart from the line wrapping due to cmt_width)
|
||||||
|
# 1: no touching at all
|
||||||
|
# 2: full reflow
|
||||||
|
cmt_reflow_mode = 2 # number
|
||||||
|
|
||||||
|
# Whether to convert all tabs to spaces in comments. Default is to leave tabs inside comments alone, unless used for indenting.
|
||||||
|
cmt_convert_tab_to_spaces = true # false/true
|
||||||
|
|
||||||
|
# Whether to group c-comments that look like they are in a block
|
||||||
|
cmt_c_group = true # false/true
|
||||||
|
|
||||||
## Modifications.
|
## Modifications.
|
||||||
|
|
||||||
# If True, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C]
|
# If True, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -18,525 +19,546 @@
|
|||||||
#include "core/feedsmodel.h"
|
#include "core/feedsmodel.h"
|
||||||
|
|
||||||
#include "definitions/definitions.h"
|
#include "definitions/definitions.h"
|
||||||
#include "services/abstract/feed.h"
|
#include "miscellaneous/databasefactory.h"
|
||||||
|
#include "miscellaneous/feedreader.h"
|
||||||
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
#include "miscellaneous/textfactory.h"
|
||||||
#include "services/abstract/category.h"
|
#include "services/abstract/category.h"
|
||||||
#include "services/abstract/serviceroot.h"
|
#include "services/abstract/feed.h"
|
||||||
#include "services/abstract/recyclebin.h"
|
#include "services/abstract/recyclebin.h"
|
||||||
#include "services/abstract/serviceentrypoint.h"
|
#include "services/abstract/serviceentrypoint.h"
|
||||||
|
#include "services/abstract/serviceroot.h"
|
||||||
#include "services/standard/standardserviceentrypoint.h"
|
#include "services/standard/standardserviceentrypoint.h"
|
||||||
#include "services/standard/standardserviceroot.h"
|
#include "services/standard/standardserviceroot.h"
|
||||||
#include "miscellaneous/textfactory.h"
|
|
||||||
#include "miscellaneous/databasefactory.h"
|
|
||||||
#include "miscellaneous/iconfactory.h"
|
|
||||||
#include "miscellaneous/feedreader.h"
|
|
||||||
|
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QPair>
|
||||||
#include <QSqlError>
|
#include <QSqlError>
|
||||||
#include <QSqlRecord>
|
#include <QSqlRecord>
|
||||||
#include <QPair>
|
|
||||||
#include <QStack>
|
#include <QStack>
|
||||||
#include <QMimeData>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
FeedsModel::FeedsModel(QObject* parent) : QAbstractItemModel(parent) {
|
FeedsModel::FeedsModel(QObject* parent) : QAbstractItemModel(parent) {
|
||||||
setObjectName(QSL("FeedsModel"));
|
setObjectName(QSL("FeedsModel"));
|
||||||
// Create root item.
|
|
||||||
m_rootItem = new RootItem();
|
// Create root item.
|
||||||
// : Name of root item of feed list which can be seen in feed add/edit dialog.
|
m_rootItem = new RootItem();
|
||||||
m_rootItem->setTitle(tr("Root"));
|
|
||||||
m_rootItem->setIcon(qApp->icons()->fromTheme(QSL("folder")));
|
// : Name of root item of feed list which can be seen in feed add/edit dialog.
|
||||||
// Setup icons.
|
m_rootItem->setTitle(tr("Root"));
|
||||||
m_countsIcon = qApp->icons()->fromTheme(QSL("mail-mark-unread"));
|
m_rootItem->setIcon(qApp->icons()->fromTheme(QSL("folder")));
|
||||||
// : Title text in the feed list header.
|
|
||||||
m_headerData << tr("Title");
|
// Setup icons.
|
||||||
m_tooltipData << /*: Feed list header "titles" column tooltip.*/ tr("Titles of feeds/categories.")
|
m_countsIcon = qApp->icons()->fromTheme(QSL("mail-mark-unread"));
|
||||||
<< /*: Feed list header "counts" column tooltip.*/ tr("Counts of unread/all mesages.");
|
|
||||||
|
// : Title text in the feed list header.
|
||||||
|
m_headerData << tr("Title");
|
||||||
|
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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
FeedsModel::~FeedsModel() {
|
FeedsModel::~FeedsModel() {
|
||||||
qDebug("Destroying FeedsModel instance.");
|
qDebug("Destroying FeedsModel instance.");
|
||||||
// Delete all model items.
|
|
||||||
delete m_rootItem;
|
// Delete all model items.
|
||||||
|
delete m_rootItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMimeData* FeedsModel::mimeData(const QModelIndexList& indexes) const {
|
QMimeData* FeedsModel::mimeData(const QModelIndexList& indexes) const {
|
||||||
QMimeData* mime_data = new QMimeData();
|
QMimeData* mime_data = new QMimeData();
|
||||||
QByteArray encoded_data;
|
QByteArray encoded_data;
|
||||||
QDataStream stream(&encoded_data, QIODevice::WriteOnly);
|
QDataStream stream(&encoded_data, QIODevice::WriteOnly);
|
||||||
|
|
||||||
foreach (const QModelIndex& index, indexes) {
|
foreach (const QModelIndex& index, indexes) {
|
||||||
if (index.column() != 0) {
|
if (index.column() != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootItem* item_for_index = itemForIndex(index);
|
RootItem* item_for_index = itemForIndex(index);
|
||||||
|
|
||||||
if (item_for_index->kind() != RootItemKind::Root) {
|
if (item_for_index->kind() != RootItemKind::Root) {
|
||||||
stream << (quintptr) item_for_index;
|
stream << (quintptr) item_for_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mime_data->setData(QSL(MIME_TYPE_ITEM_POINTER), encoded_data);
|
mime_data->setData(QSL(MIME_TYPE_ITEM_POINTER), encoded_data);
|
||||||
return mime_data;
|
|
||||||
|
return mime_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList FeedsModel::mimeTypes() const {
|
QStringList FeedsModel::mimeTypes() const {
|
||||||
return QStringList() << QSL(MIME_TYPE_ITEM_POINTER);
|
return QStringList() << QSL(MIME_TYPE_ITEM_POINTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedsModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) {
|
bool FeedsModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column,
|
||||||
Q_UNUSED(row)
|
const QModelIndex& parent) {
|
||||||
Q_UNUSED(column)
|
Q_UNUSED(row)
|
||||||
|
Q_UNUSED(column)
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray dragged_items_data = data->data(QSL(MIME_TYPE_ITEM_POINTER));
|
QByteArray dragged_items_data = data->data(QSL(MIME_TYPE_ITEM_POINTER));
|
||||||
|
|
||||||
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.
|
|
||||||
RootItem* dragged_item = (RootItem*) pointer_to_item;
|
|
||||||
RootItem* target_item = itemForIndex(parent);
|
|
||||||
ServiceRoot* dragged_item_root = dragged_item->getParentServiceRoot();
|
|
||||||
ServiceRoot* target_item_root = target_item->getParentServiceRoot();
|
|
||||||
|
|
||||||
if (dragged_item == target_item || dragged_item->parent() == target_item) {
|
// We have item we want to drag, we also determine the target item.
|
||||||
qDebug("Dragged item is equal to target item or its parent is equal to target item. Cancelling drag-drop action.");
|
RootItem* dragged_item = (RootItem*) pointer_to_item;
|
||||||
return false;
|
RootItem* target_item = itemForIndex(parent);
|
||||||
}
|
ServiceRoot* dragged_item_root = dragged_item->getParentServiceRoot();
|
||||||
|
ServiceRoot* target_item_root = target_item->getParentServiceRoot();
|
||||||
|
|
||||||
if (dragged_item_root != target_item_root) {
|
if (dragged_item == target_item || dragged_item->parent() == target_item) {
|
||||||
// Transferring of items between different accounts is not possible.
|
qDebug("Dragged item is equal to target item or its parent is equal to target item. Cancelling drag-drop action.");
|
||||||
qApp->showGuiMessage(tr("Cannot perform drag & drop operation"),
|
return false;
|
||||||
tr("You can't transfer dragged item into different account, this is not supported."),
|
}
|
||||||
QSystemTrayIcon::Warning,
|
|
||||||
qApp->mainFormWidget(),
|
|
||||||
true);
|
|
||||||
qDebug("Dragged item cannot be dragged into different account. Cancelling drag-drop action.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dragged_item->performDragDropChange(target_item)) {
|
if (dragged_item_root != target_item_root) {
|
||||||
// Drag & drop is supported by the dragged item and was
|
// Transferring of items between different accounts is not possible.
|
||||||
// completed on data level and in item hierarchy.
|
qApp->showGuiMessage(tr("Cannot perform drag & drop operation"),
|
||||||
emit requireItemValidationAfterDragDrop(indexForItem(dragged_item));
|
tr("You can't transfer dragged item into different account, this is not supported."),
|
||||||
}
|
QSystemTrayIcon::Warning,
|
||||||
}
|
qApp->mainFormWidget(),
|
||||||
|
true);
|
||||||
|
qDebug("Dragged item cannot be dragged into different account. Cancelling drag-drop action.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
if (dragged_item->performDragDropChange(target_item)) {
|
||||||
}
|
// Drag & drop is supported by the dragged item and was
|
||||||
|
// completed on data level and in item hierarchy.
|
||||||
|
emit requireItemValidationAfterDragDrop(indexForItem(dragged_item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::DropActions FeedsModel::supportedDropActions() const {
|
Qt::DropActions FeedsModel::supportedDropActions() const {
|
||||||
return Qt::MoveAction;
|
return Qt::MoveAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::ItemFlags FeedsModel::flags(const QModelIndex& index) const {
|
Qt::ItemFlags FeedsModel::flags(const QModelIndex& index) const {
|
||||||
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 base_flags = QAbstractItemModel::flags(index);
|
||||||
return base_flags | additional_flags;
|
Qt::ItemFlags additional_flags = item_for_index->additionalFlags();
|
||||||
|
|
||||||
|
return base_flags | additional_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant FeedsModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
QVariant FeedsModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||||
if (orientation != Qt::Horizontal) {
|
if (orientation != Qt::Horizontal) {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::ToolTipRole:
|
case Qt::ToolTipRole:
|
||||||
return m_tooltipData.at(section);
|
return m_tooltipData.at(section);
|
||||||
|
|
||||||
case Qt::DecorationRole:
|
case Qt::DecorationRole:
|
||||||
if (section == FDS_MODEL_COUNTS_INDEX) {
|
if (section == FDS_MODEL_COUNTS_INDEX) {
|
||||||
return m_countsIcon;
|
return m_countsIcon;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex FeedsModel::index(int row, int column, const QModelIndex& parent) const {
|
QModelIndex FeedsModel::index(int row, int column, const QModelIndex& parent) const {
|
||||||
if (!hasIndex(row, column, parent)) {
|
if (!hasIndex(row, column, parent)) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
RootItem* parent_item = itemForIndex(parent);
|
RootItem* parent_item = itemForIndex(parent);
|
||||||
RootItem* child_item = parent_item->child(row);
|
RootItem* child_item = parent_item->child(row);
|
||||||
|
|
||||||
if (child_item) {
|
if (child_item) {
|
||||||
return createIndex(row, column, child_item);
|
return createIndex(row, column, child_item);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex FeedsModel::parent(const QModelIndex& child) const {
|
QModelIndex FeedsModel::parent(const QModelIndex& child) const {
|
||||||
if (!child.isValid()) {
|
if (!child.isValid()) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
RootItem* child_item = itemForIndex(child);
|
RootItem* child_item = itemForIndex(child);
|
||||||
RootItem* parent_item = child_item->parent();
|
RootItem* parent_item = child_item->parent();
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FeedsModel::rowCount(const QModelIndex& parent) const {
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FeedsModel::countOfAllMessages() const {
|
int FeedsModel::countOfAllMessages() const {
|
||||||
return m_rootItem->countOfAllMessages();
|
return m_rootItem->countOfAllMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
int FeedsModel::countOfUnreadMessages() const {
|
int FeedsModel::countOfUnreadMessages() const {
|
||||||
return m_rootItem->countOfUnreadMessages();
|
return m_rootItem->countOfUnreadMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::reloadCountsOfWholeModel() {
|
void FeedsModel::reloadCountsOfWholeModel() {
|
||||||
m_rootItem->updateCounts(true);
|
m_rootItem->updateCounts(true);
|
||||||
reloadWholeLayout();
|
reloadWholeLayout();
|
||||||
notifyWithCounts();
|
notifyWithCounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::removeItem(const QModelIndex& index) {
|
void FeedsModel::removeItem(const QModelIndex& index) {
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
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());
|
|
||||||
parent_item->removeChild(deleting_item);
|
beginRemoveRows(parent_index, index.row(), index.row());
|
||||||
endRemoveRows();
|
parent_item->removeChild(deleting_item);
|
||||||
deleting_item->deleteLater();
|
endRemoveRows();
|
||||||
notifyWithCounts();
|
deleting_item->deleteLater();
|
||||||
}
|
notifyWithCounts();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::removeItem(RootItem* deleting_item) {
|
void FeedsModel::removeItem(RootItem* deleting_item) {
|
||||||
if (deleting_item != nullptr) {
|
if (deleting_item != nullptr) {
|
||||||
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());
|
|
||||||
parent_item->removeChild(deleting_item);
|
beginRemoveRows(parent_index, index.row(), index.row());
|
||||||
endRemoveRows();
|
parent_item->removeChild(deleting_item);
|
||||||
deleting_item->deleteLater();
|
endRemoveRows();
|
||||||
notifyWithCounts();
|
deleting_item->deleteLater();
|
||||||
}
|
notifyWithCounts();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::reassignNodeToNewParent(RootItem* original_node, RootItem* new_parent) {
|
void FeedsModel::reassignNodeToNewParent(RootItem* original_node, RootItem* new_parent) {
|
||||||
RootItem* original_parent = original_node->parent();
|
RootItem* original_parent = original_node->parent();
|
||||||
|
|
||||||
if (original_parent != new_parent) {
|
if (original_parent != new_parent) {
|
||||||
if (original_parent != nullptr) {
|
if (original_parent != nullptr) {
|
||||||
int original_index_of_item = original_parent->childItems().indexOf(original_node);
|
int original_index_of_item = original_parent->childItems().indexOf(original_node);
|
||||||
|
|
||||||
if (original_index_of_item >= 0) {
|
if (original_index_of_item >= 0) {
|
||||||
// Remove the original item from the model...
|
// Remove the original item from the model...
|
||||||
beginRemoveRows(indexForItem(original_parent), original_index_of_item, original_index_of_item);
|
beginRemoveRows(indexForItem(original_parent), original_index_of_item, original_index_of_item);
|
||||||
original_parent->removeChild(original_node);
|
original_parent->removeChild(original_node);
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_index_of_item = new_parent->childCount();
|
int new_index_of_item = new_parent->childCount();
|
||||||
// ... and insert it under the new parent.
|
|
||||||
beginInsertRows(indexForItem(new_parent), new_index_of_item, new_index_of_item);
|
// ... and insert it under the new parent.
|
||||||
new_parent->appendChild(original_node);
|
beginInsertRows(indexForItem(new_parent), new_index_of_item, new_index_of_item);
|
||||||
endInsertRows();
|
new_parent->appendChild(original_node);
|
||||||
}
|
endInsertRows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ServiceRoot*>FeedsModel::serviceRoots() const {
|
QList<ServiceRoot*>FeedsModel::serviceRoots() const {
|
||||||
QList<ServiceRoot*>roots;
|
QList<ServiceRoot*>roots;
|
||||||
|
|
||||||
foreach (RootItem* root, m_rootItem->childItems()) {
|
foreach (RootItem* root, m_rootItem->childItems()) {
|
||||||
if (root->kind() == RootItemKind::ServiceRoot) {
|
if (root->kind() == RootItemKind::ServiceRoot) {
|
||||||
roots.append(root->toServiceRoot());
|
roots.append(root->toServiceRoot());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return roots;
|
return roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedsModel::containsServiceRootFromEntryPoint(const ServiceEntryPoint* point) const {
|
bool FeedsModel::containsServiceRootFromEntryPoint(const ServiceEntryPoint* point) const {
|
||||||
foreach (const ServiceRoot* root, serviceRoots()) {
|
foreach (const ServiceRoot* root, serviceRoots()) {
|
||||||
if (root->code() == point->code()) {
|
if (root->code() == point->code()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardServiceRoot* FeedsModel::standardServiceRoot() const {
|
StandardServiceRoot* FeedsModel::standardServiceRoot() const {
|
||||||
foreach (ServiceRoot* root, serviceRoots()) {
|
foreach (ServiceRoot* root, serviceRoots()) {
|
||||||
StandardServiceRoot* std_service_root;
|
StandardServiceRoot* std_service_root;
|
||||||
|
|
||||||
if ((std_service_root = dynamic_cast<StandardServiceRoot*>(root)) != nullptr) {
|
if ((std_service_root = dynamic_cast<StandardServiceRoot*>(root)) != nullptr) {
|
||||||
return std_service_root;
|
return std_service_root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Feed*>FeedsModel::feedsForScheduledUpdate(bool auto_update_now) {
|
QList<Feed*>FeedsModel::feedsForScheduledUpdate(bool auto_update_now) {
|
||||||
QList<Feed*>feeds_for_update;
|
QList<Feed*>feeds_for_update;
|
||||||
|
|
||||||
foreach (Feed* feed, m_rootItem->getSubTreeFeeds()) {
|
foreach (Feed* feed, m_rootItem->getSubTreeFeeds()) {
|
||||||
switch (feed->autoUpdateType()) {
|
switch (feed->autoUpdateType()) {
|
||||||
case Feed::DontAutoUpdate:
|
case Feed::DontAutoUpdate:
|
||||||
// Do not auto-update this feed ever.
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case Feed::DefaultAutoUpdate:
|
// Do not auto-update this feed ever.
|
||||||
if (auto_update_now) {
|
continue;
|
||||||
feeds_for_update.append(feed);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
case Feed::DefaultAutoUpdate:
|
||||||
|
|
||||||
case Feed::SpecificAutoUpdate:
|
if (auto_update_now) {
|
||||||
default:
|
feeds_for_update.append(feed);
|
||||||
int remaining_interval = feed->autoUpdateRemainingInterval();
|
}
|
||||||
|
|
||||||
if (--remaining_interval <= 0) {
|
break;
|
||||||
// Interval of this feed passed, include this feed in the output list
|
|
||||||
// and reset the interval.
|
|
||||||
feeds_for_update.append(feed);
|
|
||||||
feed->setAutoUpdateRemainingInterval(feed->autoUpdateInitialInterval());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Interval did not pass, set new decremented interval and do NOT
|
|
||||||
// include this feed in the output list.
|
|
||||||
feed->setAutoUpdateRemainingInterval(remaining_interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
case Feed::SpecificAutoUpdate:
|
||||||
}
|
default:
|
||||||
}
|
int remaining_interval = feed->autoUpdateRemainingInterval();
|
||||||
|
|
||||||
return feeds_for_update;
|
if (--remaining_interval <= 0) {
|
||||||
|
// Interval of this feed passed, include this feed in the output list
|
||||||
|
// and reset the interval.
|
||||||
|
feeds_for_update.append(feed);
|
||||||
|
feed->setAutoUpdateRemainingInterval(feed->autoUpdateInitialInterval());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Interval did not pass, set new decremented interval and do NOT
|
||||||
|
// include this feed in the output list.
|
||||||
|
feed->setAutoUpdateRemainingInterval(remaining_interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return feeds_for_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Message>FeedsModel::messagesForItem(RootItem* item) const {
|
QList<Message>FeedsModel::messagesForItem(RootItem* item) const {
|
||||||
return item->undeletedMessages();
|
return item->undeletedMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RootItem* FeedsModel::itemForIndex(const QModelIndex& index) const {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex FeedsModel::indexForItem(const RootItem* item) const {
|
QModelIndex FeedsModel::indexForItem(const RootItem* item) const {
|
||||||
if (item == nullptr || item->kind() == RootItemKind::Root) {
|
if (item == nullptr || item->kind() == RootItemKind::Root) {
|
||||||
// Root item lies on invalid index.
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStack<const RootItem*>chain;
|
// Root item lies on invalid index.
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
while (item->kind() != RootItemKind::Root) {
|
QStack<const RootItem*>chain;
|
||||||
chain.push(item);
|
|
||||||
item = item->parent();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now, we have complete chain list: parent --- ..... --- parent --- leaf (item).
|
while (item->kind() != RootItemKind::Root) {
|
||||||
QModelIndex target_index = indexForItem(m_rootItem);
|
chain.push(item);
|
||||||
|
item = item->parent();
|
||||||
|
}
|
||||||
|
|
||||||
// We go through the stack and create our target index.
|
// Now, we have complete chain list: parent --- ..... --- parent --- leaf (item).
|
||||||
while (!chain.isEmpty()) {
|
QModelIndex target_index = indexForItem(m_rootItem);
|
||||||
const RootItem* parent_item = chain.pop();
|
|
||||||
target_index = index(parent_item->parent()->childItems().indexOf(const_cast<RootItem* const>(parent_item)), 0, target_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
return target_index;
|
// We go through the stack and create our target index.
|
||||||
|
while (!chain.isEmpty()) {
|
||||||
|
const RootItem* parent_item = chain.pop();
|
||||||
|
|
||||||
|
target_index = index(parent_item->parent()->childItems().indexOf(const_cast<RootItem* const>(parent_item)),
|
||||||
|
0,
|
||||||
|
target_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return target_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedsModel::hasAnyFeedNewMessages() const {
|
bool FeedsModel::hasAnyFeedNewMessages() const {
|
||||||
foreach (const Feed* feed, m_rootItem->getSubTreeFeeds()) {
|
foreach (const Feed* feed, m_rootItem->getSubTreeFeeds()) {
|
||||||
if (feed->status() == Feed::NewMessages) {
|
if (feed->status() == Feed::NewMessages) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootItem* FeedsModel::rootItem() const {
|
RootItem* FeedsModel::rootItem() const {
|
||||||
return m_rootItem;
|
return m_rootItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::reloadChangedLayout(QModelIndexList list) {
|
void FeedsModel::reloadChangedLayout(QModelIndexList list) {
|
||||||
while (!list.isEmpty()) {
|
while (!list.isEmpty()) {
|
||||||
QModelIndex indx = list.takeFirst();
|
QModelIndex indx = list.takeFirst();
|
||||||
|
|
||||||
if (indx.isValid()) {
|
if (indx.isValid()) {
|
||||||
QModelIndex indx_parent = indx.parent();
|
QModelIndex indx_parent = indx.parent();
|
||||||
// Underlying data are changed.
|
|
||||||
emit dataChanged(index(indx.row(), 0, indx_parent), index(indx.row(), FDS_MODEL_COUNTS_INDEX, indx_parent));
|
// Underlying data are changed.
|
||||||
list.append(indx_parent);
|
emit dataChanged(index(indx.row(), 0, indx_parent), index(indx.row(), FDS_MODEL_COUNTS_INDEX, indx_parent));
|
||||||
}
|
|
||||||
}
|
list.append(indx_parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::reloadChangedItem(RootItem* item) {
|
void FeedsModel::reloadChangedItem(RootItem* item) {
|
||||||
QModelIndex index_item = indexForItem(item);
|
reloadChangedLayout(QModelIndexList() << indexForItem(item));
|
||||||
reloadChangedLayout(QModelIndexList() << index_item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::notifyWithCounts() {
|
void FeedsModel::notifyWithCounts() {
|
||||||
emit messageCountsChanged(countOfUnreadMessages(), hasAnyFeedNewMessages());
|
emit messageCountsChanged(countOfUnreadMessages(), hasAnyFeedNewMessages());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::onItemDataChanged(const QList<RootItem*>& items) {
|
void FeedsModel::onItemDataChanged(const QList<RootItem*>& items) {
|
||||||
if (items.size() > RELOAD_MODEL_BORDER_NUM) {
|
if (items.size() > RELOAD_MODEL_BORDER_NUM) {
|
||||||
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());
|
||||||
|
|
||||||
foreach (RootItem* item, items) {
|
foreach (RootItem* item, items) {
|
||||||
reloadChangedItem(item);
|
reloadChangedItem(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyWithCounts();
|
notifyWithCounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::reloadWholeLayout() {
|
void FeedsModel::reloadWholeLayout() {
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
m_rootItem->appendChild(root);
|
beginInsertRows(indexForItem(m_rootItem), new_row_index, new_row_index);
|
||||||
endInsertRows();
|
m_rootItem->appendChild(root);
|
||||||
// Connect.
|
endInsertRows();
|
||||||
connect(root, &ServiceRoot::itemRemovalRequested, this, static_cast<void (FeedsModel::*)(RootItem*)>(&FeedsModel::removeItem));
|
|
||||||
connect(root, &ServiceRoot::itemReassignmentRequested, this, &FeedsModel::reassignNodeToNewParent);
|
// Connect.
|
||||||
connect(root, &ServiceRoot::dataChanged, this, &FeedsModel::onItemDataChanged);
|
connect(root, &ServiceRoot::itemRemovalRequested, this, static_cast<void (FeedsModel::*)(RootItem*)>(&FeedsModel::removeItem));
|
||||||
connect(root, &ServiceRoot::reloadMessageListRequested, this, &FeedsModel::reloadMessageListRequested);
|
connect(root, &ServiceRoot::itemReassignmentRequested, this, &FeedsModel::reassignNodeToNewParent);
|
||||||
connect(root, &ServiceRoot::itemExpandRequested, this, &FeedsModel::itemExpandRequested);
|
connect(root, &ServiceRoot::dataChanged, this, &FeedsModel::onItemDataChanged);
|
||||||
connect(root, &ServiceRoot::itemExpandStateSaveRequested, this, &FeedsModel::itemExpandStateSaveRequested);
|
connect(root, &ServiceRoot::reloadMessageListRequested, this, &FeedsModel::reloadMessageListRequested);
|
||||||
root->start(freshly_activated);
|
connect(root, &ServiceRoot::itemExpandRequested, this, &FeedsModel::itemExpandRequested);
|
||||||
return true;
|
connect(root, &ServiceRoot::itemExpandStateSaveRequested, this, &FeedsModel::itemExpandStateSaveRequested);
|
||||||
|
root->start(freshly_activated);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedsModel::restoreAllBins() {
|
bool FeedsModel::restoreAllBins() {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
foreach (ServiceRoot* root, serviceRoots()) {
|
foreach (ServiceRoot* root, serviceRoots()) {
|
||||||
RecycleBin* bin_of_root = root->recycleBin();
|
RecycleBin* bin_of_root = root->recycleBin();
|
||||||
|
|
||||||
if (bin_of_root != nullptr) {
|
if (bin_of_root != nullptr) {
|
||||||
result &= bin_of_root->restore();
|
result &= bin_of_root->restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedsModel::emptyAllBins() {
|
bool FeedsModel::emptyAllBins() {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
foreach (ServiceRoot* root, serviceRoots()) {
|
foreach (ServiceRoot* root, serviceRoots()) {
|
||||||
RecycleBin* bin_of_root = root->recycleBin();
|
RecycleBin* bin_of_root = root->recycleBin();
|
||||||
|
|
||||||
if (bin_of_root != nullptr) {
|
if (bin_of_root != nullptr) {
|
||||||
result &= bin_of_root->empty();
|
result &= bin_of_root->empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::loadActivatedServiceAccounts() {
|
void FeedsModel::loadActivatedServiceAccounts() {
|
||||||
// Iterate all globally available feed "service plugins".
|
// Iterate all globally available feed "service plugins".
|
||||||
foreach (const ServiceEntryPoint* entry_point, qApp->feedReader()->feedServices()) {
|
foreach (const ServiceEntryPoint* entry_point, qApp->feedReader()->feedServices()) {
|
||||||
// Load all stored root nodes from the entry point and add those to the model.
|
// Load all stored root nodes from the entry point and add those to the model.
|
||||||
QList<ServiceRoot*>roots = entry_point->initializeSubtree();
|
QList<ServiceRoot*>roots = entry_point->initializeSubtree();
|
||||||
|
|
||||||
foreach (ServiceRoot* root, roots) {
|
foreach (ServiceRoot* root, roots) {
|
||||||
addServiceAccount(root, false);
|
addServiceAccount(root, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serviceRoots().isEmpty()) {
|
if (serviceRoots().isEmpty()) {
|
||||||
QTimer::singleShot(2000, [this]() {
|
QTimer::singleShot(2000, [this]() {
|
||||||
addServiceAccount(StandardServiceEntryPoint().createNewRoot(), true);
|
addServiceAccount(StandardServiceEntryPoint().createNewRoot(), true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsModel::stopServiceAccounts() {
|
void FeedsModel::stopServiceAccounts() {
|
||||||
foreach (ServiceRoot* account, serviceRoots()) {
|
foreach (ServiceRoot* account, serviceRoots()) {
|
||||||
account->stop();
|
account->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Feed*>FeedsModel::feedsForIndex(const QModelIndex& index) const {
|
QList<Feed*>FeedsModel::feedsForIndex(const QModelIndex& index) const {
|
||||||
return itemForIndex(index)->getSubTreeFeeds();
|
return itemForIndex(index)->getSubTreeFeeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedsModel::markItemRead(RootItem* item, RootItem::ReadStatus read) {
|
bool FeedsModel::markItemRead(RootItem* item, RootItem::ReadStatus read) {
|
||||||
return item->markAsReadUnread(read);
|
return item->markAsReadUnread(read);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedsModel::markItemCleared(RootItem* item, bool clean_read_only) {
|
bool FeedsModel::markItemCleared(RootItem* item, bool clean_read_only) {
|
||||||
return item->cleanMessages(clean_read_only);
|
return item->cleanMessages(clean_read_only);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -20,7 +21,6 @@
|
|||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
#include "core/message.h"
|
|
||||||
#include "services/abstract/rootitem.h"
|
#include "services/abstract/rootitem.h"
|
||||||
|
|
||||||
class Category;
|
class Category;
|
||||||
@ -30,153 +30,152 @@ class ServiceEntryPoint;
|
|||||||
class StandardServiceRoot;
|
class StandardServiceRoot;
|
||||||
|
|
||||||
class FeedsModel : public QAbstractItemModel {
|
class FeedsModel : public QAbstractItemModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructors and destructors.
|
explicit FeedsModel(QObject* parent = 0);
|
||||||
explicit FeedsModel(QObject* parent = 0);
|
virtual ~FeedsModel();
|
||||||
virtual ~FeedsModel();
|
|
||||||
|
|
||||||
// Model implementation.
|
// Model implementation.
|
||||||
inline QVariant data(const QModelIndex& index, int role) const {
|
inline QVariant data(const QModelIndex& index, int role) const {
|
||||||
// Return data according to item.
|
// Return data according to item.
|
||||||
return itemForIndex(index)->data(index.column(), role);
|
return itemForIndex(index)->data(index.column(), role);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drag & drop.
|
// Drag & drop.
|
||||||
QMimeData* mimeData(const QModelIndexList& indexes) const;
|
QMimeData* mimeData(const QModelIndexList& indexes) const;
|
||||||
QStringList mimeTypes() const;
|
|
||||||
bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
|
|
||||||
Qt::DropActions supportedDropActions() const;
|
|
||||||
Qt::ItemFlags flags(const QModelIndex& index) const;
|
|
||||||
|
|
||||||
// Other subclassed methods.
|
QStringList mimeTypes() const;
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
|
||||||
QModelIndex index(int row, int column, const QModelIndex& parent) const;
|
Qt::DropActions supportedDropActions() const;
|
||||||
QModelIndex parent(const QModelIndex& child) const;
|
Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||||
int columnCount(const QModelIndex& parent) const;
|
|
||||||
int rowCount(const QModelIndex& parent) const;
|
|
||||||
|
|
||||||
// Returns counts of ALL/UNREAD (non-deleted) messages for the model.
|
// Other subclassed methods.
|
||||||
int countOfAllMessages() const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
int countOfUnreadMessages() const;
|
QModelIndex index(int row, int column, const QModelIndex& parent) const;
|
||||||
|
QModelIndex parent(const QModelIndex& child) const;
|
||||||
|
int columnCount(const QModelIndex& parent) const;
|
||||||
|
int rowCount(const QModelIndex& parent) const;
|
||||||
|
|
||||||
// Returns all activated service roots.
|
// Returns counts of ALL/UNREAD (non-deleted) messages for the model.
|
||||||
// NOTE: Service root nodes are lying directly UNDER
|
int countOfAllMessages() const;
|
||||||
// the model root item.
|
int countOfUnreadMessages() const;
|
||||||
QList<ServiceRoot*>serviceRoots() const;
|
|
||||||
|
|
||||||
// Determines if there is any account activated from given entry point.
|
// Returns all activated service roots.
|
||||||
bool containsServiceRootFromEntryPoint(const ServiceEntryPoint* point) const;
|
// NOTE: Service root nodes are lying directly UNDER
|
||||||
|
// the model root item.
|
||||||
|
QList<ServiceRoot*>serviceRoots() const;
|
||||||
|
|
||||||
// Direct and the only global accessor to standard service root.
|
// Determines if there is any account activated from given entry point.
|
||||||
StandardServiceRoot* standardServiceRoot() const;
|
bool containsServiceRootFromEntryPoint(const ServiceEntryPoint* point) const;
|
||||||
|
|
||||||
// Returns the list of feeds which should be updated
|
// Direct and the only global accessor to standard service root.
|
||||||
// according to auto-update schedule.
|
StandardServiceRoot* standardServiceRoot() const;
|
||||||
// Variable "auto_update_now" is true, when global timeout
|
|
||||||
// for scheduled auto-update was met and global auto-update strategy is enabled
|
|
||||||
// so feeds with "default" auto-update strategy should be updated.
|
|
||||||
//
|
|
||||||
// This method might change some properties of some feeds.
|
|
||||||
QList<Feed*>feedsForScheduledUpdate(bool auto_update_now);
|
|
||||||
|
|
||||||
// Returns (undeleted) messages for given feeds.
|
// Returns the list of feeds which should be updated
|
||||||
// This is usually used for displaying whole feeds
|
// according to auto-update schedule.
|
||||||
// in "newspaper" mode.
|
// Variable "auto_update_now" is true, when global timeout
|
||||||
QList<Message>messagesForItem(RootItem* item) const;
|
// for scheduled auto-update was met and global auto-update strategy is enabled
|
||||||
|
// so feeds with "default" auto-update strategy should be updated.
|
||||||
|
//
|
||||||
|
// This method might change some properties of some feeds.
|
||||||
|
QList<Feed*>feedsForScheduledUpdate(bool auto_update_now);
|
||||||
|
|
||||||
// Returns ALL RECURSIVE CHILD feeds contained within single index.
|
// Returns (undeleted) messages for given feeds.
|
||||||
QList<Feed*>feedsForIndex(const QModelIndex& index) const;
|
// This is usually used for displaying whole feeds
|
||||||
|
// in "newspaper" mode.
|
||||||
|
QList<Message>messagesForItem(RootItem* item) const;
|
||||||
|
|
||||||
// Returns feed/category which lies at the specified index or
|
// Returns ALL RECURSIVE CHILD feeds contained within single index.
|
||||||
// root item if index is invalid.
|
QList<Feed*>feedsForIndex(const QModelIndex& index) const;
|
||||||
RootItem* itemForIndex(const QModelIndex& index) const;
|
|
||||||
|
|
||||||
// Returns source QModelIndex on which lies given item.
|
// Returns feed/category which lies at the specified index or
|
||||||
// NOTE: This goes through all available indexes and
|
// root item if index is invalid.
|
||||||
// checks their bound items manually, there is no
|
RootItem* itemForIndex(const QModelIndex& index) const;
|
||||||
// other way to to this.
|
|
||||||
QModelIndex indexForItem(const RootItem* item) const;
|
|
||||||
|
|
||||||
// Determines if any feed has any new messages.
|
// Returns source QModelIndex on which lies given item.
|
||||||
bool hasAnyFeedNewMessages() const;
|
// NOTE: This goes through all available indexes and
|
||||||
|
// checks their bound items manually, there is no
|
||||||
|
// other way to to this.
|
||||||
|
QModelIndex indexForItem(const RootItem* item) const;
|
||||||
|
|
||||||
// Access to root item.
|
// Determines if any feed has any new messages.
|
||||||
RootItem* rootItem() const;
|
bool hasAnyFeedNewMessages() const;
|
||||||
|
|
||||||
public slots:
|
// Access to root item.
|
||||||
// Loads feed/categories from the database.
|
RootItem* rootItem() const;
|
||||||
void loadActivatedServiceAccounts();
|
|
||||||
|
|
||||||
// Stops all accounts before exit.
|
public slots:
|
||||||
void stopServiceAccounts();
|
void loadActivatedServiceAccounts();
|
||||||
|
|
||||||
// Reloads counts of all feeds/categories/whatever in the model.
|
// Stops all accounts before exit.
|
||||||
void reloadCountsOfWholeModel();
|
void stopServiceAccounts();
|
||||||
|
|
||||||
// Checks if new parent node is different from one used by original node.
|
// Reloads counts of all feeds/categories/whatever in the model.
|
||||||
// If it is, then it reassigns original_node to new parent.
|
void reloadCountsOfWholeModel();
|
||||||
void reassignNodeToNewParent(RootItem* original_node, RootItem* new_parent);
|
|
||||||
|
|
||||||
// Adds given service root account.
|
// Checks if new parent node is different from one used by original node.
|
||||||
bool addServiceAccount(ServiceRoot* root, bool freshly_activated);
|
// If it is, then it reassigns original_node to new parent.
|
||||||
|
void reassignNodeToNewParent(RootItem* original_node, RootItem* new_parent);
|
||||||
|
|
||||||
// Removes item with given index.
|
// Adds given service root account.
|
||||||
// NOTE: Also deletes item from memory.
|
bool addServiceAccount(ServiceRoot* root, bool freshly_activated);
|
||||||
void removeItem(const QModelIndex& index);
|
|
||||||
void removeItem(RootItem* deleting_item);
|
|
||||||
|
|
||||||
// Recycle bins operations.
|
// Removes item with given index.
|
||||||
bool restoreAllBins();
|
// NOTE: Also deletes item from memory.
|
||||||
bool emptyAllBins();
|
void removeItem(const QModelIndex& index);
|
||||||
|
void removeItem(RootItem* deleting_item);
|
||||||
|
|
||||||
// Feeds operations.
|
// Recycle bins operations.
|
||||||
bool markItemRead(RootItem* item, RootItem::ReadStatus read);
|
bool restoreAllBins();
|
||||||
bool markItemCleared(RootItem* item, bool clean_read_only);
|
bool emptyAllBins();
|
||||||
|
|
||||||
// Signals that properties (probably counts)
|
// Feeds operations.
|
||||||
// of ALL items have changed.
|
bool markItemRead(RootItem* item, RootItem::ReadStatus read);
|
||||||
void reloadWholeLayout();
|
bool markItemCleared(RootItem* item, bool clean_read_only);
|
||||||
|
|
||||||
// Signals that SOME data of this model need
|
// Signals that properties (probably counts)
|
||||||
// to be reloaded by ALL attached views.
|
// of ALL items have changed.
|
||||||
// NOTE: This reloads all parent valid indexes too.
|
void reloadWholeLayout();
|
||||||
void reloadChangedLayout(QModelIndexList list);
|
|
||||||
|
|
||||||
// Invalidates data under index for the item.
|
// Signals that SOME data of this model need
|
||||||
void reloadChangedItem(RootItem* item);
|
// to be reloaded by ALL attached views.
|
||||||
|
// NOTE: This reloads all parent valid indexes too.
|
||||||
|
void reloadChangedLayout(QModelIndexList list);
|
||||||
|
|
||||||
// Notifies other components about messages
|
// Invalidates data under index for the item.
|
||||||
// counts.
|
void reloadChangedItem(RootItem* item);
|
||||||
void notifyWithCounts();
|
|
||||||
|
|
||||||
private slots:
|
// Notifies other components about messages
|
||||||
void onItemDataChanged(const QList<RootItem*>& items);
|
// counts.
|
||||||
|
void notifyWithCounts();
|
||||||
|
|
||||||
signals:
|
private slots:
|
||||||
// Emitted if counts of messages are changed.
|
void onItemDataChanged(const QList<RootItem*>& items);
|
||||||
void messageCountsChanged(int unread_messages, bool any_feed_has_unread_messages);
|
|
||||||
|
|
||||||
// Emitted if any item requested that any view should expand it.
|
signals:
|
||||||
void itemExpandRequested(QList<RootItem*>items, bool expand);
|
void messageCountsChanged(int unread_messages, bool any_feed_has_unread_messages);
|
||||||
|
|
||||||
// Emitted if any item requested that its expand states should be explicitly saved.
|
// Emitted if any item requested that any view should expand it.
|
||||||
// NOTE: Normally expand states are saved when application quits.
|
void itemExpandRequested(QList<RootItem*>items, bool expand);
|
||||||
void itemExpandStateSaveRequested(RootItem* subtree_root);
|
|
||||||
|
|
||||||
// Emitted when there is a need of reloading of displayed messages.
|
// Emitted if any item requested that its expand states should be explicitly saved.
|
||||||
void reloadMessageListRequested(bool mark_selected_messages_read);
|
// NOTE: Normally expand states are saved when application quits.
|
||||||
|
void itemExpandStateSaveRequested(RootItem* subtree_root);
|
||||||
|
|
||||||
// There was some drag/drop operation, notify view about this.
|
// Emitted when there is a need of reloading of displayed messages.
|
||||||
// NOTE: View will probably expand dropped index.
|
void reloadMessageListRequested(bool mark_selected_messages_read);
|
||||||
void requireItemValidationAfterDragDrop(const QModelIndex& source_index);
|
|
||||||
|
|
||||||
private:
|
// There was some drag/drop operation, notify view about this.
|
||||||
RootItem* m_rootItem;
|
// NOTE: View will probably expand dropped index.
|
||||||
QList<QString>m_headerData;
|
void requireItemValidationAfterDragDrop(const QModelIndex& source_index);
|
||||||
QList<QString>m_tooltipData;
|
|
||||||
QIcon m_countsIcon;
|
private:
|
||||||
|
RootItem* m_rootItem;
|
||||||
|
|
||||||
|
QList<QString> m_headerData;
|
||||||
|
QList<QString> m_tooltipData;
|
||||||
|
QIcon m_countsIcon;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FEEDSMODEL_H
|
#endif // FEEDSMODEL_H
|
||||||
|
@ -220,7 +220,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_LINUX)
|
#if defined(Q_OS_LINUX)
|
||||||
|
|
||||||
#define APP_DESKTOP_SOURCE_ENTRY_FILE "rssguard.desktop.autostart"
|
#define APP_DESKTOP_SOURCE_ENTRY_FILE "rssguard.desktop.autostart"
|
||||||
#define APP_DESKTOP_ENTRY_FILE "rssguard.desktop"
|
#define APP_DESKTOP_ENTRY_FILE "rssguard.desktop"
|
||||||
|
|
||||||
@ -233,9 +232,7 @@
|
|||||||
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/../share/pixmaps/rssguard.png")
|
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/../share/pixmaps/rssguard.png")
|
||||||
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/icons/rssguard_plain.png")
|
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/icons/rssguard_plain.png")
|
||||||
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/initial_feeds")
|
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/../share/rssguard/initial_feeds")
|
||||||
|
|
||||||
#elif defined(Q_OS_OSX)
|
#elif defined(Q_OS_OSX)
|
||||||
|
|
||||||
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/../Resources/translations")
|
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/../Resources/translations")
|
||||||
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/../Resources/skins")
|
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/../Resources/skins")
|
||||||
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../Resources/information")
|
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../Resources/information")
|
||||||
@ -245,9 +242,7 @@
|
|||||||
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../Resources/information")
|
#define APP_INFO_PATH QApplication::applicationDirPath() + QString("/../Resources/information")
|
||||||
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/../Resources/icons/rssguard_plain.png")
|
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/../Resources/icons/rssguard_plain.png")
|
||||||
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/../Resources/initial_feeds")
|
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/../Resources/initial_feeds")
|
||||||
|
|
||||||
#elif defined(Q_OS_WIN)
|
#elif defined(Q_OS_WIN)
|
||||||
|
|
||||||
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/translations")
|
#define APP_LANG_PATH QApplication::applicationDirPath() + QString("/translations")
|
||||||
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins")
|
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins")
|
||||||
#define APP_INFO_PATH QApplication::applicationDirPath()
|
#define APP_INFO_PATH QApplication::applicationDirPath()
|
||||||
@ -256,7 +251,6 @@
|
|||||||
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/rssguard.png")
|
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/rssguard.png")
|
||||||
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/rssguard_plain.png")
|
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/rssguard_plain.png")
|
||||||
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/initial_feeds")
|
#define APP_INITIAL_FEEDS_PATH QApplication::applicationDirPath() + QString("/initial_feeds")
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // DEFINITIONS_H
|
#endif // DEFINITIONS_H
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -17,95 +18,85 @@
|
|||||||
|
|
||||||
#include "gui/dialogs/formabout.h"
|
#include "gui/dialogs/formabout.h"
|
||||||
|
|
||||||
#include "miscellaneous/iconfactory.h"
|
|
||||||
#include "miscellaneous/textfactory.h"
|
|
||||||
#include "miscellaneous/settingsproperties.h"
|
|
||||||
#include "gui/guiutilities.h"
|
|
||||||
#include "exceptions/applicationexception.h"
|
#include "exceptions/applicationexception.h"
|
||||||
|
#include "gui/guiutilities.h"
|
||||||
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
#include "miscellaneous/settingsproperties.h"
|
||||||
|
#include "miscellaneous/textfactory.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
|
|
||||||
FormAbout::FormAbout(QWidget* parent) : QDialog(parent) {
|
FormAbout::FormAbout(QWidget* parent) : QDialog(parent) {
|
||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
m_ui.m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH));
|
m_ui.m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH));
|
||||||
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("help-about")), tr("About %1").arg(APP_NAME));
|
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("help-about")), tr("About %1").arg(APP_NAME));
|
||||||
loadLicenseAndInformation();
|
loadLicenseAndInformation();
|
||||||
loadSettingsAndPaths();
|
loadSettingsAndPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
FormAbout::~FormAbout() {
|
FormAbout::~FormAbout() {
|
||||||
qDebug("Destroying FormAbout instance.");
|
qDebug("Destroying FormAbout instance.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormAbout::loadSettingsAndPaths() {
|
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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui.m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->userDataFolder() +
|
m_ui.m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->userDataFolder() + QDir::separator() + QString(APP_DB_SQLITE_PATH)));
|
||||||
QDir::separator() +
|
m_ui.m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName()));
|
||||||
QString(APP_DB_SQLITE_PATH)));
|
m_ui.m_txtPathsSkinsRoot->setText(QDir::toNativeSeparators(qApp->skins()->customSkinBaseFolder()));
|
||||||
m_ui.m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName()));
|
|
||||||
m_ui.m_txtPathsSkinsRoot->setText(QDir::toNativeSeparators(qApp->skins()->customSkinBaseFolder()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormAbout::loadLicenseAndInformation() {
|
void FormAbout::loadLicenseAndInformation() {
|
||||||
try {
|
try {
|
||||||
m_ui.m_txtLicenseGnu->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
|
m_ui.m_txtLicenseGnu->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
m_ui.m_txtLicenseGnu->setText(tr("License not found."));
|
m_ui.m_txtLicenseGnu->setText(tr("License not found."));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_ui.m_txtLicenseGnu->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
|
m_ui.m_txtLicenseGnu->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
m_ui.m_txtLicenseGnu->setText(tr("License not found."));
|
m_ui.m_txtLicenseGnu->setText(tr("License not found."));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_ui.m_txtChangelog->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/CHANGELOG")));
|
m_ui.m_txtChangelog->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/CHANGELOG")));
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
m_ui.m_txtChangelog->setText(tr("Changelog not found."));
|
m_ui.m_txtChangelog->setText(tr("Changelog not found."));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_ui.m_txtLicenseBsd->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_BSD")));
|
m_ui.m_txtLicenseBsd->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_BSD")));
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
m_ui.m_txtLicenseBsd->setText(tr("License not found."));
|
m_ui.m_txtLicenseBsd->setText(tr("License not found."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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>Revision:</b> %4<br>" "<b>Build date:</b> %5<br>"
|
||||||
"<b>Version:</b> %1 (built on %2/%3)<br>"
|
"<b>Qt:</b> %6 (compiled against %7)<br>").arg(
|
||||||
"<b>Revision:</b> %4<br>"
|
qApp->applicationVersion(), APP_SYSTEM_NAME, APP_SYSTEM_VERSION, APP_REVISION,
|
||||||
"<b>Build date:</b> %5<br>"
|
TextFactory
|
||||||
"<b>Qt:</b> %6 (compiled against %7)<br>").arg(qApp->applicationVersion(),
|
::parseDateTime(QString("%1 %2").arg(__DATE__, __TIME__)).toString(Qt::DefaultLocaleShortDate),
|
||||||
APP_SYSTEM_NAME,
|
qVersion(), QT_VERSION_STR,
|
||||||
APP_SYSTEM_VERSION,
|
APP_NAME));
|
||||||
APP_REVISION,
|
m_ui.m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader."
|
||||||
TextFactory::parseDateTime(QString("%1 %2").arg(__DATE__,
|
"<br><br>This software is distributed under the terms of GNU General Public License, version 3."
|
||||||
__TIME__)).toString(Qt::DefaultLocaleShortDate),
|
"<br><br>Contacts:"
|
||||||
qVersion(),
|
"<ul><li><a href=\"mailto://%1\">%1</a> ~e-mail</li>"
|
||||||
QT_VERSION_STR,
|
"<li><a href=\"%2\">%2</a> ~website</li></ul>"
|
||||||
APP_NAME));
|
"You can obtain source code for %5 from its website."
|
||||||
m_ui.m_txtInfo->setText(tr("<body>%5 is a (very) tiny feed reader."
|
"<br><br><br>Copyright (C) 2011-%3 %4</body>").arg(APP_EMAIL, APP_URL,
|
||||||
"<br><br>This software is distributed under the terms of GNU General Public License, version 3."
|
QString
|
||||||
"<br><br>Contacts:"
|
::number(QDateTime::currentDateTime().date().year()),
|
||||||
"<ul><li><a href=\"mailto://%1\">%1</a> ~e-mail</li>"
|
APP_AUTHOR, APP_NAME));
|
||||||
"<li><a href=\"%2\">%2</a> ~website</li></ul>"
|
|
||||||
"You can obtain source code for %5 from its website."
|
|
||||||
"<br><br><br>Copyright (C) 2011-%3 %4</body>").arg(APP_EMAIL,
|
|
||||||
APP_URL,
|
|
||||||
QString::number(QDateTime::currentDateTime().date().year()),
|
|
||||||
APP_AUTHOR,
|
|
||||||
APP_NAME));
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -17,118 +18,113 @@
|
|||||||
|
|
||||||
#include "gui/dialogs/formrestoredatabasesettings.h"
|
#include "gui/dialogs/formrestoredatabasesettings.h"
|
||||||
|
|
||||||
#include "gui/messagebox.h"
|
|
||||||
#include "gui/dialogs/formmain.h"
|
|
||||||
#include "miscellaneous/iconfactory.h"
|
|
||||||
#include "exceptions/applicationexception.h"
|
#include "exceptions/applicationexception.h"
|
||||||
|
#include "gui/dialogs/formmain.h"
|
||||||
|
#include "gui/messagebox.h"
|
||||||
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
|
||||||
#include "QFileDialog"
|
#include "QFileDialog"
|
||||||
|
|
||||||
|
FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget& parent) : QDialog(&parent),
|
||||||
FormRestoreDatabaseSettings::FormRestoreDatabaseSettings(QWidget& parent)
|
m_shouldRestart(false) {
|
||||||
: QDialog(&parent), 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();
|
});
|
||||||
});
|
connect(m_ui.m_btnSelectFolder, SIGNAL(clicked()), this, SLOT(selectFolder()));
|
||||||
connect(m_ui.m_btnSelectFolder, SIGNAL(clicked()), this, SLOT(selectFolder()));
|
connect(m_ui.m_groupDatabase, SIGNAL(toggled(bool)), this, SLOT(checkOkButton()));
|
||||||
connect(m_ui.m_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->documentsFolder());
|
||||||
selectFolder(qApp->documentsFolder());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FormRestoreDatabaseSettings::~FormRestoreDatabaseSettings() {
|
FormRestoreDatabaseSettings::~FormRestoreDatabaseSettings() {
|
||||||
qDebug("Destroying FormRestoreDatabaseSettings instance.");
|
qDebug("Destroying FormRestoreDatabaseSettings instance.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormRestoreDatabaseSettings::performRestoration() {
|
void FormRestoreDatabaseSettings::performRestoration() {
|
||||||
m_ui.m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
m_ui.m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
qApp->restoreDatabaseSettings(m_ui.m_groupDatabase->isChecked(),
|
qApp->restoreDatabaseSettings(m_ui.m_groupDatabase->isChecked(),
|
||||||
m_ui.m_groupSettings->isChecked(),
|
m_ui.m_groupSettings->isChecked(),
|
||||||
m_ui.m_listDatabase->currentRow() >= 0 ?
|
m_ui.m_listDatabase->currentRow() >= 0 ? m_ui.m_listDatabase->currentItem()->data(
|
||||||
m_ui.m_listDatabase->currentItem()->data(Qt::UserRole).toString() :
|
Qt::UserRole).toString() : QString(),
|
||||||
QString(),
|
m_ui.m_listSettings->currentRow() >= 0 ? m_ui.m_listSettings->currentItem()->data(
|
||||||
m_ui.m_listSettings->currentRow() >= 0 ?
|
Qt::UserRole).toString() : QString());
|
||||||
m_ui.m_listSettings->currentItem()->data(Qt::UserRole).toString() :
|
m_btnRestart->setEnabled(true);
|
||||||
QString());
|
m_ui.m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Restoration was initiated. Restart to proceed."),
|
||||||
m_btnRestart->setEnabled(true);
|
tr("You need to restart application for restoration process to finish."));
|
||||||
m_ui.m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Restoration was initiated. Restart to proceed."),
|
}
|
||||||
tr("You need to restart application for restoration process to finish."));
|
catch (const ApplicationException& ex) {
|
||||||
}
|
m_ui.m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(),
|
||||||
catch (const ApplicationException& ex) {
|
tr("Database and/or settings were not copied to restoration directory successully."));
|
||||||
m_ui.m_lblResult->setStatus(WidgetWithStatus::Error, ex.message(),
|
}
|
||||||
tr("Database and/or settings were not copied to restoration directory successully."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormRestoreDatabaseSettings::checkOkButton() {
|
void FormRestoreDatabaseSettings::checkOkButton() {
|
||||||
m_btnRestart->setEnabled(false);
|
m_btnRestart->setEnabled(false);
|
||||||
m_ui.m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!m_ui.m_lblSelectFolder->label()->text().isEmpty() &&
|
m_ui.m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!m_ui.m_lblSelectFolder->label()->text().isEmpty() &&
|
||||||
((m_ui.m_groupDatabase->isChecked() &&
|
((m_ui.m_groupDatabase->isChecked() &&
|
||||||
m_ui.m_listDatabase->currentRow() >= 0) ||
|
m_ui.m_listDatabase->currentRow() >= 0) ||
|
||||||
(m_ui.m_groupSettings->isChecked() &&
|
(m_ui.m_groupSettings->isChecked() &&
|
||||||
m_ui.m_listSettings->currentRow() >= 0)));
|
m_ui.m_listSettings->currentRow() >= 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormRestoreDatabaseSettings::selectFolderWithGui() {
|
void FormRestoreDatabaseSettings::selectFolderWithGui() {
|
||||||
selectFolder();
|
selectFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormRestoreDatabaseSettings::selectFolder(QString folder) {
|
void FormRestoreDatabaseSettings::selectFolder(QString folder) {
|
||||||
if (folder.isEmpty()) {
|
if (folder.isEmpty()) {
|
||||||
folder = QFileDialog::getExistingDirectory(this, tr("Select source directory"), m_ui.m_lblSelectFolder->label()->text());
|
folder = QFileDialog::getExistingDirectory(this, tr("Select source directory"), m_ui.m_lblSelectFolder->label()->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!folder.isEmpty()) {
|
if (!folder.isEmpty()) {
|
||||||
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;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const QDir selected_folder(folder);
|
const QDir selected_folder(folder);
|
||||||
const QFileInfoList available_databases = selected_folder.entryInfoList(QStringList()
|
const QFileInfoList available_databases = selected_folder.entryInfoList(QStringList() << QString("*") + BACKUP_SUFFIX_DATABASE,
|
||||||
<< QString("*") + BACKUP_SUFFIX_DATABASE,
|
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable | QDir::CaseSensitive | QDir::NoSymLinks,
|
||||||
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable |
|
QDir::Name);
|
||||||
QDir::CaseSensitive | QDir::NoSymLinks,
|
const QFileInfoList available_settings = selected_folder.entryInfoList(QStringList() << QString("*") + BACKUP_SUFFIX_SETTINGS,
|
||||||
QDir::Name);
|
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable | QDir::CaseSensitive | QDir::NoSymLinks,
|
||||||
const QFileInfoList available_settings = selected_folder.entryInfoList(QStringList()
|
QDir::Name);
|
||||||
<< QString("*") + BACKUP_SUFFIX_SETTINGS,
|
|
||||||
QDir::Files | QDir::NoDotAndDotDot | QDir::Readable |
|
|
||||||
QDir::CaseSensitive | QDir::NoSymLinks,
|
|
||||||
QDir::Name);
|
|
||||||
m_ui.m_listDatabase->clear();
|
|
||||||
m_ui.m_listSettings->clear();
|
|
||||||
|
|
||||||
foreach (const QFileInfo& database_file, available_databases) {
|
m_ui.m_listDatabase->clear();
|
||||||
QListWidgetItem* database_item = new QListWidgetItem(database_file.fileName(), m_ui.m_listDatabase);
|
m_ui.m_listSettings->clear();
|
||||||
database_item->setData(Qt::UserRole, database_file.absoluteFilePath());
|
|
||||||
database_item->setToolTip(QDir::toNativeSeparators(database_file.absoluteFilePath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const QFileInfo& settings_file, available_settings) {
|
foreach (const QFileInfo& database_file, available_databases) {
|
||||||
QListWidgetItem* settings_item = new QListWidgetItem(settings_file.fileName(), m_ui.m_listSettings);
|
QListWidgetItem* database_item = new QListWidgetItem(database_file.fileName(), m_ui.m_listDatabase);
|
||||||
settings_item->setData(Qt::UserRole, settings_file.absoluteFilePath());
|
|
||||||
settings_item->setToolTip(QDir::toNativeSeparators(settings_file.absoluteFilePath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!available_databases.isEmpty()) {
|
database_item->setData(Qt::UserRole, database_file.absoluteFilePath());
|
||||||
m_ui.m_listDatabase->setCurrentRow(0);
|
database_item->setToolTip(QDir::toNativeSeparators(database_file.absoluteFilePath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!available_settings.isEmpty()) {
|
foreach (const QFileInfo& settings_file, available_settings) {
|
||||||
m_ui.m_listSettings->setCurrentRow(0);
|
QListWidgetItem* settings_item = new QListWidgetItem(settings_file.fileName(), m_ui.m_listSettings);
|
||||||
}
|
|
||||||
|
|
||||||
m_ui.m_groupDatabase->setChecked(!available_databases.isEmpty());
|
settings_item->setData(Qt::UserRole, settings_file.absoluteFilePath());
|
||||||
m_ui.m_groupSettings->setChecked(!available_settings.isEmpty());
|
settings_item->setToolTip(QDir::toNativeSeparators(settings_file.absoluteFilePath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!available_databases.isEmpty()) {
|
||||||
|
m_ui.m_listDatabase->setCurrentRow(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!available_settings.isEmpty()) {
|
||||||
|
m_ui.m_listSettings->setCurrentRow(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ui.m_groupDatabase->setChecked(!available_databases.isEmpty());
|
||||||
|
m_ui.m_groupSettings->setChecked(!available_settings.isEmpty());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -17,30 +18,30 @@
|
|||||||
|
|
||||||
#include "gui/feedmessageviewer.h"
|
#include "gui/feedmessageviewer.h"
|
||||||
|
|
||||||
#include "miscellaneous/settings.h"
|
|
||||||
#include "miscellaneous/databasefactory.h"
|
|
||||||
#include "miscellaneous/systemfactory.h"
|
|
||||||
#include "miscellaneous/iconfactory.h"
|
|
||||||
#include "miscellaneous/mutex.h"
|
|
||||||
#include "miscellaneous/databasecleaner.h"
|
|
||||||
#include "miscellaneous/feedreader.h"
|
|
||||||
#include "core/messagesproxymodel.h"
|
|
||||||
#include "core/feeddownloader.h"
|
#include "core/feeddownloader.h"
|
||||||
#include "core/feedsproxymodel.h"
|
#include "core/feedsproxymodel.h"
|
||||||
#include "services/standard/standardserviceroot.h"
|
#include "core/messagesproxymodel.h"
|
||||||
#include "services/standard/standardfeed.h"
|
#include "gui/feedstoolbar.h"
|
||||||
#include "services/standard/standardfeedsimportexportmodel.h"
|
|
||||||
#include "gui/messagesview.h"
|
|
||||||
#include "gui/feedsview.h"
|
#include "gui/feedsview.h"
|
||||||
#include "gui/statusbar.h"
|
|
||||||
#include "gui/systemtrayicon.h"
|
|
||||||
#include "gui/messagebox.h"
|
#include "gui/messagebox.h"
|
||||||
#include "gui/messagestoolbar.h"
|
#include "gui/messagestoolbar.h"
|
||||||
#include "gui/feedstoolbar.h"
|
#include "gui/messagesview.h"
|
||||||
|
#include "gui/statusbar.h"
|
||||||
|
#include "gui/systemtrayicon.h"
|
||||||
|
#include "miscellaneous/databasecleaner.h"
|
||||||
|
#include "miscellaneous/databasefactory.h"
|
||||||
|
#include "miscellaneous/feedreader.h"
|
||||||
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
#include "miscellaneous/mutex.h"
|
||||||
|
#include "miscellaneous/settings.h"
|
||||||
|
#include "miscellaneous/systemfactory.h"
|
||||||
|
#include "services/standard/standardfeed.h"
|
||||||
|
#include "services/standard/standardfeedsimportexportmodel.h"
|
||||||
|
#include "services/standard/standardserviceroot.h"
|
||||||
|
|
||||||
|
#include "exceptions/applicationexception.h"
|
||||||
#include "gui/dialogs/formdatabasecleanup.h"
|
#include "gui/dialogs/formdatabasecleanup.h"
|
||||||
#include "gui/dialogs/formmain.h"
|
#include "gui/dialogs/formmain.h"
|
||||||
#include "exceptions/applicationexception.h"
|
|
||||||
|
|
||||||
#if defined(USE_WEBENGINE)
|
#if defined(USE_WEBENGINE)
|
||||||
#include "gui/webbrowser.h"
|
#include "gui/webbrowser.h"
|
||||||
@ -48,236 +49,246 @@
|
|||||||
#include "gui/messagepreviewer.h"
|
#include "gui/messagepreviewer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
#include <QAction>
|
||||||
#include <QSplitter>
|
|
||||||
#include <QToolBar>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QAction>
|
|
||||||
#include <QToolButton>
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QWidgetAction>
|
|
||||||
#include <QThread>
|
|
||||||
#include <QProgressBar>
|
|
||||||
#include <QStatusBar>
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
#include <QProgressBar>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QStatusBar>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QWidgetAction>
|
||||||
|
|
||||||
|
FeedMessageViewer::FeedMessageViewer(QWidget* parent) : TabContent(parent), m_toolBarsEnabled(true), m_listHeadersEnabled(true),
|
||||||
|
m_toolBarFeeds(new FeedsToolBar(tr("Toolbar for feeds"), this)), m_toolBarMessages(new MessagesToolBar(tr("Toolbar for messages"), this)),
|
||||||
|
m_messagesView(new MessagesView(this)), m_feedsView(new FeedsView(this)),
|
||||||
|
|
||||||
FeedMessageViewer::FeedMessageViewer(QWidget* parent)
|
|
||||||
: TabContent(parent),
|
|
||||||
m_toolBarsEnabled(true),
|
|
||||||
m_listHeadersEnabled(true),
|
|
||||||
m_toolBarFeeds(new FeedsToolBar(tr("Toolbar for feeds"), this)),
|
|
||||||
m_toolBarMessages(new MessagesToolBar(tr("Toolbar for messages"), this)),
|
|
||||||
m_messagesView(new MessagesView(this)),
|
|
||||||
m_feedsView(new FeedsView(this)),
|
|
||||||
#if defined(USE_WEBENGINE)
|
#if defined(USE_WEBENGINE)
|
||||||
m_messagesBrowser(new WebBrowser(this)) {
|
m_messagesBrowser(new WebBrowser(this)) {
|
||||||
#else
|
#else
|
||||||
m_messagesBrowser(new MessagePreviewer(this)) {
|
m_messagesBrowser(new MessagePreviewer(this)) {
|
||||||
#endif
|
#endif
|
||||||
initialize();
|
|
||||||
initializeViews();
|
initialize();
|
||||||
loadMessageViewerFonts();
|
initializeViews();
|
||||||
createConnections();
|
loadMessageViewerFonts();
|
||||||
|
createConnections();
|
||||||
}
|
}
|
||||||
|
|
||||||
FeedMessageViewer::~FeedMessageViewer() {
|
FeedMessageViewer::~FeedMessageViewer() {
|
||||||
qDebug("Destroying FeedMessageViewer instance.");
|
qDebug("Destroying FeedMessageViewer instance.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_WEBENGINE)
|
#if defined(USE_WEBENGINE)
|
||||||
|
|
||||||
WebBrowser* FeedMessageViewer::webBrowser() const {
|
WebBrowser* FeedMessageViewer::webBrowser() const {
|
||||||
return m_messagesBrowser;
|
return m_messagesBrowser;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FeedsView* FeedMessageViewer::feedsView() const {
|
FeedsView* FeedMessageViewer::feedsView() const {
|
||||||
return m_feedsView;
|
return m_feedsView;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessagesView* FeedMessageViewer::messagesView() const {
|
MessagesView* FeedMessageViewer::messagesView() const {
|
||||||
return m_messagesView;
|
return m_messagesView;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessagesToolBar* FeedMessageViewer::messagesToolBar() const {
|
MessagesToolBar* FeedMessageViewer::messagesToolBar() const {
|
||||||
return m_toolBarMessages;
|
return m_toolBarMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeedsToolBar* FeedMessageViewer::feedsToolBar() const {
|
FeedsToolBar* FeedMessageViewer::feedsToolBar() const {
|
||||||
return m_toolBarFeeds;
|
return m_toolBarFeeds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::saveSize() {
|
void FeedMessageViewer::saveSize() {
|
||||||
Settings* settings = qApp->settings();
|
Settings* settings = qApp->settings();
|
||||||
m_feedsView->saveAllExpandStates();
|
|
||||||
// Store offsets of splitters.
|
m_feedsView->saveAllExpandStates();
|
||||||
settings->setValue(GROUP(GUI), GUI::SplitterFeeds, QString(m_feedSplitter->saveState().toBase64()));
|
|
||||||
settings->setValue(GROUP(GUI), GUI::SplitterMessages, QString(m_messageSplitter->saveState().toBase64()));
|
// Store offsets of splitters.
|
||||||
settings->setValue(GROUP(GUI), GUI::MessageViewState, QString(m_messagesView->header()->saveState().toBase64()));
|
settings->setValue(GROUP(GUI), GUI::SplitterFeeds, QString(m_feedSplitter->saveState().toBase64()));
|
||||||
// Store "visibility" of toolbars and list headers.
|
settings->setValue(GROUP(GUI), GUI::SplitterMessages, QString(m_messageSplitter->saveState().toBase64()));
|
||||||
settings->setValue(GROUP(GUI), GUI::ToolbarsVisible, m_toolBarsEnabled);
|
settings->setValue(GROUP(GUI), GUI::MessageViewState, QString(m_messagesView->header()->saveState().toBase64()));
|
||||||
settings->setValue(GROUP(GUI), GUI::ListHeadersVisible, m_listHeadersEnabled);
|
|
||||||
|
// Store "visibility" of toolbars and list headers.
|
||||||
|
settings->setValue(GROUP(GUI), GUI::ToolbarsVisible, m_toolBarsEnabled);
|
||||||
|
settings->setValue(GROUP(GUI), GUI::ListHeadersVisible, m_listHeadersEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::loadSize() {
|
void FeedMessageViewer::loadSize() {
|
||||||
const Settings* settings = qApp->settings();
|
const Settings* settings = qApp->settings();
|
||||||
// Restore offsets of splitters.
|
|
||||||
m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::SplitterFeeds)).toString().toLocal8Bit()));
|
// Restore offsets of splitters.
|
||||||
m_messageSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI),
|
m_feedSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI), SETTING(GUI::SplitterFeeds)).toString().toLocal8Bit()));
|
||||||
SETTING(GUI::SplitterMessages)).toString().toLocal8Bit()));
|
m_messageSplitter->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI),
|
||||||
m_messagesView->header()->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI),
|
SETTING(GUI::SplitterMessages)).toString().toLocal8Bit()));
|
||||||
SETTING(GUI::MessageViewState)).toString().toLocal8Bit()));
|
m_messagesView->header()->restoreState(QByteArray::fromBase64(settings->value(GROUP(GUI),
|
||||||
|
SETTING(GUI::MessageViewState)).toString().toLocal8Bit()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::loadMessageViewerFonts() {
|
void FeedMessageViewer::loadMessageViewerFonts() {
|
||||||
m_messagesBrowser->reloadFontSettings();
|
m_messagesBrowser->reloadFontSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedMessageViewer::areToolBarsEnabled() const {
|
bool FeedMessageViewer::areToolBarsEnabled() const {
|
||||||
return m_toolBarsEnabled;
|
return m_toolBarsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FeedMessageViewer::areListHeadersEnabled() const {
|
bool FeedMessageViewer::areListHeadersEnabled() const {
|
||||||
return m_listHeadersEnabled;
|
return m_listHeadersEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::switchMessageSplitterOrientation() {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::setToolBarsEnabled(bool enable) {
|
void FeedMessageViewer::setToolBarsEnabled(bool enable) {
|
||||||
m_toolBarsEnabled = enable;
|
m_toolBarsEnabled = enable;
|
||||||
m_toolBarFeeds->setVisible(enable);
|
m_toolBarFeeds->setVisible(enable);
|
||||||
m_toolBarMessages->setVisible(enable);
|
m_toolBarMessages->setVisible(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::setListHeadersEnabled(bool enable) {
|
void FeedMessageViewer::setListHeadersEnabled(bool enable) {
|
||||||
m_listHeadersEnabled = enable;
|
m_listHeadersEnabled = enable;
|
||||||
m_feedsView->header()->setVisible(enable);
|
m_feedsView->header()->setVisible(enable);
|
||||||
m_messagesView->header()->setVisible(enable);
|
m_messagesView->header()->setVisible(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::switchFeedComponentVisibility() {
|
void FeedMessageViewer::switchFeedComponentVisibility() {
|
||||||
QAction* sen = qobject_cast<QAction*>(sender());
|
QAction* sen = qobject_cast<QAction*>(sender());
|
||||||
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::toggleShowOnlyUnreadFeeds() {
|
void FeedMessageViewer::toggleShowOnlyUnreadFeeds() {
|
||||||
const QAction* origin = qobject_cast<QAction*>(sender());
|
const QAction* origin = qobject_cast<QAction*>(sender());
|
||||||
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::createConnections() {
|
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);
|
||||||
connect(m_messagesBrowser, &WebBrowser::markMessageRead,
|
connect(m_messagesBrowser, &WebBrowser::markMessageRead, m_messagesView->sourceModel(), &MessagesModel::setMessageReadById);
|
||||||
m_messagesView->sourceModel(), &MessagesModel::setMessageReadById);
|
connect(m_messagesBrowser, &WebBrowser::markMessageImportant, m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById);
|
||||||
connect(m_messagesBrowser, &WebBrowser::markMessageImportant,
|
|
||||||
m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById);
|
|
||||||
#else
|
#else
|
||||||
connect(m_messagesView, &MessagesView::currentMessageRemoved, m_messagesBrowser, &MessagePreviewer::clear);
|
connect(m_messagesView, &MessagesView::currentMessageRemoved, m_messagesBrowser, &MessagePreviewer::clear);
|
||||||
connect(m_messagesView, &MessagesView::currentMessageChanged, m_messagesBrowser, &MessagePreviewer::loadMessage);
|
connect(m_messagesView, &MessagesView::currentMessageChanged, m_messagesBrowser, &MessagePreviewer::loadMessage);
|
||||||
connect(m_messagesBrowser, &MessagePreviewer::markMessageRead,
|
connect(m_messagesBrowser, &MessagePreviewer::markMessageRead, m_messagesView->sourceModel(), &MessagesModel::setMessageReadById);
|
||||||
m_messagesView->sourceModel(), &MessagesModel::setMessageReadById);
|
connect(m_messagesBrowser, &MessagePreviewer::markMessageImportant, m_messagesView->sourceModel(),
|
||||||
connect(m_messagesBrowser, &MessagePreviewer::markMessageImportant,
|
&MessagesModel::setMessageImportantById);
|
||||||
m_messagesView->sourceModel(), &MessagesModel::setMessageImportantById);
|
|
||||||
#endif
|
#endif
|
||||||
// If user selects feeds, load their messages.
|
|
||||||
connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem);
|
// If user selects feeds, load their messages.
|
||||||
|
connect(m_feedsView, &FeedsView::itemSelected, m_messagesView, &MessagesView::loadItem);
|
||||||
connect(m_feedsView, &FeedsView::requestViewNextUnreadMessage, m_messagesView, &MessagesView::selectNextUnreadItem);
|
connect(m_feedsView, &FeedsView::requestViewNextUnreadMessage, m_messagesView, &MessagesView::selectNextUnreadItem);
|
||||||
|
|
||||||
// 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, m_messagesView, &MessagesView::reloadSelections);
|
||||||
m_messagesView, &MessagesView::reloadSelections);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::initialize() {
|
void FeedMessageViewer::initialize() {
|
||||||
// Initialize/populate toolbars.
|
// Initialize/populate toolbars.
|
||||||
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.
|
|
||||||
refreshVisualProperties();
|
// Now refresh visual setup.
|
||||||
|
refreshVisualProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::initializeViews() {
|
void FeedMessageViewer::initializeViews() {
|
||||||
m_feedsWidget = new QWidget(this);
|
m_feedsWidget = new QWidget(this);
|
||||||
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.
|
|
||||||
QVBoxLayout* central_layout = new QVBoxLayout(this);
|
// Instantiate needed components.
|
||||||
QVBoxLayout* feed_layout = new QVBoxLayout(m_feedsWidget);
|
QVBoxLayout* central_layout = new QVBoxLayout(this);
|
||||||
QVBoxLayout* message_layout = new QVBoxLayout(m_messagesWidget);
|
QVBoxLayout* feed_layout = new QVBoxLayout(m_feedsWidget);
|
||||||
// Set layout properties.
|
QVBoxLayout* message_layout = new QVBoxLayout(m_messagesWidget);
|
||||||
central_layout->setMargin(0);
|
|
||||||
central_layout->setSpacing(0);
|
// Set layout properties.
|
||||||
feed_layout->setMargin(0);
|
central_layout->setMargin(0);
|
||||||
feed_layout->setSpacing(0);
|
central_layout->setSpacing(0);
|
||||||
message_layout->setMargin(0);
|
feed_layout->setMargin(0);
|
||||||
message_layout->setSpacing(0);
|
feed_layout->setSpacing(0);
|
||||||
// Set views.
|
message_layout->setMargin(0);
|
||||||
m_feedsView->setFrameStyle(QFrame::NoFrame);
|
message_layout->setSpacing(0);
|
||||||
m_messagesView->setFrameStyle(QFrame::NoFrame);
|
|
||||||
// Setup message splitter.
|
// Set views.
|
||||||
m_messageSplitter->setObjectName(QSL("MessageSplitter"));
|
m_feedsView->setFrameStyle(QFrame::NoFrame);
|
||||||
m_messageSplitter->setHandleWidth(1);
|
m_messagesView->setFrameStyle(QFrame::NoFrame);
|
||||||
m_messageSplitter->setOpaqueResize(false);
|
|
||||||
m_messageSplitter->setChildrenCollapsible(false);
|
// Setup message splitter.
|
||||||
m_messageSplitter->addWidget(m_messagesView);
|
m_messageSplitter->setObjectName(QSL("MessageSplitter"));
|
||||||
m_messageSplitter->addWidget(m_messagesBrowser);
|
m_messageSplitter->setHandleWidth(1);
|
||||||
// Assemble message-related components to single widget.
|
m_messageSplitter->setOpaqueResize(false);
|
||||||
message_layout->addWidget(m_toolBarMessages);
|
m_messageSplitter->setChildrenCollapsible(false);
|
||||||
message_layout->addWidget(m_messageSplitter);
|
m_messageSplitter->addWidget(m_messagesView);
|
||||||
// Assemble feed-related components to another widget.
|
m_messageSplitter->addWidget(m_messagesBrowser);
|
||||||
feed_layout->addWidget(m_toolBarFeeds);
|
|
||||||
feed_layout->addWidget(m_feedsView);
|
// Assemble message-related components to single widget.
|
||||||
// Assembler everything together.
|
message_layout->addWidget(m_toolBarMessages);
|
||||||
m_feedSplitter->setHandleWidth(1);
|
message_layout->addWidget(m_messageSplitter);
|
||||||
m_feedSplitter->setOpaqueResize(false);
|
|
||||||
m_feedSplitter->setChildrenCollapsible(false);
|
// Assemble feed-related components to another widget.
|
||||||
m_feedSplitter->addWidget(m_feedsWidget);
|
feed_layout->addWidget(m_toolBarFeeds);
|
||||||
m_feedSplitter->addWidget(m_messagesWidget);
|
feed_layout->addWidget(m_feedsView);
|
||||||
// Add toolbar and main feeds/messages widget to main layout.
|
|
||||||
central_layout->addWidget(m_feedSplitter);
|
// Assembler everything together.
|
||||||
setTabOrder(m_feedsView, m_messagesView);
|
m_feedSplitter->setHandleWidth(1);
|
||||||
setTabOrder(m_messagesView, m_toolBarFeeds);
|
m_feedSplitter->setOpaqueResize(false);
|
||||||
setTabOrder(m_toolBarFeeds, m_toolBarMessages);
|
m_feedSplitter->setChildrenCollapsible(false);
|
||||||
setTabOrder(m_toolBarMessages, m_messagesBrowser);
|
m_feedSplitter->addWidget(m_feedsWidget);
|
||||||
|
m_feedSplitter->addWidget(m_messagesWidget);
|
||||||
|
|
||||||
|
// Add toolbar and main feeds/messages widget to main layout.
|
||||||
|
central_layout->addWidget(m_feedSplitter);
|
||||||
|
setTabOrder(m_feedsView, m_messagesView);
|
||||||
|
setTabOrder(m_messagesView, m_toolBarFeeds);
|
||||||
|
setTabOrder(m_toolBarFeeds, m_toolBarMessages);
|
||||||
|
setTabOrder(m_toolBarMessages, m_messagesBrowser);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedMessageViewer::refreshVisualProperties() {
|
void FeedMessageViewer::refreshVisualProperties() {
|
||||||
const Qt::ToolButtonStyle button_style = static_cast<Qt::ToolButtonStyle>(qApp->settings()->value(GROUP(GUI),
|
const Qt::ToolButtonStyle button_style =
|
||||||
SETTING(GUI::ToolbarStyle)).toInt());
|
static_cast<Qt::ToolButtonStyle>(qApp->settings()->value(GROUP(GUI), SETTING(GUI::ToolbarStyle)).toInt());
|
||||||
m_toolBarFeeds->setToolButtonStyle(button_style);
|
|
||||||
m_toolBarMessages->setToolButtonStyle(button_style);
|
m_toolBarFeeds->setToolButtonStyle(button_style);
|
||||||
|
m_toolBarMessages->setToolButtonStyle(button_style);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -41,79 +42,72 @@ class QSplitter;
|
|||||||
class QProgressBar;
|
class QProgressBar;
|
||||||
|
|
||||||
class FeedMessageViewer : public TabContent {
|
class FeedMessageViewer : public TabContent {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructors and destructors.
|
explicit FeedMessageViewer(QWidget* parent = 0);
|
||||||
explicit FeedMessageViewer(QWidget* parent = 0);
|
virtual ~FeedMessageViewer();
|
||||||
virtual ~FeedMessageViewer();
|
|
||||||
|
|
||||||
#if defined(USE_WEBENGINE)
|
#if defined(USE_WEBENGINE)
|
||||||
WebBrowser* webBrowser() const;
|
WebBrowser* webBrowser() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FeedsView* feedsView() const;
|
FeedsView* feedsView() const;
|
||||||
MessagesView* messagesView() const;
|
MessagesView* messagesView() const;
|
||||||
MessagesToolBar* messagesToolBar() const;
|
MessagesToolBar* messagesToolBar() const;
|
||||||
FeedsToolBar* feedsToolBar() const;
|
FeedsToolBar* feedsToolBar() const;
|
||||||
|
|
||||||
bool areToolBarsEnabled() const;
|
bool areToolBarsEnabled() const;
|
||||||
bool areListHeadersEnabled() const;
|
bool areListHeadersEnabled() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Loads/saves sizes and states of ALL
|
void saveSize();
|
||||||
// underlying widgets, this contains primarily
|
void loadSize();
|
||||||
// splitters, toolbar and views.
|
|
||||||
void saveSize();
|
|
||||||
void loadSize();
|
|
||||||
|
|
||||||
void loadMessageViewerFonts();
|
void loadMessageViewerFonts();
|
||||||
|
|
||||||
// Switches orientation horizontal/vertical.
|
// Switches orientation horizontal/vertical.
|
||||||
void switchMessageSplitterOrientation();
|
void switchMessageSplitterOrientation();
|
||||||
|
|
||||||
// Enables/disables main toolbars or list headers.
|
// Enables/disables main toolbars or list headers.
|
||||||
void setToolBarsEnabled(bool enable);
|
void setToolBarsEnabled(bool enable);
|
||||||
void setListHeadersEnabled(bool enable);
|
void setListHeadersEnabled(bool enable);
|
||||||
|
|
||||||
// Reloads some changeable visual settings.
|
// Reloads some changeable visual settings.
|
||||||
void refreshVisualProperties();
|
void refreshVisualProperties();
|
||||||
|
|
||||||
// Switches visibility of feed list and related
|
// Switches visibility of feed list and related
|
||||||
// toolbar.
|
// toolbar.
|
||||||
void switchFeedComponentVisibility();
|
void switchFeedComponentVisibility();
|
||||||
|
|
||||||
// Toggles displayed feeds.
|
// Toggles displayed feeds.
|
||||||
void toggleShowOnlyUnreadFeeds();
|
void toggleShowOnlyUnreadFeeds();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Initializes some properties of the widget.
|
void initialize();
|
||||||
void initialize();
|
|
||||||
|
|
||||||
// Initializes both messages/feeds views.
|
// Initializes both messages/feeds views.
|
||||||
void initializeViews();
|
void initializeViews();
|
||||||
|
|
||||||
// Sets up connections.
|
// Sets up connections.
|
||||||
void createConnections();
|
void createConnections();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_toolBarsEnabled;
|
bool m_toolBarsEnabled;
|
||||||
bool m_listHeadersEnabled;
|
bool m_listHeadersEnabled;
|
||||||
FeedsToolBar* m_toolBarFeeds;
|
FeedsToolBar* m_toolBarFeeds;
|
||||||
MessagesToolBar* m_toolBarMessages;
|
MessagesToolBar* m_toolBarMessages;
|
||||||
|
QSplitter* m_feedSplitter;
|
||||||
QSplitter* m_feedSplitter;
|
QSplitter* m_messageSplitter;
|
||||||
QSplitter* m_messageSplitter;
|
MessagesView* m_messagesView;
|
||||||
|
FeedsView* m_feedsView;
|
||||||
MessagesView* m_messagesView;
|
QWidget* m_feedsWidget;
|
||||||
FeedsView* m_feedsView;
|
QWidget* m_messagesWidget;
|
||||||
QWidget* m_feedsWidget;
|
|
||||||
QWidget* m_messagesWidget;
|
|
||||||
|
|
||||||
#if defined(USE_WEBENGINE)
|
#if defined(USE_WEBENGINE)
|
||||||
WebBrowser* m_messagesBrowser;
|
WebBrowser* m_messagesBrowser;
|
||||||
#else
|
#else
|
||||||
MessagePreviewer* m_messagesBrowser;
|
MessagePreviewer* m_messagesBrowser;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,87 +20,82 @@
|
|||||||
#include "miscellaneous/application.h"
|
#include "miscellaneous/application.h"
|
||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QCheckBox>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
#include <QCheckBox>
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
|
||||||
MessageBox::MessageBox(QWidget* parent) : QMessageBox(parent) {
|
MessageBox::MessageBox(QWidget* parent) : QMessageBox(parent) {}
|
||||||
}
|
|
||||||
|
|
||||||
MessageBox::~MessageBox() {
|
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.
|
|
||||||
setIconPixmap(iconForStatus(icon).pixmap(icon_size, icon_size));
|
// Setup status icon.
|
||||||
|
setIconPixmap(iconForStatus(icon).pixmap(icon_size, icon_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
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->setText(text);
|
check_box->setChecked(*data);
|
||||||
connect(check_box, &QCheckBox::toggled, [ = ](bool checked) {
|
check_box->setText(text);
|
||||||
*data = checked;
|
connect(check_box, &QCheckBox::toggled, [=](bool checked) {
|
||||||
});
|
*data = checked;
|
||||||
msg_box->setCheckBox(check_box);
|
});
|
||||||
|
msg_box->setCheckBox(check_box);
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon MessageBox::iconForStatus(QMessageBox::Icon status) {
|
QIcon MessageBox::iconForStatus(QMessageBox::Icon status) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case QMessageBox::Information:
|
case QMessageBox::Information:
|
||||||
return qApp->icons()->fromTheme(QSL("dialog-information"));
|
return qApp->icons()->fromTheme(QSL("dialog-information"));
|
||||||
|
|
||||||
case QMessageBox::Warning:
|
case QMessageBox::Warning:
|
||||||
return qApp->icons()->fromTheme(QSL("dialog-warning"));
|
return qApp->icons()->fromTheme(QSL("dialog-warning"));
|
||||||
|
|
||||||
case QMessageBox::Critical:
|
case QMessageBox::Critical:
|
||||||
return qApp->icons()->fromTheme(QSL("dialog-error"));
|
return qApp->icons()->fromTheme(QSL("dialog-error"));
|
||||||
|
|
||||||
case QMessageBox::Question:
|
case QMessageBox::Question:
|
||||||
return qApp->icons()->fromTheme(QSL("dialog-question"));
|
return qApp->icons()->fromTheme(QSL("dialog-question"));
|
||||||
|
|
||||||
case QMessageBox::NoIcon:
|
case QMessageBox::NoIcon:
|
||||||
default:
|
default:
|
||||||
return QIcon();
|
return QIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QMessageBox::StandardButton MessageBox::show(QWidget* parent,
|
QMessageBox::StandardButton MessageBox::show(QWidget* parent, QMessageBox::Icon icon, const QString& title, const QString& text,
|
||||||
QMessageBox::Icon icon,
|
const QString& informative_text, const QString& detailed_text, QMessageBox::StandardButtons buttons,
|
||||||
const QString& title,
|
QMessageBox::StandardButton default_button, bool* dont_show_again) {
|
||||||
const QString& text,
|
// Create and find needed components.
|
||||||
const QString& informative_text,
|
MessageBox msg_box(parent);
|
||||||
const QString& detailed_text,
|
|
||||||
QMessageBox::StandardButtons buttons,
|
|
||||||
QMessageBox::StandardButton default_button,
|
|
||||||
bool* dont_show_again) {
|
|
||||||
// Create and find needed components.
|
|
||||||
MessageBox msg_box(parent);
|
|
||||||
// Initialize message box properties.
|
|
||||||
msg_box.setWindowTitle(title);
|
|
||||||
msg_box.setText(text);
|
|
||||||
msg_box.setInformativeText(informative_text);
|
|
||||||
msg_box.setDetailedText(detailed_text);
|
|
||||||
msg_box.setIcon(icon);
|
|
||||||
msg_box.setStandardButtons(buttons);
|
|
||||||
msg_box.setDefaultButton(default_button);
|
|
||||||
|
|
||||||
if (dont_show_again != nullptr) {
|
// Initialize message box properties.
|
||||||
MessageBox::setCheckBox(&msg_box, tr("Do not show this dialog again."), dont_show_again);
|
msg_box.setWindowTitle(title);
|
||||||
}
|
msg_box.setText(text);
|
||||||
|
msg_box.setInformativeText(informative_text);
|
||||||
|
msg_box.setDetailedText(detailed_text);
|
||||||
|
msg_box.setIcon(icon);
|
||||||
|
msg_box.setStandardButtons(buttons);
|
||||||
|
msg_box.setDefaultButton(default_button);
|
||||||
|
|
||||||
// Display it.
|
if (dont_show_again != nullptr) {
|
||||||
if (msg_box.exec() == -1) {
|
MessageBox::setCheckBox(&msg_box, tr("Do not show this dialog again."), dont_show_again);
|
||||||
return QMessageBox::Cancel;
|
}
|
||||||
}
|
|
||||||
else {
|
// Display it.
|
||||||
return msg_box.standardButton(msg_box.clickedButton());
|
if (msg_box.exec() == -1) {
|
||||||
}
|
return QMessageBox::Cancel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return msg_box.standardButton(msg_box.clickedButton());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
//
|
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
// RSS Guard is free software: you can redistribute it and/or modify
|
// RSS Guard is free software: you can redistribute it and/or modify
|
||||||
@ -17,175 +17,179 @@
|
|||||||
|
|
||||||
#include "gui/messagesview.h"
|
#include "gui/messagesview.h"
|
||||||
|
|
||||||
#include "core/messagesproxymodel.h"
|
|
||||||
#include "core/messagesmodel.h"
|
#include "core/messagesmodel.h"
|
||||||
#include "miscellaneous/settings.h"
|
#include "core/messagesproxymodel.h"
|
||||||
|
#include "gui/dialogs/formmain.h"
|
||||||
|
#include "gui/messagebox.h"
|
||||||
|
#include "gui/styleditemdelegatewithoutfocus.h"
|
||||||
|
#include "gui/treeviewcolumnsmenu.h"
|
||||||
|
#include "miscellaneous/externaltool.h"
|
||||||
#include "miscellaneous/feedreader.h"
|
#include "miscellaneous/feedreader.h"
|
||||||
|
#include "miscellaneous/settings.h"
|
||||||
#include "network-web/networkfactory.h"
|
#include "network-web/networkfactory.h"
|
||||||
#include "network-web/webfactory.h"
|
#include "network-web/webfactory.h"
|
||||||
#include "gui/dialogs/formmain.h"
|
|
||||||
#include "miscellaneous/externaltool.h"
|
|
||||||
#include "gui/messagebox.h"
|
|
||||||
#include "gui/treeviewcolumnsmenu.h"
|
|
||||||
#include "gui/styleditemdelegatewithoutfocus.h"
|
|
||||||
|
|
||||||
|
#include <QFileIconProvider>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QProcess>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QMenu>
|
|
||||||
#include <QFileIconProvider>
|
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
|
MessagesView::MessagesView(QWidget* parent) : QTreeView(parent), m_contextMenu(nullptr), m_columnsAdjusted(false) {
|
||||||
|
m_sourceModel = qApp->feedReader()->messagesModel();
|
||||||
|
m_proxyModel = qApp->feedReader()->messagesProxyModel();
|
||||||
|
|
||||||
MessagesView::MessagesView(QWidget* parent)
|
// Forward count changes to the view.
|
||||||
: QTreeView(parent), m_contextMenu(nullptr), m_columnsAdjusted(false) {
|
createConnections();
|
||||||
m_sourceModel = qApp->feedReader()->messagesModel();
|
setModel(m_proxyModel);
|
||||||
m_proxyModel = qApp->feedReader()->messagesProxyModel();
|
setupAppearance();
|
||||||
// Forward count changes to the view.
|
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
createConnections();
|
connect(header(), &QHeaderView::customContextMenuRequested, [=](const QPoint& point) {
|
||||||
setModel(m_proxyModel);
|
TreeViewColumnsMenu mm(header());
|
||||||
setupAppearance();
|
mm.exec(header()->mapToGlobal(point));
|
||||||
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
});
|
||||||
connect(header(), &QHeaderView::customContextMenuRequested, [ = ](const QPoint & point) {
|
|
||||||
TreeViewColumnsMenu mm(header());
|
|
||||||
mm.exec(header()->mapToGlobal(point));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessagesView::~MessagesView() {
|
MessagesView::~MessagesView() {
|
||||||
qDebug("Destroying MessagesView instance.");
|
qDebug("Destroying MessagesView instance.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header) {
|
void MessagesView::sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header) {
|
||||||
if (change_header && !emit_changed_from_header) {
|
if (change_header && !emit_changed_from_header) {
|
||||||
header()->blockSignals(true);
|
header()->blockSignals(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sourceModel->addSortState(column, order);
|
m_sourceModel->addSortState(column, order);
|
||||||
|
|
||||||
if (repopulate_data) {
|
if (repopulate_data) {
|
||||||
m_sourceModel->repopulate();
|
m_sourceModel->repopulate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (change_header) {
|
if (change_header) {
|
||||||
header()->setSortIndicator(column, order);
|
header()->setSortIndicator(column, order);
|
||||||
header()->blockSignals(false);
|
header()->blockSignals(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
|
||||||
connect(header(), &QHeaderView::geometriesChanged, this, &MessagesView::adjustColumns);
|
// Adjust columns when layout gets changed.
|
||||||
connect(header(), &QHeaderView::sortIndicatorChanged, this, &MessagesView::onSortIndicatorChanged);
|
connect(header(), &QHeaderView::geometriesChanged, this, &MessagesView::adjustColumns);
|
||||||
|
connect(header(), &QHeaderView::sortIndicatorChanged, this, &MessagesView::onSortIndicatorChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::keyboardSearch(const QString& search) {
|
void MessagesView::keyboardSearch(const QString& search) {
|
||||||
// WARNING: This is quite hacky way how to force selection of next item even
|
// WARNING: This is quite hacky way how to force selection of next item even
|
||||||
// with extended selection enabled.
|
// with extended selection enabled.
|
||||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
QTreeView::keyboardSearch(search);
|
QTreeView::keyboardSearch(search);
|
||||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
|
||||||
sort(col, ord, true, false, false);
|
|
||||||
|
|
||||||
// Now, we must find the same previously focused message.
|
// Reload the model now.
|
||||||
if (selected_message.m_id > 0) {
|
sort(col, ord, true, false, false);
|
||||||
if (m_proxyModel->rowCount() == 0) {
|
|
||||||
current_index = QModelIndex();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (int i = 0; i < m_proxyModel->rowCount(); i++) {
|
|
||||||
QModelIndex msg_idx = m_proxyModel->index(i, MSG_DB_TITLE_INDEX);
|
|
||||||
Message msg = m_sourceModel->messageAt(m_proxyModel->mapToSource(msg_idx).row());
|
|
||||||
|
|
||||||
if (msg.m_id == selected_message.m_id) {
|
// Now, we must find the same previously focused message.
|
||||||
current_index = msg_idx;
|
if (selected_message.m_id > 0) {
|
||||||
break;
|
if (m_proxyModel->rowCount() == 0) {
|
||||||
}
|
current_index = QModelIndex();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < m_proxyModel->rowCount(); i++) {
|
||||||
|
QModelIndex msg_idx = m_proxyModel->index(i, MSG_DB_TITLE_INDEX);
|
||||||
|
Message msg = m_sourceModel->messageAt(m_proxyModel->mapToSource(msg_idx).row());
|
||||||
|
|
||||||
if (i == m_proxyModel->rowCount() - 1) {
|
if (msg.m_id == selected_message.m_id) {
|
||||||
current_index = QModelIndex();
|
current_index = msg_idx;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current_index.isValid()) {
|
if (i == m_proxyModel->rowCount() - 1) {
|
||||||
scrollTo(current_index);
|
current_index = QModelIndex();
|
||||||
setCurrentIndex(current_index);
|
}
|
||||||
reselectIndexes(QModelIndexList() << current_index);
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
// Messages were probably removed from the model, nothing can
|
|
||||||
// be selected and no message can be displayed.
|
|
||||||
emit currentMessageRemoved();
|
|
||||||
}
|
|
||||||
|
|
||||||
const QDateTime dt2 = QDateTime::currentDateTime();
|
if (current_index.isValid()) {
|
||||||
qDebug("Reloading of msg selections took %lld miliseconds.", dt1.msecsTo(dt2));
|
scrollTo(current_index);
|
||||||
|
setCurrentIndex(current_index);
|
||||||
|
reselectIndexes(QModelIndexList() << current_index);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Messages were probably removed from the model, nothing can
|
||||||
|
// be selected and no message can be displayed.
|
||||||
|
emit currentMessageRemoved();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDateTime dt2 = QDateTime::currentDateTime();
|
||||||
|
|
||||||
|
qDebug("Reloading of msg selections took %lld miliseconds.", dt1.msecsTo(dt2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::setupAppearance() {
|
void MessagesView::setupAppearance() {
|
||||||
setUniformRowHeights(true);
|
setUniformRowHeights(true);
|
||||||
setAcceptDrops(false);
|
setAcceptDrops(false);
|
||||||
setDragEnabled(false);
|
setDragEnabled(false);
|
||||||
setDragDropMode(QAbstractItemView::NoDragDrop);
|
setDragDropMode(QAbstractItemView::NoDragDrop);
|
||||||
setExpandsOnDoubleClick(false);
|
setExpandsOnDoubleClick(false);
|
||||||
setRootIsDecorated(false);
|
setRootIsDecorated(false);
|
||||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
setItemsExpandable(false);
|
setItemsExpandable(false);
|
||||||
setSortingEnabled(true);
|
setSortingEnabled(true);
|
||||||
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);
|
||||||
header()->setStretchLastSection(true);
|
header()->setStretchLastSection(true);
|
||||||
header()->setSortIndicatorShown(true);
|
header()->setSortIndicatorShown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::keyPressEvent(QKeyEvent* event) {
|
void MessagesView::keyPressEvent(QKeyEvent* event) {
|
||||||
QTreeView::keyPressEvent(event);
|
QTreeView::keyPressEvent(event);
|
||||||
|
|
||||||
if (event->key() == Qt::Key_Delete) {
|
if (event->key() == Qt::Key_Delete) {
|
||||||
deleteSelectedMessages();
|
deleteSelectedMessages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::contextMenuEvent(QContextMenuEvent* event) {
|
void MessagesView::contextMenuEvent(QContextMenuEvent* event) {
|
||||||
const QModelIndex clicked_index = indexAt(event->pos());
|
const QModelIndex clicked_index = indexAt(event->pos());
|
||||||
|
|
||||||
if (!clicked_index.isValid()) {
|
if (!clicked_index.isValid()) {
|
||||||
TreeViewColumnsMenu menu(header());
|
TreeViewColumnsMenu menu(header());
|
||||||
menu.exec(event->globalPos());
|
|
||||||
}
|
menu.exec(event->globalPos());
|
||||||
else {
|
}
|
||||||
// Context menu is not initialized, initialize.
|
else {
|
||||||
initializeContextMenu();
|
// Context menu is not initialized, initialize.
|
||||||
m_contextMenu->exec(event->globalPos());
|
initializeContextMenu();
|
||||||
}
|
m_contextMenu->exec(event->globalPos());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::initializeContextMenu() {
|
void MessagesView::initializeContextMenu() {
|
||||||
if (m_contextMenu == nullptr) {
|
if (m_contextMenu == nullptr) {
|
||||||
m_contextMenu = new QMenu(tr("Context menu for messages"), this);
|
m_contextMenu = new QMenu(tr("Context menu for messages"), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_contextMenu->clear();
|
m_contextMenu->clear();
|
||||||
|
|
||||||
QFileIconProvider icon_provider;
|
QFileIconProvider icon_provider;
|
||||||
QMenu* menu = new QMenu(tr("Open with external tool"), m_contextMenu);
|
QMenu* menu = new QMenu(tr("Open with external tool"), m_contextMenu);
|
||||||
|
|
||||||
menu->setIcon(qApp->icons()->fromTheme(QSL("document-open")));
|
menu->setIcon(qApp->icons()->fromTheme(QSL("document-open")));
|
||||||
|
|
||||||
foreach (const ExternalTool& tool, ExternalTool::toolsFromSettings()) {
|
foreach (const ExternalTool& tool, ExternalTool::toolsFromSettings()) {
|
||||||
@ -201,307 +205,304 @@ void MessagesView::initializeContextMenu() {
|
|||||||
|
|
||||||
if (menu->actions().isEmpty()) {
|
if (menu->actions().isEmpty()) {
|
||||||
QAction* act_not_tools = new QAction("No external tools activated");
|
QAction* act_not_tools = new QAction("No external tools activated");
|
||||||
|
|
||||||
act_not_tools->setEnabled(false);
|
act_not_tools->setEnabled(false);
|
||||||
menu->addAction(act_not_tools);
|
menu->addAction(act_not_tools);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_contextMenu->addMenu(menu);
|
m_contextMenu->addMenu(menu);
|
||||||
m_contextMenu->addActions(QList<QAction*>() <<
|
m_contextMenu->addActions(QList<QAction*>() << qApp->mainForm()->m_ui->m_actionSendMessageViaEmail << qApp->mainForm()->m_ui->m_actionOpenSelectedSourceArticlesExternally << qApp->mainForm()->m_ui->m_actionOpenSelectedMessagesInternally << qApp->mainForm()->m_ui->m_actionMarkSelectedMessagesAsRead << qApp->mainForm()->m_ui->m_actionMarkSelectedMessagesAsUnread << qApp->mainForm()->m_ui->m_actionSwitchImportanceOfSelectedMessages << qApp->mainForm()->m_ui->m_actionDeleteSelectedMessages);
|
||||||
qApp->mainForm()->m_ui->m_actionSendMessageViaEmail <<
|
|
||||||
qApp->mainForm()->m_ui->m_actionOpenSelectedSourceArticlesExternally <<
|
|
||||||
qApp->mainForm()->m_ui->m_actionOpenSelectedMessagesInternally <<
|
|
||||||
qApp->mainForm()->m_ui->m_actionMarkSelectedMessagesAsRead <<
|
|
||||||
qApp->mainForm()->m_ui->m_actionMarkSelectedMessagesAsUnread <<
|
|
||||||
qApp->mainForm()->m_ui->m_actionSwitchImportanceOfSelectedMessages <<
|
|
||||||
qApp->mainForm()->m_ui->m_actionDeleteSelectedMessages);
|
|
||||||
|
|
||||||
if (m_sourceModel->loadedItem() != nullptr && m_sourceModel->loadedItem()->kind() == RootItemKind::Bin) {
|
if (m_sourceModel->loadedItem() != nullptr && m_sourceModel->loadedItem()->kind() == RootItemKind::Bin) {
|
||||||
m_contextMenu->addAction(qApp->mainForm()->m_ui->m_actionRestoreSelectedMessages);
|
m_contextMenu->addAction(qApp->mainForm()->m_ui->m_actionRestoreSelectedMessages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::mousePressEvent(QMouseEvent* event) {
|
void MessagesView::mousePressEvent(QMouseEvent* event) {
|
||||||
QTreeView::mousePressEvent(event);
|
QTreeView::mousePressEvent(event);
|
||||||
|
|
||||||
switch (event->button()) {
|
switch (event->button()) {
|
||||||
case Qt::LeftButton: {
|
case Qt::LeftButton: {
|
||||||
// Make sure that message importance is switched when user
|
// Make sure that message importance is switched when user
|
||||||
// clicks the "important" column.
|
// clicks the "important" column.
|
||||||
const QModelIndex clicked_index = indexAt(event->pos());
|
const QModelIndex clicked_index = indexAt(event->pos());
|
||||||
|
|
||||||
if (clicked_index.isValid()) {
|
if (clicked_index.isValid()) {
|
||||||
const QModelIndex mapped_index = m_proxyModel->mapToSource(clicked_index);
|
const QModelIndex mapped_index = m_proxyModel->mapToSource(clicked_index);
|
||||||
|
|
||||||
if (mapped_index.column() == MSG_DB_IMPORTANT_INDEX) {
|
if (mapped_index.column() == MSG_DB_IMPORTANT_INDEX) {
|
||||||
if (m_sourceModel->switchMessageImportance(mapped_index.row())) {
|
if (m_sourceModel->switchMessageImportance(mapped_index.row())) {
|
||||||
emit currentMessageChanged(m_sourceModel->messageAt(mapped_index.row()), m_sourceModel->loadedItem());
|
emit currentMessageChanged(m_sourceModel->messageAt(mapped_index.row()), m_sourceModel->loadedItem());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Qt::MiddleButton: {
|
case Qt::MiddleButton: {
|
||||||
// Make sure that message importance is switched when user
|
// Make sure that message importance is switched when user
|
||||||
// clicks the "important" column.
|
// clicks the "important" column.
|
||||||
const QModelIndex clicked_index = indexAt(event->pos());
|
const QModelIndex clicked_index = indexAt(event->pos());
|
||||||
|
|
||||||
if (clicked_index.isValid()) {
|
if (clicked_index.isValid()) {
|
||||||
const QModelIndex mapped_index = m_proxyModel->mapToSource(clicked_index);
|
const QModelIndex mapped_index = m_proxyModel->mapToSource(clicked_index);
|
||||||
const QString url = m_sourceModel->messageAt(mapped_index.row()).m_url;
|
const QString url = m_sourceModel->messageAt(mapped_index.row()).m_url;
|
||||||
|
|
||||||
if (!url.isEmpty()) {
|
if (!url.isEmpty()) {
|
||||||
qApp->mainForm()->tabWidget()->addLinkedBrowser(url);
|
qApp->mainForm()->tabWidget()->addLinkedBrowser(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) {
|
void MessagesView::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) {
|
||||||
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].",
|
|
||||||
current_index.row(), current_index.column(),
|
|
||||||
mapped_current_index.row(), mapped_current_index.column());
|
|
||||||
|
|
||||||
if (mapped_current_index.isValid() && selected_rows.count() > 0) {
|
qDebug("Current row changed - row [%d,%d] source [%d, %d].",current_index.row(), current_index.column(),mapped_current_index.row(), mapped_current_index.column());
|
||||||
Message message = m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row());
|
|
||||||
// Set this message as read only if current item
|
|
||||||
// wasn't changed by "mark selected messages unread" action.
|
|
||||||
m_sourceModel->setMessageRead(mapped_current_index.row(), RootItem::Read);
|
|
||||||
message.m_isRead = true;
|
|
||||||
emit currentMessageChanged(message, m_sourceModel->loadedItem());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
emit currentMessageRemoved();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::KeepCursorInCenter)).toBool()) {
|
if (mapped_current_index.isValid() && selected_rows.count() > 0) {
|
||||||
scrollTo(currentIndex(), QAbstractItemView::PositionAtCenter);
|
Message message = m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row());
|
||||||
}
|
|
||||||
|
|
||||||
QTreeView::selectionChanged(selected, deselected);
|
// Set this message as read only if current item
|
||||||
|
// wasn't changed by "mark selected messages unread" action.
|
||||||
|
m_sourceModel->setMessageRead(mapped_current_index.row(), RootItem::Read);
|
||||||
|
message.m_isRead = true;
|
||||||
|
|
||||||
|
emit currentMessageChanged(message, m_sourceModel->loadedItem());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
emit currentMessageRemoved();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::KeepCursorInCenter)).toBool()) {
|
||||||
|
scrollTo(currentIndex(), QAbstractItemView::PositionAtCenter);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTreeView::selectionChanged(selected, deselected);
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
sort(col, ord, false, true, false);
|
scrollToTop();
|
||||||
m_sourceModel->loadMessages(item);
|
sort(col, ord, false, true, false);
|
||||||
// Messages are loaded, make sure that previously
|
m_sourceModel->loadMessages(item);
|
||||||
// active message is not shown in browser.
|
|
||||||
// BUG: Qt 5 is probably bugged here. Selections
|
// Messages are loaded, make sure that previously
|
||||||
// should be cleared automatically when SQL model is reset.
|
// active message is not shown in browser.
|
||||||
emit currentMessageRemoved();
|
// BUG: Qt 5 is probably bugged here. Selections
|
||||||
|
// should be cleared automatically when SQL model is reset.
|
||||||
|
emit currentMessageRemoved();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::openSelectedSourceMessagesExternally() {
|
void MessagesView::openSelectedSourceMessagesExternally() {
|
||||||
foreach (const QModelIndex& index, selectionModel()->selectedRows()) {
|
foreach (const QModelIndex& index, selectionModel()->selectedRows()) {
|
||||||
const QString link = m_sourceModel->messageAt(m_proxyModel->mapToSource(index).row()).m_url;
|
const QString link = m_sourceModel->messageAt(m_proxyModel->mapToSource(index).row()).m_url;
|
||||||
|
|
||||||
if (!qApp->web()->openUrlInExternalBrowser(link)) {
|
if (!qApp->web()->openUrlInExternalBrowser(link)) {
|
||||||
qApp->showGuiMessage(tr("Problem with starting external web browser"),
|
qApp->showGuiMessage(tr("Problem with starting external web browser"),tr("External web browser could not be started."),QSystemTrayIcon::Critical);
|
||||||
tr("External web browser could not be started."),
|
return;
|
||||||
QSystemTrayIcon::Critical);
|
}
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, mark opened messages as read.
|
// Finally, mark opened messages as read.
|
||||||
if (!selectionModel()->selectedRows().isEmpty()) {
|
if (!selectionModel()->selectedRows().isEmpty()) {
|
||||||
QTimer::singleShot(0, this, SLOT(markSelectedMessagesRead()));
|
QTimer::singleShot(0, this, SLOT(markSelectedMessagesRead()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::openSelectedMessagesInternally() {
|
void MessagesView::openSelectedMessagesInternally() {
|
||||||
QList<Message> messages;
|
QList<Message> messages;
|
||||||
|
|
||||||
foreach (const QModelIndex& index, selectionModel()->selectedRows()) {
|
foreach (const QModelIndex& index, selectionModel()->selectedRows()) {
|
||||||
messages << m_sourceModel->messageAt(m_proxyModel->mapToSource(index).row());
|
messages << m_sourceModel->messageAt(m_proxyModel->mapToSource(index).row());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!messages.isEmpty()) {
|
if (!messages.isEmpty()) {
|
||||||
emit openMessagesInNewspaperView(m_sourceModel->loadedItem(), messages);
|
emit openMessagesInNewspaperView(m_sourceModel->loadedItem(), messages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::sendSelectedMessageViaEmail() {
|
void MessagesView::sendSelectedMessageViaEmail() {
|
||||||
if (selectionModel()->selectedRows().size() == 1) {
|
if (selectionModel()->selectedRows().size() == 1) {
|
||||||
const Message message = m_sourceModel->messageAt(m_proxyModel->mapToSource(selectionModel()->selectedRows().at(0)).row());
|
const Message message = m_sourceModel->messageAt(m_proxyModel->mapToSource(selectionModel()->selectedRows().at(0)).row());
|
||||||
|
|
||||||
if (!qApp->web()->sendMessageViaEmail(message)) {
|
if (!qApp->web()->sendMessageViaEmail(message)) {
|
||||||
MessageBox::show(this,
|
MessageBox::show(this,QMessageBox::Critical,tr("Problem with starting external e-mail client"),tr("External e-mail client could not be started."));
|
||||||
QMessageBox::Critical,
|
}
|
||||||
tr("Problem with starting external e-mail client"),
|
}
|
||||||
tr("External e-mail client could not be started."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::markSelectedMessagesRead() {
|
void MessagesView::markSelectedMessagesRead() {
|
||||||
setSelectedMessagesReadStatus(RootItem::Read);
|
setSelectedMessagesReadStatus(RootItem::Read);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::markSelectedMessagesUnread() {
|
void MessagesView::markSelectedMessagesUnread() {
|
||||||
setSelectedMessagesReadStatus(RootItem::Unread);
|
setSelectedMessagesReadStatus(RootItem::Unread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::setSelectedMessagesReadStatus(RootItem::ReadStatus read) {
|
void MessagesView::setSelectedMessagesReadStatus(RootItem::ReadStatus read) {
|
||||||
QModelIndex current_index = selectionModel()->currentIndex();
|
QModelIndex current_index = selectionModel()->currentIndex();
|
||||||
|
|
||||||
if (!current_index.isValid()) {
|
if (!current_index.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
current_index = m_proxyModel->index(current_index.row(), current_index.column());
|
|
||||||
|
|
||||||
if (current_index.isValid()) {
|
m_sourceModel->setBatchMessagesRead(mapped_indexes, read);
|
||||||
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
|
current_index = m_proxyModel->index(current_index.row(), current_index.column());
|
||||||
}
|
|
||||||
else {
|
if (current_index.isValid()) {
|
||||||
emit currentMessageRemoved();
|
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
emit currentMessageRemoved();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::deleteSelectedMessages() {
|
void MessagesView::deleteSelectedMessages() {
|
||||||
QModelIndex current_index = selectionModel()->currentIndex();
|
QModelIndex current_index = selectionModel()->currentIndex();
|
||||||
|
|
||||||
if (!current_index.isValid()) {
|
if (!current_index.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
current_index = moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier);
|
|
||||||
|
|
||||||
if (current_index.isValid()) {
|
m_sourceModel->setBatchMessagesDeleted(mapped_indexes);
|
||||||
setCurrentIndex(current_index);
|
current_index = moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier);
|
||||||
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
|
|
||||||
}
|
if (current_index.isValid()) {
|
||||||
else {
|
setCurrentIndex(current_index);
|
||||||
emit currentMessageRemoved();
|
|
||||||
}
|
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
emit currentMessageRemoved();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::restoreSelectedMessages() {
|
void MessagesView::restoreSelectedMessages() {
|
||||||
QModelIndex current_index = selectionModel()->currentIndex();
|
QModelIndex current_index = selectionModel()->currentIndex();
|
||||||
|
|
||||||
if (!current_index.isValid()) {
|
if (!current_index.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
current_index = m_proxyModel->index(current_index.row(), current_index.column());
|
|
||||||
|
|
||||||
if (current_index.isValid()) {
|
m_sourceModel->setBatchMessagesRestored(mapped_indexes);
|
||||||
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
|
current_index = m_proxyModel->index(current_index.row(), current_index.column());
|
||||||
}
|
|
||||||
else {
|
if (current_index.isValid()) {
|
||||||
emit currentMessageRemoved();
|
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
emit currentMessageRemoved();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::switchSelectedMessagesImportance() {
|
void MessagesView::switchSelectedMessagesImportance() {
|
||||||
QModelIndex current_index = selectionModel()->currentIndex();
|
QModelIndex current_index = selectionModel()->currentIndex();
|
||||||
|
|
||||||
if (!current_index.isValid()) {
|
if (!current_index.isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
current_index = m_proxyModel->index(current_index.row(), current_index.column());
|
|
||||||
|
|
||||||
if (current_index.isValid()) {
|
m_sourceModel->switchBatchMessageImportance(mapped_indexes);
|
||||||
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
|
current_index = m_proxyModel->index(current_index.row(), current_index.column());
|
||||||
}
|
|
||||||
else {
|
if (current_index.isValid()) {
|
||||||
// Messages were probably removed from the model, nothing can
|
emit currentMessageChanged(m_sourceModel->messageAt(m_proxyModel->mapToSource(current_index).row()), m_sourceModel->loadedItem());
|
||||||
// be selected and no message can be displayed.
|
}
|
||||||
emit currentMessageRemoved();
|
else {
|
||||||
}
|
// Messages were probably removed from the model, nothing can
|
||||||
|
// be selected and no message can be displayed.
|
||||||
|
emit currentMessageRemoved();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::reselectIndexes(const QModelIndexList& indexes) {
|
void MessagesView::reselectIndexes(const QModelIndexList& indexes) {
|
||||||
if (indexes.size() < RESELECT_MESSAGE_THRESSHOLD) {
|
if (indexes.size() < RESELECT_MESSAGE_THRESSHOLD) {
|
||||||
QItemSelection selection;
|
QItemSelection selection;
|
||||||
|
|
||||||
foreach (const QModelIndex& index, indexes) {
|
foreach (const QModelIndex& index, indexes) {
|
||||||
selection.merge(QItemSelection(index, index), QItemSelectionModel::Select);
|
selection.merge(QItemSelection(index, index), QItemSelectionModel::Select);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::selectNextItem() {
|
void MessagesView::selectNextItem() {
|
||||||
const QModelIndex index_next = moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier);
|
const QModelIndex index_next = moveCursor(QAbstractItemView::MoveDown, Qt::NoModifier);
|
||||||
|
|
||||||
if (index_next.isValid()) {
|
if (index_next.isValid()) {
|
||||||
setCurrentIndex(index_next);
|
setCurrentIndex(index_next);
|
||||||
selectionModel()->select(index_next, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
selectionModel()->select(index_next, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||||
setFocus();
|
setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::selectPreviousItem() {
|
void MessagesView::selectPreviousItem() {
|
||||||
const QModelIndex index_previous = moveCursor(QAbstractItemView::MoveUp, Qt::NoModifier);
|
const QModelIndex index_previous = moveCursor(QAbstractItemView::MoveUp, Qt::NoModifier);
|
||||||
|
|
||||||
if (index_previous.isValid()) {
|
if (index_previous.isValid()) {
|
||||||
setCurrentIndex(index_previous);
|
setCurrentIndex(index_previous);
|
||||||
selectionModel()->select(index_previous, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
selectionModel()->select(index_previous, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||||
setFocus();
|
setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::selectNextUnreadItem() {
|
void MessagesView::selectNextUnreadItem() {
|
||||||
const QModelIndexList selected_rows = selectionModel()->selectedRows();
|
const QModelIndexList selected_rows = selectionModel()->selectedRows();
|
||||||
int active_row;
|
int active_row;
|
||||||
|
|
||||||
if (!selected_rows.isEmpty()) {
|
if (!selected_rows.isEmpty()) {
|
||||||
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QModelIndex next_unread = m_proxyModel->getNextPreviousUnreadItemIndex(active_row);
|
const QModelIndex next_unread = m_proxyModel->getNextPreviousUnreadItemIndex(active_row);
|
||||||
|
|
||||||
if (next_unread.isValid()) {
|
if (next_unread.isValid()) {
|
||||||
// We found unread message, mark it.
|
// We found unread message, mark it.
|
||||||
setCurrentIndex(next_unread);
|
setCurrentIndex(next_unread);
|
||||||
selectionModel()->select(next_unread, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
selectionModel()->select(next_unread, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||||
setFocus();
|
setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::searchMessages(const QString& pattern) {
|
void MessagesView::searchMessages(const QString& pattern) {
|
||||||
m_proxyModel->setFilterRegExp(pattern);
|
m_proxyModel->setFilterRegExp(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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::filterMessages(MessagesModel::MessageHighlighter filter) {
|
void MessagesView::filterMessages(MessagesModel::MessageHighlighter filter) {
|
||||||
@ -519,8 +520,7 @@ void MessagesView::openSelectedMessagesWithExternalTool() {
|
|||||||
|
|
||||||
if (!link.isEmpty()) {
|
if (!link.isEmpty()) {
|
||||||
if (!QProcess::startDetached(tool.executable(), QStringList() << tool.parameters() << link)) {
|
if (!QProcess::startDetached(tool.executable(), QStringList() << tool.parameters() << link)) {
|
||||||
qApp->showGuiMessage(tr("Cannot run external tool"), tr("External tool '%1' could not be started.").arg(tool.executable()),
|
qApp->showGuiMessage(tr("Cannot run external tool"), tr("External tool '%1' could not be started.").arg(tool.executable()),QSystemTrayIcon::Critical);
|
||||||
QSystemTrayIcon::Critical);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,39 +528,42 @@ void MessagesView::openSelectedMessagesWithExternalTool() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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.
|
|
||||||
header()->setSectionResizeMode(MSG_DB_ID_INDEX, QHeaderView::Interactive);
|
// Setup column resize strategies.
|
||||||
header()->setSectionResizeMode(MSG_DB_READ_INDEX, QHeaderView::ResizeToContents);
|
header()->setSectionResizeMode(MSG_DB_ID_INDEX, QHeaderView::Interactive);
|
||||||
header()->setSectionResizeMode(MSG_DB_DELETED_INDEX, QHeaderView::Interactive);
|
header()->setSectionResizeMode(MSG_DB_READ_INDEX, QHeaderView::ResizeToContents);
|
||||||
header()->setSectionResizeMode(MSG_DB_IMPORTANT_INDEX, QHeaderView::ResizeToContents);
|
header()->setSectionResizeMode(MSG_DB_DELETED_INDEX, QHeaderView::Interactive);
|
||||||
header()->setSectionResizeMode(MSG_DB_FEED_TITLE_INDEX, QHeaderView::Interactive);
|
header()->setSectionResizeMode(MSG_DB_IMPORTANT_INDEX, QHeaderView::ResizeToContents);
|
||||||
header()->setSectionResizeMode(MSG_DB_TITLE_INDEX, QHeaderView::Interactive);
|
header()->setSectionResizeMode(MSG_DB_FEED_TITLE_INDEX, QHeaderView::Interactive);
|
||||||
header()->setSectionResizeMode(MSG_DB_URL_INDEX, QHeaderView::Interactive);
|
header()->setSectionResizeMode(MSG_DB_TITLE_INDEX, QHeaderView::Interactive);
|
||||||
header()->setSectionResizeMode(MSG_DB_AUTHOR_INDEX, QHeaderView::Interactive);
|
header()->setSectionResizeMode(MSG_DB_URL_INDEX, QHeaderView::Interactive);
|
||||||
header()->setSectionResizeMode(MSG_DB_DCREATED_INDEX, QHeaderView::Interactive);
|
header()->setSectionResizeMode(MSG_DB_AUTHOR_INDEX, QHeaderView::Interactive);
|
||||||
header()->setSectionResizeMode(MSG_DB_CONTENTS_INDEX, QHeaderView::Interactive);
|
header()->setSectionResizeMode(MSG_DB_DCREATED_INDEX, QHeaderView::Interactive);
|
||||||
header()->setSectionResizeMode(MSG_DB_PDELETED_INDEX, QHeaderView::Interactive);
|
header()->setSectionResizeMode(MSG_DB_CONTENTS_INDEX, QHeaderView::Interactive);
|
||||||
//header()->resizeSection(MSG_DB_READ_INDEX, MESSAGES_VIEW_MINIMUM_COL);
|
header()->setSectionResizeMode(MSG_DB_PDELETED_INDEX, QHeaderView::Interactive);
|
||||||
//header()->resizeSection(MSG_DB_IMPORTANT_INDEX, MESSAGES_VIEW_MINIMUM_COL);
|
|
||||||
// Hide columns.
|
//header()->resizeSection(MSG_DB_READ_INDEX, MESSAGES_VIEW_MINIMUM_COL);
|
||||||
hideColumn(MSG_DB_ID_INDEX);
|
//header()->resizeSection(MSG_DB_IMPORTANT_INDEX, MESSAGES_VIEW_MINIMUM_COL);
|
||||||
hideColumn(MSG_DB_DELETED_INDEX);
|
// Hide columns.
|
||||||
hideColumn(MSG_DB_URL_INDEX);
|
hideColumn(MSG_DB_ID_INDEX);
|
||||||
hideColumn(MSG_DB_CONTENTS_INDEX);
|
hideColumn(MSG_DB_DELETED_INDEX);
|
||||||
hideColumn(MSG_DB_PDELETED_INDEX);
|
hideColumn(MSG_DB_URL_INDEX);
|
||||||
hideColumn(MSG_DB_ENCLOSURES_INDEX);
|
hideColumn(MSG_DB_CONTENTS_INDEX);
|
||||||
hideColumn(MSG_DB_ACCOUNT_ID_INDEX);
|
hideColumn(MSG_DB_PDELETED_INDEX);
|
||||||
hideColumn(MSG_DB_CUSTOM_ID_INDEX);
|
hideColumn(MSG_DB_ENCLOSURES_INDEX);
|
||||||
hideColumn(MSG_DB_CUSTOM_HASH_INDEX);
|
hideColumn(MSG_DB_ACCOUNT_ID_INDEX);
|
||||||
hideColumn(MSG_DB_FEED_CUSTOM_ID_INDEX);
|
hideColumn(MSG_DB_CUSTOM_ID_INDEX);
|
||||||
qDebug("Adjusting column resize modes for MessagesView.");
|
hideColumn(MSG_DB_CUSTOM_HASH_INDEX);
|
||||||
}
|
hideColumn(MSG_DB_FEED_CUSTOM_ID_INDEX);
|
||||||
|
qDebug("Adjusting column resize modes for MessagesView.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessagesView::onSortIndicatorChanged(int column, Qt::SortOrder order) {
|
void MessagesView::onSortIndicatorChanged(int column, Qt::SortOrder order) {
|
||||||
// Repopulate the shit.
|
// Repopulate the shit.
|
||||||
sort(column, order, true, false, false);
|
sort(column, order, true, false, false);
|
||||||
emit currentMessageRemoved();
|
|
||||||
|
emit currentMessageRemoved();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -22,106 +23,101 @@
|
|||||||
|
|
||||||
#include "services/abstract/rootitem.h"
|
#include "services/abstract/rootitem.h"
|
||||||
|
|
||||||
#include <QTreeView>
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
class MessagesProxyModel;
|
class MessagesProxyModel;
|
||||||
|
|
||||||
class MessagesView : public QTreeView {
|
class MessagesView : public QTreeView {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructors and destructors.
|
explicit MessagesView(QWidget* parent = 0);
|
||||||
explicit MessagesView(QWidget* parent = 0);
|
virtual ~MessagesView();
|
||||||
virtual ~MessagesView();
|
|
||||||
|
|
||||||
// Model accessors.
|
// Model accessors.
|
||||||
inline MessagesProxyModel* model() const {
|
inline MessagesProxyModel* model() const {
|
||||||
return m_proxyModel;
|
return m_proxyModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MessagesModel* sourceModel() const {
|
inline MessagesModel* sourceModel() const {
|
||||||
return m_sourceModel;
|
return m_sourceModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void keyboardSearch(const QString& search);
|
void keyboardSearch(const QString& search);
|
||||||
|
|
||||||
// Called after data got changed externally
|
// Called after data got changed externally
|
||||||
// and it needs to be reloaded to the view.
|
// and it needs to be reloaded to the view.
|
||||||
void reloadSelections();
|
void reloadSelections();
|
||||||
|
|
||||||
// Loads un-deleted messages from selected feeds.
|
// Loads un-deleted messages from selected feeds.
|
||||||
void loadItem(RootItem* item);
|
void loadItem(RootItem* item);
|
||||||
|
|
||||||
// Message manipulators.
|
// Message manipulators.
|
||||||
void openSelectedSourceMessagesExternally();
|
void openSelectedSourceMessagesExternally();
|
||||||
void openSelectedMessagesInternally();
|
void openSelectedMessagesInternally();
|
||||||
void sendSelectedMessageViaEmail();
|
void sendSelectedMessageViaEmail();
|
||||||
|
|
||||||
// Works with SELECTED messages only.
|
// Works with SELECTED messages only.
|
||||||
void setSelectedMessagesReadStatus(RootItem::ReadStatus read);
|
void setSelectedMessagesReadStatus(RootItem::ReadStatus read);
|
||||||
void markSelectedMessagesRead();
|
void markSelectedMessagesRead();
|
||||||
void markSelectedMessagesUnread();
|
void markSelectedMessagesUnread();
|
||||||
void switchSelectedMessagesImportance();
|
void switchSelectedMessagesImportance();
|
||||||
void deleteSelectedMessages();
|
void deleteSelectedMessages();
|
||||||
void restoreSelectedMessages();
|
void restoreSelectedMessages();
|
||||||
|
|
||||||
void selectNextItem();
|
void selectNextItem();
|
||||||
void selectPreviousItem();
|
void selectPreviousItem();
|
||||||
void selectNextUnreadItem();
|
void selectNextUnreadItem();
|
||||||
|
|
||||||
// Searchs the visible message according to given pattern.
|
// Searchs the visible message according to given pattern.
|
||||||
void searchMessages(const QString& pattern);
|
void searchMessages(const QString& pattern);
|
||||||
void filterMessages(MessagesModel::MessageHighlighter filter);
|
void filterMessages(MessagesModel::MessageHighlighter filter);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void openSelectedMessagesWithExternalTool();
|
void openSelectedMessagesWithExternalTool();
|
||||||
|
|
||||||
// Marks given indexes as selected.
|
// Marks given indexes as selected.
|
||||||
void reselectIndexes(const QModelIndexList& indexes);
|
void reselectIndexes(const QModelIndexList& indexes);
|
||||||
|
|
||||||
// Changes resize mode for all columns.
|
// Changes resize mode for all columns.
|
||||||
void adjustColumns();
|
void adjustColumns();
|
||||||
|
|
||||||
// Saves current sort state.
|
// Saves current sort state.
|
||||||
void onSortIndicatorChanged(int column, Qt::SortOrder order);
|
void onSortIndicatorChanged(int column, Qt::SortOrder order);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Link/message openers.
|
void openLinkNewTab(const QString& link);
|
||||||
void openLinkNewTab(const QString& link);
|
void openLinkMiniBrowser(const QString& link);
|
||||||
void openLinkMiniBrowser(const QString& link);
|
void openMessagesInNewspaperView(RootItem* root, const QList<Message>& messages);
|
||||||
void openMessagesInNewspaperView(RootItem* root, const QList<Message>& messages);
|
|
||||||
|
|
||||||
// Notify others about message selections.
|
// Notify others about message selections.
|
||||||
void currentMessageChanged(const Message& message, RootItem* root);
|
void currentMessageChanged(const Message& message, RootItem* root);
|
||||||
void currentMessageRemoved();
|
void currentMessageRemoved();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header);
|
void sort(int column, Qt::SortOrder order, bool repopulate_data, bool change_header, bool emit_changed_from_header);
|
||||||
|
|
||||||
// Creates needed connections.
|
// Creates needed connections.
|
||||||
void createConnections();
|
void createConnections();
|
||||||
|
|
||||||
// Initializes context menu.
|
// Initializes context menu.
|
||||||
void initializeContextMenu();
|
void initializeContextMenu();
|
||||||
|
|
||||||
// Sets up appearance.
|
// Sets up appearance.
|
||||||
void setupAppearance();
|
void setupAppearance();
|
||||||
|
|
||||||
// Event reimplementations.
|
// Event reimplementations.
|
||||||
void contextMenuEvent(QContextMenuEvent* event);
|
void contextMenuEvent(QContextMenuEvent* event);
|
||||||
void mousePressEvent(QMouseEvent* event);
|
void mousePressEvent(QMouseEvent* event);
|
||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
||||||
|
|
||||||
QMenu* m_contextMenu;
|
QMenu* m_contextMenu;
|
||||||
|
MessagesProxyModel* m_proxyModel;
|
||||||
MessagesProxyModel* m_proxyModel;
|
MessagesModel* m_sourceModel;
|
||||||
MessagesModel* m_sourceModel;
|
bool m_columnsAdjusted;
|
||||||
|
|
||||||
bool m_columnsAdjusted;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MESSAGESVIEW_H
|
#endif // MESSAGESVIEW_H
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -18,245 +19,252 @@
|
|||||||
#include "gui/statusbar.h"
|
#include "gui/statusbar.h"
|
||||||
|
|
||||||
#include "gui/dialogs/formmain.h"
|
#include "gui/dialogs/formmain.h"
|
||||||
#include "gui/tabwidget.h"
|
|
||||||
#include "gui/plaintoolbutton.h"
|
#include "gui/plaintoolbutton.h"
|
||||||
#include "miscellaneous/mutex.h"
|
#include "gui/tabwidget.h"
|
||||||
#include "miscellaneous/iconfactory.h"
|
#include "miscellaneous/iconfactory.h"
|
||||||
|
#include "miscellaneous/mutex.h"
|
||||||
|
|
||||||
#include <QToolButton>
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QProgressBar>
|
#include <QProgressBar>
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusBar::~StatusBar() {
|
StatusBar::~StatusBar() {
|
||||||
clear();
|
clear();
|
||||||
qDebug("Destroying StatusBar instance.");
|
qDebug("Destroying StatusBar instance.");
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
|
||||||
actions << m_barProgressDownloadAction << m_barProgressFeedsAction <<
|
// Now, add placeholder actions for custom stuff.
|
||||||
m_lblProgressDownloadAction << m_lblProgressFeedsAction;
|
actions << m_barProgressDownloadAction << m_barProgressFeedsAction << m_lblProgressDownloadAction << m_lblProgressFeedsAction;
|
||||||
return actions;
|
|
||||||
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QAction*> StatusBar::changeableActions() const {
|
QList<QAction*> StatusBar::changeableActions() const {
|
||||||
return actions();
|
return actions();
|
||||||
}
|
}
|
||||||
|
|
||||||
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(",")));
|
|
||||||
loadSpecificActions(getSpecificActions(actions));
|
qApp->settings()->setValue(GROUP(GUI), GUI::StatusbarActions, actions.join(QSL(",")));
|
||||||
|
loadSpecificActions(getSpecificActions(actions));
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList StatusBar::defaultActions() const {
|
QStringList StatusBar::defaultActions() const {
|
||||||
return QString(GUI::StatusbarActionsDef).split(',', QString::SkipEmptyParts);
|
return QString(GUI::StatusbarActionsDef).split(',', QString::SkipEmptyParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList StatusBar::savedActions() const {
|
QStringList StatusBar::savedActions() const {
|
||||||
return qApp->settings()->value(GROUP(GUI), SETTING(GUI::StatusbarActions)).toString().split(',', QString::SkipEmptyParts);
|
return qApp->settings()->value(GROUP(GUI), SETTING(GUI::StatusbarActions)).toString().split(',',QString::SkipEmptyParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QAction*> StatusBar::getSpecificActions(const QStringList& actions) {
|
QList<QAction*> StatusBar::getSpecificActions(const QStringList& actions) {
|
||||||
bool progress_visible = this->actions().contains(m_barProgressFeedsAction) &&
|
bool progress_visible = this->actions().contains(m_barProgressFeedsAction) && m_lblProgressFeeds->isVisible() &&
|
||||||
m_lblProgressFeeds->isVisible() &&
|
m_barProgressFeeds->isVisible();
|
||||||
m_barProgressFeeds->isVisible();
|
|
||||||
QList<QAction*> available_actions = availableActions();
|
|
||||||
QList<QAction*> spec_actions;
|
|
||||||
|
|
||||||
// Iterate action names and add respectable actions into the toolbar.
|
QList<QAction*> available_actions = availableActions();
|
||||||
foreach (const QString& action_name, actions) {
|
QList<QAction*> spec_actions;
|
||||||
QAction* matching_action = findMatchingAction(action_name, available_actions);
|
|
||||||
QAction* action_to_add;
|
|
||||||
QWidget* widget_to_add;
|
|
||||||
|
|
||||||
if (matching_action == m_barProgressDownloadAction) {
|
// Iterate action names and add respectable
|
||||||
widget_to_add = m_barProgressDownload;
|
// actions into the toolbar.
|
||||||
action_to_add = m_barProgressDownloadAction;
|
foreach (const QString& action_name, actions) {
|
||||||
widget_to_add->setVisible(false);
|
QAction* matching_action = findMatchingAction(action_name, available_actions);
|
||||||
}
|
QAction* action_to_add;
|
||||||
else if (matching_action == m_barProgressFeedsAction) {
|
QWidget* widget_to_add;
|
||||||
widget_to_add = m_barProgressFeeds;
|
|
||||||
action_to_add = m_barProgressFeedsAction;
|
|
||||||
widget_to_add->setVisible(progress_visible);
|
|
||||||
}
|
|
||||||
else if (matching_action == m_lblProgressDownloadAction) {
|
|
||||||
widget_to_add = m_lblProgressDownload;
|
|
||||||
action_to_add = m_lblProgressDownloadAction;
|
|
||||||
widget_to_add->setVisible(false);
|
|
||||||
}
|
|
||||||
else if (matching_action == m_lblProgressFeedsAction) {
|
|
||||||
widget_to_add = m_lblProgressFeeds;
|
|
||||||
action_to_add = m_lblProgressFeedsAction;
|
|
||||||
widget_to_add->setVisible(progress_visible);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (action_name == SEPARATOR_ACTION_NAME) {
|
|
||||||
QLabel* lbl = new QLabel(QString::fromUtf8("•"));
|
|
||||||
widget_to_add = lbl;
|
|
||||||
action_to_add = new QAction(this);
|
|
||||||
action_to_add->setSeparator(true);
|
|
||||||
action_to_add->setProperty("should_remove_action", true);
|
|
||||||
}
|
|
||||||
else if (action_name == SPACER_ACTION_NAME) {
|
|
||||||
QLabel* lbl = new QLabel(QSL("\t\t"));
|
|
||||||
widget_to_add = lbl;
|
|
||||||
action_to_add = new QAction(this);
|
|
||||||
action_to_add->setProperty("should_remove_action", true);
|
|
||||||
action_to_add->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
|
|
||||||
action_to_add->setProperty("type", SPACER_ACTION_NAME);
|
|
||||||
action_to_add->setProperty("name", tr("Toolbar spacer"));
|
|
||||||
}
|
|
||||||
else if (matching_action != nullptr) {
|
|
||||||
// Add originally toolbar action.
|
|
||||||
PlainToolButton* tool_button = new PlainToolButton(this);
|
|
||||||
tool_button->reactOnActionChange(matching_action);
|
|
||||||
widget_to_add = tool_button;
|
|
||||||
action_to_add = matching_action;
|
|
||||||
connect(tool_button, &PlainToolButton::clicked, matching_action, &QAction::trigger);
|
|
||||||
connect(matching_action, &QAction::changed, tool_button, &PlainToolButton::reactOnSenderActionChange);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
action_to_add = nullptr;
|
|
||||||
widget_to_add = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action_to_add != nullptr) {
|
if (matching_action == m_barProgressDownloadAction) {
|
||||||
action_to_add->setProperty("should_remove_widget", true);
|
widget_to_add = m_barProgressDownload;
|
||||||
}
|
action_to_add = m_barProgressDownloadAction;
|
||||||
}
|
widget_to_add->setVisible(false);
|
||||||
|
}
|
||||||
|
else if (matching_action == m_barProgressFeedsAction) {
|
||||||
|
widget_to_add = m_barProgressFeeds;
|
||||||
|
action_to_add = m_barProgressFeedsAction;
|
||||||
|
widget_to_add->setVisible(progress_visible);
|
||||||
|
}
|
||||||
|
else if (matching_action == m_lblProgressDownloadAction) {
|
||||||
|
widget_to_add = m_lblProgressDownload;
|
||||||
|
action_to_add = m_lblProgressDownloadAction;
|
||||||
|
widget_to_add->setVisible(false);
|
||||||
|
}
|
||||||
|
else if (matching_action == m_lblProgressFeedsAction) {
|
||||||
|
widget_to_add = m_lblProgressFeeds;
|
||||||
|
action_to_add = m_lblProgressFeedsAction;
|
||||||
|
widget_to_add->setVisible(progress_visible);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (action_name == SEPARATOR_ACTION_NAME) {
|
||||||
|
QLabel* lbl = new QLabel(QString::fromUtf8("•"));
|
||||||
|
|
||||||
if (action_to_add != nullptr && widget_to_add != nullptr) {
|
widget_to_add = lbl;
|
||||||
action_to_add->setProperty("widget", QVariant::fromValue((void*) widget_to_add));
|
action_to_add = new QAction(this);
|
||||||
spec_actions.append(action_to_add);
|
action_to_add->setSeparator(true);
|
||||||
}
|
action_to_add->setProperty("should_remove_action", true);
|
||||||
}
|
}
|
||||||
|
else if (action_name == SPACER_ACTION_NAME) {
|
||||||
|
QLabel* lbl = new QLabel(QSL("\t\t"));
|
||||||
|
|
||||||
return spec_actions;
|
widget_to_add = lbl;
|
||||||
|
action_to_add = new QAction(this);
|
||||||
|
action_to_add->setProperty("should_remove_action", true);
|
||||||
|
action_to_add->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
|
||||||
|
action_to_add->setProperty("type", SPACER_ACTION_NAME);
|
||||||
|
action_to_add->setProperty("name", tr("Toolbar spacer"));
|
||||||
|
}
|
||||||
|
else if (matching_action != nullptr) {
|
||||||
|
// Add originally toolbar action.
|
||||||
|
PlainToolButton* tool_button = new PlainToolButton(this);
|
||||||
|
|
||||||
|
tool_button->reactOnActionChange(matching_action);
|
||||||
|
widget_to_add = tool_button;
|
||||||
|
action_to_add = matching_action;
|
||||||
|
connect(tool_button, &PlainToolButton::clicked, matching_action, &QAction::trigger);
|
||||||
|
connect(matching_action, &QAction::changed, tool_button,&PlainToolButton::reactOnSenderActionChange);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
action_to_add = nullptr;
|
||||||
|
widget_to_add = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action_to_add != nullptr) {
|
||||||
|
action_to_add->setProperty("should_remove_widget", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action_to_add != nullptr && widget_to_add != nullptr) {
|
||||||
|
action_to_add->setProperty("widget", QVariant::fromValue((void*) widget_to_add));
|
||||||
|
spec_actions.append(action_to_add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec_actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBar::loadSpecificActions(const QList<QAction*>& actions) {
|
void StatusBar::loadSpecificActions(const QList<QAction*>& actions) {
|
||||||
foreach (QAction* act, this->actions()) {
|
foreach (QAction* act, this->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;
|
||||||
|
|
||||||
if (widget != nullptr) {
|
if (widget != nullptr) {
|
||||||
removeWidget(widget);
|
removeWidget(widget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeWidget(m_barProgressDownload);
|
removeWidget(m_barProgressDownload);
|
||||||
removeWidget(m_barProgressFeeds);
|
removeWidget(m_barProgressFeeds);
|
||||||
removeWidget(m_lblProgressDownload);
|
removeWidget(m_lblProgressDownload);
|
||||||
removeWidget(m_lblProgressFeeds);
|
removeWidget(m_lblProgressFeeds);
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// And also add widget.
|
addAction(act);
|
||||||
if (widget != nullptr) {
|
|
||||||
addPermanentWidget(widget);
|
// And also add widget.
|
||||||
}
|
if (widget != nullptr) {
|
||||||
}
|
addPermanentWidget(widget);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StatusBar::eventFilter(QObject* watched, QEvent* event) {
|
bool StatusBar::eventFilter(QObject* watched, QEvent* event) {
|
||||||
if (watched == m_lblProgressDownload || watched == m_barProgressDownload) {
|
if (watched == m_lblProgressDownload || watched == m_barProgressDownload) {
|
||||||
if (event->type() == QEvent::MouseButtonPress) {
|
if (event->type() == QEvent::MouseButtonPress) {
|
||||||
qApp->mainForm()->tabWidget()->showDownloadManager();
|
qApp->mainForm()->tabWidget()->showDownloadManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBar::clear() {
|
void StatusBar::clear() {
|
||||||
while (!actions().isEmpty()) {
|
while (!actions().isEmpty()) {
|
||||||
QAction* act = actions().at(0);
|
QAction* act = actions().at(0);
|
||||||
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);
|
|
||||||
|
|
||||||
if (widget != nullptr) {
|
removeAction(act);
|
||||||
removeWidget(widget);
|
|
||||||
widget->setVisible(false);
|
|
||||||
|
|
||||||
if (should_remove_widget) {
|
if (widget != nullptr) {
|
||||||
widget->deleteLater();
|
removeWidget(widget);
|
||||||
}
|
widget->setVisible(false);
|
||||||
|
|
||||||
if (should_remove_action) {
|
if (should_remove_widget) {
|
||||||
act->deleteLater();
|
widget->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
if (should_remove_action) {
|
||||||
|
act->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBar::showProgressFeeds(int progress, const QString& label) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBar::clearProgressFeeds() {
|
void StatusBar::clearProgressFeeds() {
|
||||||
m_lblProgressFeeds->setVisible(false);
|
m_lblProgressFeeds->setVisible(false);
|
||||||
m_barProgressFeeds->setVisible(false);
|
m_barProgressFeeds->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBar::showProgressDownload(int progress, const QString& tooltip) {
|
void StatusBar::showProgressDownload(int progress, const QString& tooltip) {
|
||||||
if (actions().contains(m_barProgressDownloadAction)) {
|
if (actions().contains(m_barProgressDownloadAction)) {
|
||||||
m_lblProgressDownload->setVisible(true);
|
m_lblProgressDownload->setVisible(true);
|
||||||
m_barProgressDownload->setVisible(true);
|
m_barProgressDownload->setVisible(true);
|
||||||
m_barProgressDownload->setValue(progress);
|
m_barProgressDownload->setValue(progress);
|
||||||
m_barProgressDownload->setToolTip(tooltip);
|
m_barProgressDownload->setToolTip(tooltip);
|
||||||
m_lblProgressDownload->setToolTip(tooltip);
|
m_lblProgressDownload->setToolTip(tooltip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBar::clearProgressDownload() {
|
void StatusBar::clearProgressDownload() {
|
||||||
m_lblProgressDownload->setVisible(false);
|
m_lblProgressDownload->setVisible(false);
|
||||||
m_barProgressDownload->setVisible(false);
|
m_barProgressDownload->setVisible(false);
|
||||||
m_barProgressDownload->setValue(0);
|
m_barProgressDownload->setValue(0);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// This file is part of RSS Guard.
|
// This file is part of RSS Guard.
|
||||||
|
|
||||||
//
|
//
|
||||||
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
// Copyright (C) 2011-2017 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
//
|
//
|
||||||
@ -22,55 +23,48 @@
|
|||||||
|
|
||||||
#include "gui/basetoolbar.h"
|
#include "gui/basetoolbar.h"
|
||||||
|
|
||||||
|
|
||||||
class QProgressBar;
|
class QProgressBar;
|
||||||
class PlainToolButton;
|
class PlainToolButton;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class Mutex;
|
class Mutex;
|
||||||
|
|
||||||
class StatusBar : public QStatusBar, public BaseBar {
|
class StatusBar : public QStatusBar, public BaseBar {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructors and destructors.
|
explicit StatusBar(QWidget* parent = 0);
|
||||||
explicit StatusBar(QWidget* parent = 0);
|
virtual ~StatusBar();
|
||||||
virtual ~StatusBar();
|
|
||||||
|
|
||||||
QList<QAction*> availableActions() const;
|
QList<QAction*> availableActions() const;
|
||||||
QList<QAction*> changeableActions() const;
|
QList<QAction*> changeableActions() const;
|
||||||
void saveChangeableActions(const QStringList& actions);
|
void saveChangeableActions(const QStringList& actions);
|
||||||
QStringList defaultActions() const;
|
QStringList defaultActions() const;
|
||||||
QStringList savedActions() const;
|
QStringList savedActions() const;
|
||||||
QList<QAction*> getSpecificActions(const QStringList& actions);
|
QList<QAction*> getSpecificActions(const QStringList& actions);
|
||||||
void loadSpecificActions(const QList<QAction*>& actions);
|
void loadSpecificActions(const QList<QAction*>& actions);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// Progress bar operations
|
void showProgressFeeds(int progress, const QString& label);
|
||||||
void showProgressFeeds(int progress, const QString& label);
|
void clearProgressFeeds();
|
||||||
void clearProgressFeeds();
|
|
||||||
|
|
||||||
void showProgressDownload(int progress, const QString& tooltip);
|
void showProgressDownload(int progress, const QString& tooltip);
|
||||||
void clearProgressDownload();
|
void clearProgressDownload();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject* watched, QEvent* event);
|
bool eventFilter(QObject* watched, QEvent* event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
Mutex* m_mutex;
|
Mutex* m_mutex;
|
||||||
|
QProgressBar* m_barProgressFeeds;
|
||||||
QProgressBar* m_barProgressFeeds;
|
QAction* m_barProgressFeedsAction;
|
||||||
QAction* m_barProgressFeedsAction;
|
QLabel* m_lblProgressFeeds;
|
||||||
|
QAction* m_lblProgressFeedsAction;
|
||||||
QLabel* m_lblProgressFeeds;
|
QProgressBar* m_barProgressDownload;
|
||||||
QAction* m_lblProgressFeedsAction;
|
QAction* m_barProgressDownloadAction;
|
||||||
|
QLabel* m_lblProgressDownload;
|
||||||
QProgressBar* m_barProgressDownload;
|
QAction* m_lblProgressDownloadAction;
|
||||||
QAction* m_barProgressDownloadAction;
|
|
||||||
|
|
||||||
QLabel* m_lblProgressDownload;
|
|
||||||
QAction* m_lblProgressDownloadAction;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STATUSBAR_H
|
#endif // STATUSBAR_H
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
|
|
||||||
#include "services/owncloud/network/owncloudnetworkfactory.h"
|
#include "services/owncloud/network/owncloudnetworkfactory.h"
|
||||||
|
|
||||||
#include "services/owncloud/definitions.h"
|
|
||||||
#include "network-web/networkfactory.h"
|
|
||||||
#include "miscellaneous/application.h"
|
#include "miscellaneous/application.h"
|
||||||
#include "miscellaneous/settings.h"
|
#include "miscellaneous/settings.h"
|
||||||
#include "miscellaneous/textfactory.h"
|
#include "miscellaneous/textfactory.h"
|
||||||
|
#include "network-web/networkfactory.h"
|
||||||
#include "services/abstract/rootitem.h"
|
#include "services/abstract/rootitem.h"
|
||||||
|
#include "services/owncloud/definitions.h"
|
||||||
#include "services/owncloud/owncloudcategory.h"
|
#include "services/owncloud/owncloudcategory.h"
|
||||||
#include "services/owncloud/owncloudfeed.h"
|
#include "services/owncloud/owncloudfeed.h"
|
||||||
|
|
||||||
@ -33,298 +33,327 @@
|
|||||||
|
|
||||||
|
|
||||||
OwnCloudNetworkFactory::OwnCloudNetworkFactory()
|
OwnCloudNetworkFactory::OwnCloudNetworkFactory()
|
||||||
: m_url(QString()), m_fixedUrl(QString()), m_forceServerSideUpdate(false),
|
: m_url(QString()), m_fixedUrl(QString()), m_forceServerSideUpdate(false),
|
||||||
m_authUsername(QString()), m_authPassword(QString()), m_batchSize(-1), m_urlUser(QString()), m_urlStatus(QString()),
|
m_authUsername(QString()), m_authPassword(QString()), m_batchSize(-1), m_urlUser(QString()), m_urlStatus(QString()),
|
||||||
m_urlFolders(QString()), m_urlFeeds(QString()), m_urlMessages(QString()), m_urlFeedsUpdate(QString()),
|
m_urlFolders(QString()), m_urlFeeds(QString()), m_urlMessages(QString()), m_urlFeedsUpdate(QString()),
|
||||||
m_urlDeleteFeed(QString()), m_urlRenameFeed(QString()), m_userId(QString()) {
|
m_urlDeleteFeed(QString()), m_urlRenameFeed(QString()), m_userId(QString()) {}
|
||||||
}
|
|
||||||
|
|
||||||
OwnCloudNetworkFactory::~OwnCloudNetworkFactory() {
|
OwnCloudNetworkFactory::~OwnCloudNetworkFactory() {}
|
||||||
}
|
|
||||||
|
|
||||||
QString OwnCloudNetworkFactory::url() const {
|
QString OwnCloudNetworkFactory::url() const {
|
||||||
return m_url;
|
return m_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OwnCloudNetworkFactory::setUrl(const QString& url) {
|
void OwnCloudNetworkFactory::setUrl(const QString& url) {
|
||||||
m_url = url;
|
m_url = url;
|
||||||
|
|
||||||
if (url.endsWith('/')) {
|
if (url.endsWith('/')
|
||||||
m_fixedUrl = url;
|
) {
|
||||||
}
|
m_fixedUrl = url;
|
||||||
else {
|
}
|
||||||
m_fixedUrl = url + '/';
|
else {
|
||||||
}
|
m_fixedUrl = url + '/';
|
||||||
|
}
|
||||||
|
|
||||||
// Store endpoints.
|
// Store endpoints.
|
||||||
m_urlUser = m_fixedUrl + API_PATH + "user";
|
m_urlUser = m_fixedUrl + API_PATH + "user";
|
||||||
m_urlStatus = m_fixedUrl + API_PATH + "status";
|
m_urlStatus = m_fixedUrl + API_PATH + "status";
|
||||||
m_urlFolders = m_fixedUrl + API_PATH + "folders";
|
m_urlFolders = m_fixedUrl + API_PATH + "folders";
|
||||||
m_urlFeeds = m_fixedUrl + API_PATH + "feeds";
|
m_urlFeeds = m_fixedUrl + API_PATH + "feeds";
|
||||||
m_urlMessages = m_fixedUrl + API_PATH + "items?id=%1&batchSize=%2&type=%3";
|
m_urlMessages = m_fixedUrl + API_PATH + "items?id=%1&batchSize=%2&type=%3";
|
||||||
m_urlFeedsUpdate = m_fixedUrl + API_PATH + "feeds/update?userId=%1&feedId=%2";
|
m_urlFeedsUpdate = m_fixedUrl + API_PATH + "feeds/update?userId=%1&feedId=%2";
|
||||||
m_urlDeleteFeed = m_fixedUrl + API_PATH + "feeds/%1";
|
m_urlDeleteFeed = m_fixedUrl + API_PATH + "feeds/%1";
|
||||||
m_urlRenameFeed = m_fixedUrl + API_PATH + "feeds/%1/rename";
|
m_urlRenameFeed = m_fixedUrl + API_PATH + "feeds/%1/rename";
|
||||||
setUserId(QString());
|
setUserId(QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OwnCloudNetworkFactory::forceServerSideUpdate() const {
|
bool OwnCloudNetworkFactory::forceServerSideUpdate() const {
|
||||||
return m_forceServerSideUpdate;
|
return m_forceServerSideUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OwnCloudNetworkFactory::setForceServerSideUpdate(bool force_update) {
|
void OwnCloudNetworkFactory::setForceServerSideUpdate(bool force_update) {
|
||||||
m_forceServerSideUpdate = force_update;
|
m_forceServerSideUpdate = force_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OwnCloudNetworkFactory::authUsername() const {
|
QString OwnCloudNetworkFactory::authUsername() const {
|
||||||
return m_authUsername;
|
return m_authUsername;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OwnCloudNetworkFactory::setAuthUsername(const QString& auth_username) {
|
void OwnCloudNetworkFactory::setAuthUsername(const QString& auth_username) {
|
||||||
m_authUsername = auth_username;
|
m_authUsername = auth_username;
|
||||||
setUserId(QString());
|
setUserId(QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OwnCloudNetworkFactory::authPassword() const {
|
QString OwnCloudNetworkFactory::authPassword() const {
|
||||||
return m_authPassword;
|
return m_authPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OwnCloudNetworkFactory::setAuthPassword(const QString& auth_password) {
|
void OwnCloudNetworkFactory::setAuthPassword(const QString& auth_password) {
|
||||||
m_authPassword = auth_password;
|
m_authPassword = auth_password;
|
||||||
setUserId(QString());
|
setUserId(QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply::NetworkError OwnCloudNetworkFactory::lastError() const {
|
QNetworkReply::NetworkError OwnCloudNetworkFactory::lastError() const {
|
||||||
return m_lastError;
|
return m_lastError;
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnCloudUserResponse OwnCloudNetworkFactory::userInfo() {
|
OwnCloudUserResponse OwnCloudNetworkFactory::userInfo() {
|
||||||
QByteArray result_raw;
|
QByteArray result_raw;
|
||||||
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlUser,
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlUser,
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
QByteArray(), QString(), result_raw,
|
QByteArray(), QString(), result_raw,
|
||||||
QNetworkAccessManager::GetOperation,
|
QNetworkAccessManager::GetOperation,
|
||||||
true, m_authUsername, m_authPassword,
|
true, m_authUsername, m_authPassword,
|
||||||
true);
|
true);
|
||||||
OwnCloudUserResponse user_response(QString::fromUtf8(result_raw));
|
OwnCloudUserResponse user_response(QString::fromUtf8(result_raw));
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
qWarning("ownCloud: Obtaining user info failed with error %d.", network_reply.first);
|
) {
|
||||||
}
|
qWarning("ownCloud: Obtaining user info failed with error %d.", network_reply.first);
|
||||||
|
}
|
||||||
|
|
||||||
m_lastError = network_reply.first;
|
m_lastError = network_reply.first;
|
||||||
return user_response;
|
return user_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnCloudStatusResponse OwnCloudNetworkFactory::status() {
|
OwnCloudStatusResponse OwnCloudNetworkFactory::status() {
|
||||||
QByteArray result_raw;
|
QByteArray result_raw;
|
||||||
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlStatus,
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlStatus,
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
QByteArray(), QString(), result_raw,
|
QByteArray(), QString(), result_raw,
|
||||||
QNetworkAccessManager::GetOperation,
|
QNetworkAccessManager::GetOperation,
|
||||||
true, m_authUsername, m_authPassword,
|
true, m_authUsername, m_authPassword,
|
||||||
true);
|
true);
|
||||||
OwnCloudStatusResponse status_response(QString::fromUtf8(result_raw));
|
OwnCloudStatusResponse status_response(QString::fromUtf8(result_raw));
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
qWarning("ownCloud: Obtaining status info failed with error %d.", network_reply.first);
|
) {
|
||||||
}
|
qWarning("ownCloud: Obtaining status info failed with error %d.", network_reply.first);
|
||||||
|
}
|
||||||
|
|
||||||
m_lastError = network_reply.first;
|
m_lastError = network_reply.first;
|
||||||
return status_response;
|
return status_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnCloudGetFeedsCategoriesResponse OwnCloudNetworkFactory::feedsCategories() {
|
OwnCloudGetFeedsCategoriesResponse OwnCloudNetworkFactory::feedsCategories() {
|
||||||
QByteArray result_raw;
|
QByteArray result_raw;
|
||||||
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFolders,
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFolders,
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
QByteArray(), QString(), result_raw,
|
QByteArray(), QString(), result_raw,
|
||||||
QNetworkAccessManager::GetOperation,
|
QNetworkAccessManager::GetOperation,
|
||||||
true, m_authUsername, m_authPassword,
|
true, m_authUsername, m_authPassword,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
qWarning("ownCloud: Obtaining of categories failed with error %d.", network_reply.first);
|
) {
|
||||||
m_lastError = network_reply.first;
|
qWarning("ownCloud: Obtaining of categories failed with error %d.", network_reply.first);
|
||||||
return OwnCloudGetFeedsCategoriesResponse();
|
m_lastError = network_reply.first;
|
||||||
}
|
return OwnCloudGetFeedsCategoriesResponse();
|
||||||
|
}
|
||||||
|
|
||||||
QString content_categories = QString::fromUtf8(result_raw);
|
QString content_categories = QString::fromUtf8(result_raw);
|
||||||
// Now, obtain feeds.
|
|
||||||
network_reply = NetworkFactory::performNetworkOperation(m_urlFeeds,
|
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
|
||||||
QByteArray(), QString(), result_raw,
|
|
||||||
QNetworkAccessManager::GetOperation,
|
|
||||||
true, m_authUsername, m_authPassword,
|
|
||||||
true);
|
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
|
||||||
qWarning("ownCloud: Obtaining of feeds failed with error %d.", network_reply.first);
|
|
||||||
m_lastError = network_reply.first;
|
|
||||||
return OwnCloudGetFeedsCategoriesResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString content_feeds = QString::fromUtf8(result_raw);
|
// Now, obtain feeds.
|
||||||
m_lastError = network_reply.first;
|
network_reply = NetworkFactory::performNetworkOperation(m_urlFeeds,
|
||||||
return OwnCloudGetFeedsCategoriesResponse(content_categories, content_feeds);
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
|
QByteArray(), QString(), result_raw,
|
||||||
|
QNetworkAccessManager::GetOperation,
|
||||||
|
true, m_authUsername, m_authPassword,
|
||||||
|
true);
|
||||||
|
|
||||||
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
|
) {
|
||||||
|
qWarning("ownCloud: Obtaining of feeds failed with error %d.", network_reply.first);
|
||||||
|
m_lastError = network_reply.first;
|
||||||
|
return OwnCloudGetFeedsCategoriesResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString content_feeds = QString::fromUtf8(result_raw);
|
||||||
|
|
||||||
|
|
||||||
|
m_lastError = network_reply.first;
|
||||||
|
return OwnCloudGetFeedsCategoriesResponse(content_categories, content_feeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OwnCloudNetworkFactory::deleteFeed(int feed_id) {
|
bool OwnCloudNetworkFactory::deleteFeed(int feed_id) {
|
||||||
QString final_url = m_urlDeleteFeed.arg(QString::number(feed_id));
|
QString final_url = m_urlDeleteFeed.arg(QString::number(feed_id));
|
||||||
QByteArray raw_output;
|
QByteArray raw_output;
|
||||||
NetworkResult network_reply = NetworkFactory::performNetworkOperation(final_url,
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(final_url,
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
QByteArray(), QString(),
|
QByteArray(), QString(),
|
||||||
raw_output, QNetworkAccessManager::DeleteOperation,
|
raw_output, QNetworkAccessManager::DeleteOperation,
|
||||||
true, m_authUsername, m_authPassword, true);
|
true, m_authUsername, m_authPassword, true);
|
||||||
m_lastError = network_reply.first;
|
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
m_lastError = network_reply.first;
|
||||||
qWarning("ownCloud: Obtaining of categories failed with error %d.", network_reply.first);
|
|
||||||
return false;
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
}
|
) {
|
||||||
else {
|
qWarning("ownCloud: Obtaining of categories failed with error %d.", network_reply.first);
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OwnCloudNetworkFactory::createFeed(const QString& url, int parent_id) {
|
bool OwnCloudNetworkFactory::createFeed(const QString& url, int parent_id) {
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
json["url"] = url;
|
|
||||||
json["folderId"] = parent_id;
|
|
||||||
QByteArray result_raw;
|
|
||||||
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFeeds,
|
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
|
||||||
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
|
||||||
QSL("application/json"),
|
|
||||||
result_raw,
|
|
||||||
QNetworkAccessManager::PostOperation,
|
|
||||||
true, m_authUsername, m_authPassword, true);
|
|
||||||
m_lastError = network_reply.first;
|
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
json["url"] = url;
|
||||||
qWarning("ownCloud: Creating of category failed with error %d.", network_reply.first);
|
json["folderId"] = parent_id;
|
||||||
return false;
|
|
||||||
}
|
QByteArray result_raw;
|
||||||
else {
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFeeds,
|
||||||
return true;
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
}
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
|
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
||||||
|
QSL("application/json"),
|
||||||
|
result_raw,
|
||||||
|
QNetworkAccessManager::PostOperation,
|
||||||
|
true, m_authUsername, m_authPassword, true);
|
||||||
|
|
||||||
|
|
||||||
|
m_lastError = network_reply.first;
|
||||||
|
|
||||||
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
|
) {
|
||||||
|
qWarning("ownCloud: Creating of category failed with error %d.", network_reply.first);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OwnCloudNetworkFactory::renameFeed(const QString& new_name, int feed_id) {
|
bool OwnCloudNetworkFactory::renameFeed(const QString& new_name, int feed_id) {
|
||||||
QString final_url = m_urlRenameFeed.arg(QString::number(feed_id));
|
QString final_url = m_urlRenameFeed.arg(QString::number(feed_id));
|
||||||
QByteArray result_raw;
|
QByteArray result_raw;
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
json["feedTitle"] = new_name;
|
|
||||||
NetworkResult network_reply = NetworkFactory::performNetworkOperation(final_url,
|
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
|
||||||
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
|
||||||
QSL("application/json"), result_raw,
|
|
||||||
QNetworkAccessManager::PutOperation,
|
|
||||||
true, m_authUsername, m_authPassword,
|
|
||||||
true);
|
|
||||||
m_lastError = network_reply.first;
|
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
json["feedTitle"] = new_name;
|
||||||
qWarning("ownCloud: Renaming of feed failed with error %d.", network_reply.first);
|
|
||||||
return false;
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(
|
||||||
}
|
final_url,
|
||||||
else {
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
return true;
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
}
|
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
||||||
|
QSL("application/json"), result_raw,
|
||||||
|
QNetworkAccessManager::PutOperation,
|
||||||
|
true, m_authUsername, m_authPassword,
|
||||||
|
true);
|
||||||
|
|
||||||
|
|
||||||
|
m_lastError = network_reply.first;
|
||||||
|
|
||||||
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
|
) {
|
||||||
|
qWarning("ownCloud: Renaming of feed failed with error %d.", network_reply.first);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnCloudGetMessagesResponse OwnCloudNetworkFactory::getMessages(int feed_id) {
|
OwnCloudGetMessagesResponse OwnCloudNetworkFactory::getMessages(int feed_id) {
|
||||||
if (forceServerSideUpdate()) {
|
if (forceServerSideUpdate()
|
||||||
triggerFeedUpdate(feed_id);
|
) {
|
||||||
}
|
triggerFeedUpdate(feed_id);
|
||||||
|
}
|
||||||
|
|
||||||
QString final_url = m_urlMessages.arg(QString::number(feed_id),
|
QString final_url = m_urlMessages.arg(QString::number(feed_id),
|
||||||
QString::number(batchSize() <= 0 ? -1 : batchSize()),
|
QString::number(batchSize() <= 0 ? -1 : batchSize()),
|
||||||
QString::number(0));
|
QString::number(0));
|
||||||
QByteArray result_raw;
|
QByteArray result_raw;
|
||||||
NetworkResult network_reply = NetworkFactory::performNetworkOperation(final_url,
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(final_url,
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
QByteArray(), QString(), result_raw,
|
QByteArray(), QString(), result_raw,
|
||||||
QNetworkAccessManager::GetOperation,
|
QNetworkAccessManager::GetOperation,
|
||||||
true, m_authUsername, m_authPassword,
|
true, m_authUsername, m_authPassword,
|
||||||
true);
|
true);
|
||||||
OwnCloudGetMessagesResponse msgs_response(QString::fromUtf8(result_raw));
|
OwnCloudGetMessagesResponse msgs_response(QString::fromUtf8(result_raw));
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
|
||||||
qWarning("ownCloud: Obtaining messages failed with error %d.", network_reply.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lastError = network_reply.first;
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
return msgs_response;
|
) {
|
||||||
|
qWarning("ownCloud: Obtaining messages failed with error %d.", network_reply.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastError = network_reply.first;
|
||||||
|
return msgs_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkReply::NetworkError OwnCloudNetworkFactory::triggerFeedUpdate(int feed_id) {
|
QNetworkReply::NetworkError OwnCloudNetworkFactory::triggerFeedUpdate(int feed_id) {
|
||||||
if (userId().isEmpty()) {
|
if (userId().isEmpty()
|
||||||
// We need to get user ID first.
|
) {
|
||||||
OwnCloudUserResponse info = userInfo();
|
// We need to get user ID first.
|
||||||
|
OwnCloudUserResponse info = userInfo();
|
||||||
|
|
||||||
if (lastError() != QNetworkReply::NoError) {
|
|
||||||
return lastError();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// We have new user ID, set it up.
|
|
||||||
setUserId(info.userId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now, we can trigger the update.
|
if (lastError() != QNetworkReply::NoError
|
||||||
QByteArray raw_output;
|
) {
|
||||||
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFeedsUpdate.arg(userId(),
|
return lastError();
|
||||||
QString::number(feed_id)),
|
}
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
else {
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
// We have new user ID, set it up.
|
||||||
QByteArray(), QString(), raw_output,
|
setUserId(info.userId());
|
||||||
QNetworkAccessManager::GetOperation,
|
}
|
||||||
true, m_authUsername, m_authPassword,
|
}
|
||||||
true);
|
|
||||||
|
|
||||||
if (network_reply.first != QNetworkReply::NoError) {
|
// Now, we can trigger the update.
|
||||||
qWarning("ownCloud: Feeds update failed with error %d.", network_reply.first);
|
QByteArray raw_output;
|
||||||
}
|
NetworkResult network_reply = NetworkFactory::performNetworkOperation(m_urlFeedsUpdate.arg(userId(),
|
||||||
|
QString::number(feed_id)),
|
||||||
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
|
QByteArray(), QString(), raw_output,
|
||||||
|
QNetworkAccessManager::GetOperation,
|
||||||
|
true, m_authUsername, m_authPassword,
|
||||||
|
true);
|
||||||
|
|
||||||
return (m_lastError = network_reply.first);
|
if (network_reply.first != QNetworkReply::NoError
|
||||||
|
) {
|
||||||
|
qWarning("ownCloud: Feeds update failed with error %d.", network_reply.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (m_lastError = network_reply.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OwnCloudNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids) {
|
void OwnCloudNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids) {
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
QJsonArray ids;
|
QJsonArray ids;
|
||||||
QString final_url;
|
QString final_url;
|
||||||
|
|
||||||
if (status == RootItem::Read) {
|
if (status == RootItem::Read
|
||||||
final_url = m_fixedUrl + API_PATH + "items/read/multiple";
|
) {
|
||||||
}
|
final_url = m_fixedUrl + API_PATH + "items/read/multiple";
|
||||||
else {
|
}
|
||||||
final_url = m_fixedUrl + API_PATH + "items/unread/multiple";
|
else {
|
||||||
}
|
final_url = m_fixedUrl + API_PATH + "items/unread/multiple";
|
||||||
|
}
|
||||||
|
|
||||||
foreach (const QString& id, custom_ids) {
|
foreach (const QString& id, custom_ids) {
|
||||||
ids.append(QJsonValue(id.toInt()));
|
ids.append(QJsonValue(id.toInt()));
|
||||||
}
|
}
|
||||||
|
|
||||||
json["items"] = ids;
|
json["items"] = ids;
|
||||||
|
|
||||||
Downloader* downloader = NetworkFactory::performAsyncNetworkOperation(final_url,
|
Downloader* downloader = NetworkFactory::performAsyncNetworkOperation(final_url,
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
||||||
CONTENT_TYPE,
|
CONTENT_TYPE,
|
||||||
QNetworkAccessManager::PutOperation,
|
QNetworkAccessManager::PutOperation,
|
||||||
true, m_authUsername, m_authPassword,
|
true, m_authUsername, m_authPassword,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
|
||||||
QObject::connect(downloader, &Downloader::completed, downloader, &Downloader::deleteLater);
|
QObject::connect(downloader, &Downloader::completed, downloader, &Downloader::deleteLater);
|
||||||
}
|
}
|
||||||
@ -332,33 +361,38 @@ void OwnCloudNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const
|
|||||||
void OwnCloudNetworkFactory::markMessagesStarred(RootItem::Importance importance,
|
void OwnCloudNetworkFactory::markMessagesStarred(RootItem::Importance importance,
|
||||||
const QStringList& feed_ids,
|
const QStringList& feed_ids,
|
||||||
const QStringList& guid_hashes) {
|
const QStringList& guid_hashes) {
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
QJsonArray ids;
|
QJsonArray ids;
|
||||||
QString final_url;
|
QString final_url;
|
||||||
|
|
||||||
if (importance == RootItem::Important) {
|
if (importance == RootItem::Important
|
||||||
final_url = m_fixedUrl + API_PATH + "items/star/multiple";
|
) {
|
||||||
}
|
final_url = m_fixedUrl + API_PATH + "items/star/multiple";
|
||||||
else {
|
}
|
||||||
final_url = m_fixedUrl + API_PATH + "items/unstar/multiple";
|
else {
|
||||||
}
|
final_url = m_fixedUrl + API_PATH + "items/unstar/multiple";
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < feed_ids.size(); i++) {
|
for (int i = 0; i < feed_ids.size(); i++) {
|
||||||
QJsonObject item;
|
QJsonObject item;
|
||||||
item["feedId"] = feed_ids.at(i);
|
|
||||||
item["guidHash"] = guid_hashes.at(i);
|
|
||||||
ids.append(item);
|
item["feedId"] = feed_ids.at(i);
|
||||||
}
|
item["guidHash"] = guid_hashes.at(i);
|
||||||
|
ids.append(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
json["items"] = ids;
|
||||||
|
|
||||||
json["items"] = ids;
|
|
||||||
Downloader* downloader = NetworkFactory::performAsyncNetworkOperation(final_url,
|
Downloader* downloader = NetworkFactory::performAsyncNetworkOperation(final_url,
|
||||||
qApp->settings()->value(GROUP(Feeds),
|
qApp->settings()->value(GROUP(Feeds),
|
||||||
SETTING(Feeds::UpdateTimeout)).toInt(),
|
SETTING(Feeds::UpdateTimeout)).toInt(),
|
||||||
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
QJsonDocument(json).toJson(QJsonDocument::Compact),
|
||||||
CONTENT_TYPE,
|
CONTENT_TYPE,
|
||||||
QNetworkAccessManager::PutOperation,
|
QNetworkAccessManager::PutOperation,
|
||||||
true, m_authUsername, m_authPassword,
|
true, m_authUsername, m_authPassword,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
|
||||||
QObject::connect(downloader, &Downloader::completed, downloader, &Downloader::deleteLater);
|
QObject::connect(downloader, &Downloader::completed, downloader, &Downloader::deleteLater);
|
||||||
}
|
}
|
||||||
@ -380,185 +414,202 @@ void OwnCloudNetworkFactory::setUserId(const QString& userId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OwnCloudResponse::OwnCloudResponse(const QString& raw_content) {
|
OwnCloudResponse::OwnCloudResponse(const QString& raw_content) {
|
||||||
m_rawContent = QJsonDocument::fromJson(raw_content.toUtf8()).object();
|
m_rawContent = QJsonDocument::fromJson(raw_content.toUtf8()).object();
|
||||||
m_emptyString = raw_content.isEmpty();
|
m_emptyString = raw_content.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnCloudResponse::~OwnCloudResponse() {
|
OwnCloudResponse::~OwnCloudResponse() {}
|
||||||
}
|
|
||||||
|
|
||||||
bool OwnCloudResponse::isLoaded() const {
|
bool OwnCloudResponse::isLoaded() const {
|
||||||
return !m_emptyString && !m_rawContent.isEmpty();
|
return !m_emptyString && !m_rawContent.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OwnCloudResponse::toString() const {
|
QString OwnCloudResponse::toString() const {
|
||||||
return QJsonDocument(m_rawContent).toJson(QJsonDocument::Compact);
|
return QJsonDocument(m_rawContent).toJson(QJsonDocument::Compact);
|
||||||
}
|
}
|
||||||
|
|
||||||
OwnCloudUserResponse::OwnCloudUserResponse(const QString& raw_content) : OwnCloudResponse(raw_content) {
|
OwnCloudUserResponse::OwnCloudUserResponse(const QString& raw_content) : OwnCloudResponse(raw_content) {}
|
||||||
}
|
|
||||||
|
|
||||||
OwnCloudUserResponse::~OwnCloudUserResponse() {
|
OwnCloudUserResponse::~OwnCloudUserResponse() {}
|
||||||
}
|
|
||||||
|
|
||||||
QString OwnCloudUserResponse::displayName() const {
|
QString OwnCloudUserResponse::displayName() const {
|
||||||
if (isLoaded()) {
|
if (isLoaded()
|
||||||
return m_rawContent["displayName"].toString();
|
) {
|
||||||
}
|
return m_rawContent["displayName"].toString();
|
||||||
else {
|
}
|
||||||
return QString();
|
else {
|
||||||
}
|
return QString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OwnCloudUserResponse::userId() const {
|
QString OwnCloudUserResponse::userId() const {
|
||||||
if (isLoaded()) {
|
if (isLoaded()
|
||||||
return m_rawContent["userId"].toString();
|
) {
|
||||||
}
|
return m_rawContent["userId"].toString();
|
||||||
else {
|
}
|
||||||
return QString();
|
else {
|
||||||
}
|
return QString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime OwnCloudUserResponse::lastLoginTime() const {
|
QDateTime OwnCloudUserResponse::lastLoginTime() const {
|
||||||
if (isLoaded()) {
|
if (isLoaded()
|
||||||
return QDateTime::fromMSecsSinceEpoch(m_rawContent["lastLoginTimestamp"].toDouble());
|
) {
|
||||||
}
|
return QDateTime::fromMSecsSinceEpoch(m_rawContent["lastLoginTimestamp"].toDouble());
|
||||||
else {
|
}
|
||||||
return QDateTime();
|
else {
|
||||||
}
|
return QDateTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon OwnCloudUserResponse::avatar() const {
|
QIcon OwnCloudUserResponse::avatar() const {
|
||||||
if (isLoaded()) {
|
if (isLoaded()
|
||||||
QString image_data = m_rawContent["avatar"].toObject()["data"].toString();
|
) {
|
||||||
QByteArray decoded_data = QByteArray::fromBase64(image_data.toLocal8Bit());
|
QString image_data = m_rawContent["avatar"].toObject()["data"].toString();
|
||||||
QPixmap image;
|
QByteArray decoded_data = QByteArray::fromBase64(image_data.toLocal8Bit());
|
||||||
|
QPixmap image;
|
||||||
|
|
||||||
if (image.loadFromData(decoded_data)) {
|
|
||||||
return QIcon(image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return QIcon();
|
if (image.loadFromData(decoded_data)
|
||||||
|
) {
|
||||||
|
return QIcon(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OwnCloudStatusResponse::OwnCloudStatusResponse(const QString& raw_content) : OwnCloudResponse(raw_content) {
|
OwnCloudStatusResponse::OwnCloudStatusResponse(const QString& raw_content) : OwnCloudResponse(raw_content) {}
|
||||||
}
|
|
||||||
|
|
||||||
OwnCloudStatusResponse::~OwnCloudStatusResponse() {
|
OwnCloudStatusResponse::~OwnCloudStatusResponse() {}
|
||||||
}
|
|
||||||
|
|
||||||
QString OwnCloudStatusResponse::version() const {
|
QString OwnCloudStatusResponse::version() const {
|
||||||
if (isLoaded()) {
|
if (isLoaded()
|
||||||
return m_rawContent["version"].toString();
|
) {
|
||||||
}
|
return m_rawContent["version"].toString();
|
||||||
else {
|
}
|
||||||
return QString();
|
else {
|
||||||
}
|
return QString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OwnCloudStatusResponse::misconfiguredCron() const {
|
bool OwnCloudStatusResponse::misconfiguredCron() const {
|
||||||
if (isLoaded()) {
|
if (isLoaded()
|
||||||
return m_rawContent["warnings"].toObject()["improperlyConfiguredCron"].toBool();
|
) {
|
||||||
}
|
return m_rawContent["warnings"].toObject()["improperlyConfiguredCron"].toBool();
|
||||||
else {
|
}
|
||||||
return false;
|
else {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OwnCloudGetFeedsCategoriesResponse::OwnCloudGetFeedsCategoriesResponse(const QString& raw_categories,
|
OwnCloudGetFeedsCategoriesResponse::OwnCloudGetFeedsCategoriesResponse(const QString& raw_categories,
|
||||||
const QString& raw_feeds)
|
const QString& raw_feeds)
|
||||||
: m_contentCategories(raw_categories), m_contentFeeds(raw_feeds) {
|
: m_contentCategories(raw_categories), m_contentFeeds(raw_feeds) {}
|
||||||
}
|
|
||||||
|
|
||||||
OwnCloudGetFeedsCategoriesResponse::~OwnCloudGetFeedsCategoriesResponse() {
|
OwnCloudGetFeedsCategoriesResponse::~OwnCloudGetFeedsCategoriesResponse() {}
|
||||||
}
|
|
||||||
|
|
||||||
RootItem* OwnCloudGetFeedsCategoriesResponse::feedsCategories(bool obtain_icons) const {
|
RootItem* OwnCloudGetFeedsCategoriesResponse::feedsCategories(bool obtain_icons) const {
|
||||||
RootItem* parent = new RootItem();
|
RootItem* parent = new RootItem();
|
||||||
QMap<int, RootItem*>cats;
|
|
||||||
cats.insert(0, parent);
|
|
||||||
|
|
||||||
// Process categories first, then process feeds.
|
QMap<int, RootItem*>cats;
|
||||||
foreach (const QJsonValue& cat, QJsonDocument::fromJson(m_contentCategories.toUtf8()).object()["folders"].toArray()) {
|
cats.insert(0, parent);
|
||||||
QJsonObject item = cat.toObject();
|
|
||||||
OwnCloudCategory* category = new OwnCloudCategory();
|
|
||||||
category->setTitle(item["name"].toString());
|
|
||||||
category->setCustomId(item["id"].toInt());
|
|
||||||
cats.insert(category->customId(), category);
|
|
||||||
// All categories in ownCloud are top-level.
|
|
||||||
parent->appendChild(category);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have categories added, now add all feeds.
|
// Process categories first, then process feeds.
|
||||||
foreach (const QJsonValue& fed, QJsonDocument::fromJson(m_contentFeeds.toUtf8()).object()["feeds"].toArray()) {
|
foreach (const QJsonValue& cat, QJsonDocument::fromJson(m_contentCategories.toUtf8()).object()["folders"].toArray()) {
|
||||||
QJsonObject item = fed.toObject();
|
QJsonObject item = cat.toObject();
|
||||||
OwnCloudFeed* feed = new OwnCloudFeed();
|
OwnCloudCategory* category = new OwnCloudCategory();
|
||||||
|
|
||||||
if (obtain_icons) {
|
|
||||||
QString icon_path = item["faviconLink"].toString();
|
|
||||||
|
|
||||||
if (!icon_path.isEmpty()) {
|
category->setTitle(item["name"].toString());
|
||||||
QByteArray icon_data;
|
category->setCustomId(item["id"].toInt());
|
||||||
|
cats.insert(category->customId(), category);
|
||||||
|
// All categories in ownCloud are top-level.
|
||||||
|
parent->appendChild(category);
|
||||||
|
}
|
||||||
|
|
||||||
if (NetworkFactory::performNetworkOperation(icon_path, DOWNLOAD_TIMEOUT,
|
// We have categories added, now add all feeds.
|
||||||
QByteArray(), QString(), icon_data,
|
foreach (const QJsonValue& fed, QJsonDocument::fromJson(m_contentFeeds.toUtf8()).object()["feeds"].toArray()) {
|
||||||
QNetworkAccessManager::GetOperation).first == QNetworkReply::NoError) {
|
QJsonObject item = fed.toObject();
|
||||||
// Icon downloaded, set it up.
|
OwnCloudFeed* feed = new OwnCloudFeed();
|
||||||
QPixmap icon_pixmap;
|
|
||||||
icon_pixmap.loadFromData(icon_data);
|
|
||||||
feed->setIcon(QIcon(icon_pixmap));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
feed->setUrl(item["link"].toString());
|
|
||||||
feed->setTitle(item["title"].toString());
|
|
||||||
feed->setCustomId(item["id"].toInt());
|
|
||||||
qDebug("Custom ID of next fetched Nextcloud feed is '%d'.", item["id"].toInt());
|
|
||||||
cats.value(item["folderId"].toInt())->appendChild(feed);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent;
|
if (obtain_icons
|
||||||
|
) {
|
||||||
|
QString icon_path = item["faviconLink"].toString();
|
||||||
|
|
||||||
|
|
||||||
|
if (!icon_path.isEmpty()
|
||||||
|
) {
|
||||||
|
QByteArray icon_data;
|
||||||
|
|
||||||
|
|
||||||
|
if (NetworkFactory::performNetworkOperation(icon_path, DOWNLOAD_TIMEOUT,
|
||||||
|
QByteArray(), QString(), icon_data,
|
||||||
|
QNetworkAccessManager::GetOperation).first == QNetworkReply::NoError
|
||||||
|
) {
|
||||||
|
// Icon downloaded, set it up.
|
||||||
|
QPixmap icon_pixmap;
|
||||||
|
|
||||||
|
|
||||||
|
icon_pixmap.loadFromData(icon_data);
|
||||||
|
feed->setIcon(QIcon(icon_pixmap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
feed->setUrl(item["link"].toString());
|
||||||
|
feed->setTitle(item["title"].toString());
|
||||||
|
feed->setCustomId(item["id"].toInt());
|
||||||
|
qDebug("Custom ID of next fetched Nextcloud feed is '%d'.", item["id"].toInt());
|
||||||
|
cats.value(item["folderId"].toInt())->appendChild(feed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
OwnCloudGetMessagesResponse::OwnCloudGetMessagesResponse(const QString& raw_content) : OwnCloudResponse(raw_content) {
|
OwnCloudGetMessagesResponse::OwnCloudGetMessagesResponse(const QString& raw_content) : OwnCloudResponse(raw_content) {}
|
||||||
}
|
|
||||||
|
|
||||||
OwnCloudGetMessagesResponse::~OwnCloudGetMessagesResponse() {
|
OwnCloudGetMessagesResponse::~OwnCloudGetMessagesResponse() {}
|
||||||
}
|
|
||||||
|
|
||||||
QList<Message>OwnCloudGetMessagesResponse::messages() const {
|
QList<Message>OwnCloudGetMessagesResponse::messages() const {
|
||||||
QList<Message>msgs;
|
QList<Message>msgs;
|
||||||
|
|
||||||
foreach (const QJsonValue& message, m_rawContent["items"].toArray()) {
|
foreach (const QJsonValue& message, m_rawContent["items"].toArray()) {
|
||||||
QJsonObject message_map = message.toObject();
|
QJsonObject message_map = message.toObject();
|
||||||
Message msg;
|
Message msg;
|
||||||
msg.m_author = message_map["author"].toString();
|
|
||||||
msg.m_contents = message_map["body"].toString();
|
|
||||||
msg.m_created = TextFactory::parseDateTime(message_map["pubDate"].toDouble() * 1000);
|
|
||||||
msg.m_createdFromFeed = true;
|
|
||||||
msg.m_customId = QString::number(message_map["id"].toInt());
|
|
||||||
msg.m_customHash = message_map["guidHash"].toString();
|
|
||||||
QString enclosure_link = message_map["enclosureLink"].toString();
|
|
||||||
|
|
||||||
if (!enclosure_link.isEmpty()) {
|
|
||||||
Enclosure enclosure;
|
|
||||||
enclosure.m_mimeType = message_map["enclosureMime"].toString();
|
|
||||||
enclosure.m_url = enclosure_link;
|
|
||||||
msg.m_enclosures.append(enclosure);
|
|
||||||
}
|
|
||||||
|
|
||||||
msg.m_feedId = QString::number(message_map["feedId"].toInt());
|
msg.m_author = message_map["author"].toString();
|
||||||
msg.m_isImportant = message_map["starred"].toBool();
|
msg.m_contents = message_map["body"].toString();
|
||||||
msg.m_isRead = !message_map["unread"].toBool();
|
msg.m_created = TextFactory::parseDateTime(message_map["pubDate"].toDouble() * 1000);
|
||||||
msg.m_title = message_map["title"].toString();
|
msg.m_createdFromFeed = true;
|
||||||
msg.m_url = message_map["url"].toString();
|
msg.m_customId = QString::number(message_map["id"].toInt());
|
||||||
msgs.append(msg);
|
msg.m_customHash = message_map["guidHash"].toString();
|
||||||
}
|
|
||||||
|
|
||||||
return msgs;
|
QString enclosure_link = message_map["enclosureLink"].toString();
|
||||||
|
|
||||||
|
|
||||||
|
if (!enclosure_link.isEmpty()
|
||||||
|
) {
|
||||||
|
Enclosure enclosure;
|
||||||
|
|
||||||
|
|
||||||
|
enclosure.m_mimeType = message_map["enclosureMime"].toString();
|
||||||
|
enclosure.m_url = enclosure_link;
|
||||||
|
msg.m_enclosures.append(enclosure);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.m_feedId = QString::number(message_map["feedId"].toInt());
|
||||||
|
msg.m_isImportant = message_map["starred"].toBool();
|
||||||
|
msg.m_isRead = !message_map["unread"].toBool();
|
||||||
|
msg.m_title = message_map["title"].toString();
|
||||||
|
msg.m_url = message_map["url"].toString();
|
||||||
|
msgs.append(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return msgs;
|
||||||
}
|
}
|
||||||
|
@ -22,114 +22,114 @@
|
|||||||
#include "services/abstract/rootitem.h"
|
#include "services/abstract/rootitem.h"
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QString>
|
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
|
||||||
class OwnCloudResponse {
|
class OwnCloudResponse {
|
||||||
public:
|
public:
|
||||||
explicit OwnCloudResponse(const QString& raw_content = QString());
|
explicit OwnCloudResponse(const QString& raw_content = QString());
|
||||||
virtual ~OwnCloudResponse();
|
virtual ~OwnCloudResponse();
|
||||||
|
|
||||||
bool isLoaded() const;
|
bool isLoaded() const;
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QJsonObject m_rawContent;
|
QJsonObject m_rawContent;
|
||||||
bool m_emptyString;
|
bool m_emptyString;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OwnCloudUserResponse : public OwnCloudResponse {
|
class OwnCloudUserResponse : public OwnCloudResponse {
|
||||||
public:
|
public:
|
||||||
explicit OwnCloudUserResponse(const QString& raw_content = QString());
|
explicit OwnCloudUserResponse(const QString& raw_content = QString());
|
||||||
virtual ~OwnCloudUserResponse();
|
virtual ~OwnCloudUserResponse();
|
||||||
|
|
||||||
QString userId() const;
|
QString userId() const;
|
||||||
QString displayName() const;
|
QString displayName() const;
|
||||||
QDateTime lastLoginTime() const;
|
QDateTime lastLoginTime() const;
|
||||||
QIcon avatar() const;
|
QIcon avatar() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OwnCloudGetMessagesResponse : public OwnCloudResponse {
|
class OwnCloudGetMessagesResponse : public OwnCloudResponse {
|
||||||
public:
|
public:
|
||||||
explicit OwnCloudGetMessagesResponse(const QString& raw_content = QString());
|
explicit OwnCloudGetMessagesResponse(const QString& raw_content = QString());
|
||||||
virtual ~OwnCloudGetMessagesResponse();
|
virtual ~OwnCloudGetMessagesResponse();
|
||||||
|
|
||||||
QList<Message> messages() const;
|
QList<Message> messages() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OwnCloudStatusResponse : public OwnCloudResponse {
|
class OwnCloudStatusResponse : public OwnCloudResponse {
|
||||||
public:
|
public:
|
||||||
explicit OwnCloudStatusResponse(const QString& raw_content = QString());
|
explicit OwnCloudStatusResponse(const QString& raw_content = QString());
|
||||||
virtual ~OwnCloudStatusResponse();
|
virtual ~OwnCloudStatusResponse();
|
||||||
|
|
||||||
QString version() const;
|
QString version() const;
|
||||||
bool misconfiguredCron() const;
|
bool misconfiguredCron() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RootItem;
|
class RootItem;
|
||||||
|
|
||||||
class OwnCloudGetFeedsCategoriesResponse {
|
class OwnCloudGetFeedsCategoriesResponse {
|
||||||
public:
|
public:
|
||||||
explicit OwnCloudGetFeedsCategoriesResponse(const QString& raw_categories = QString(),
|
explicit OwnCloudGetFeedsCategoriesResponse(const QString& raw_categories = QString(),
|
||||||
const QString& raw_feeds = QString());
|
const QString& raw_feeds = QString());
|
||||||
virtual ~OwnCloudGetFeedsCategoriesResponse();
|
virtual ~OwnCloudGetFeedsCategoriesResponse();
|
||||||
|
|
||||||
// Returns tree of feeds/categories.
|
// Returns tree of feeds/categories.
|
||||||
// Top-level root of the tree is not needed here.
|
// Top-level root of the tree is not needed here.
|
||||||
// Returned items do not have primary IDs assigned.
|
// Returned items do not have primary IDs assigned.
|
||||||
RootItem* feedsCategories(bool obtain_icons) const;
|
RootItem* feedsCategories(bool obtain_icons) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_contentCategories;
|
QString m_contentCategories;
|
||||||
QString m_contentFeeds;
|
QString m_contentFeeds;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OwnCloudNetworkFactory {
|
class OwnCloudNetworkFactory {
|
||||||
public:
|
public:
|
||||||
explicit OwnCloudNetworkFactory();
|
explicit OwnCloudNetworkFactory();
|
||||||
virtual ~OwnCloudNetworkFactory();
|
virtual ~OwnCloudNetworkFactory();
|
||||||
|
|
||||||
QString url() const;
|
QString url() const;
|
||||||
void setUrl(const QString& url);
|
void setUrl(const QString& url);
|
||||||
|
|
||||||
bool forceServerSideUpdate() const;
|
bool forceServerSideUpdate() const;
|
||||||
void setForceServerSideUpdate(bool force_update);
|
void setForceServerSideUpdate(bool force_update);
|
||||||
|
|
||||||
QString authUsername() const;
|
QString authUsername() const;
|
||||||
void setAuthUsername(const QString& auth_username);
|
void setAuthUsername(const QString& auth_username);
|
||||||
|
|
||||||
QString authPassword() const;
|
QString authPassword() const;
|
||||||
void setAuthPassword(const QString& auth_password);
|
void setAuthPassword(const QString& auth_password);
|
||||||
|
|
||||||
QString userId() const;
|
QString userId() const;
|
||||||
void setUserId(const QString& userId);
|
void setUserId(const QString& userId);
|
||||||
|
|
||||||
QNetworkReply::NetworkError lastError() const;
|
QNetworkReply::NetworkError lastError() const;
|
||||||
|
|
||||||
// Operations.
|
// Operations.
|
||||||
|
|
||||||
// Get user info.
|
// Get user info.
|
||||||
OwnCloudUserResponse userInfo();
|
OwnCloudUserResponse userInfo();
|
||||||
|
|
||||||
// Get version info.
|
// Get version info.
|
||||||
OwnCloudStatusResponse status();
|
OwnCloudStatusResponse status();
|
||||||
|
|
||||||
// Get feeds & categories (used for sync-in).
|
// Get feeds & categories (used for sync-in).
|
||||||
OwnCloudGetFeedsCategoriesResponse feedsCategories();
|
OwnCloudGetFeedsCategoriesResponse feedsCategories();
|
||||||
|
|
||||||
// Feed operations.
|
// Feed operations.
|
||||||
bool deleteFeed(int feed_id);
|
bool deleteFeed(int feed_id);
|
||||||
bool createFeed(const QString& url, int parent_id);
|
bool createFeed(const QString& url, int parent_id);
|
||||||
bool renameFeed(const QString& new_name, int feed_id);
|
bool renameFeed(const QString& new_name, int feed_id);
|
||||||
|
|
||||||
// Get messages for given feed.
|
// Get messages for given feed.
|
||||||
OwnCloudGetMessagesResponse getMessages(int feed_id);
|
OwnCloudGetMessagesResponse getMessages(int feed_id);
|
||||||
|
|
||||||
// Misc methods.
|
// Misc methods.
|
||||||
QNetworkReply::NetworkError triggerFeedUpdate(int feed_id);
|
QNetworkReply::NetworkError triggerFeedUpdate(int feed_id);
|
||||||
void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids);
|
void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids);
|
||||||
void markMessagesStarred(RootItem::Importance importance, const QStringList& feed_ids, const QStringList& guid_hashes);
|
void markMessagesStarred(RootItem::Importance importance, const QStringList& feed_ids, const QStringList& guid_hashes);
|
||||||
|
|
||||||
@ -141,21 +141,21 @@ class OwnCloudNetworkFactory {
|
|||||||
QString m_url;
|
QString m_url;
|
||||||
QString m_fixedUrl;
|
QString m_fixedUrl;
|
||||||
bool m_forceServerSideUpdate;
|
bool m_forceServerSideUpdate;
|
||||||
QString m_authUsername;
|
QString m_authUsername;
|
||||||
QString m_authPassword;
|
QString m_authPassword;
|
||||||
QNetworkReply::NetworkError m_lastError;
|
QNetworkReply::NetworkError m_lastError;
|
||||||
int m_batchSize;
|
int m_batchSize;
|
||||||
|
|
||||||
// Endpoints.
|
// Endpoints.
|
||||||
QString m_urlUser;
|
QString m_urlUser;
|
||||||
QString m_urlStatus;
|
QString m_urlStatus;
|
||||||
QString m_urlFolders;
|
QString m_urlFolders;
|
||||||
QString m_urlFeeds;
|
QString m_urlFeeds;
|
||||||
QString m_urlMessages;
|
QString m_urlMessages;
|
||||||
QString m_urlFeedsUpdate;
|
QString m_urlFeedsUpdate;
|
||||||
QString m_urlDeleteFeed;
|
QString m_urlDeleteFeed;
|
||||||
QString m_urlRenameFeed;
|
QString m_urlRenameFeed;
|
||||||
QString m_userId;
|
QString m_userId;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OWNCLOUDNETWORKFACTORY_H
|
#endif // OWNCLOUDNETWORKFACTORY_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user