Refactored item/model data getters.

This commit is contained in:
Martin Rotter 2015-11-09 09:40:26 +01:00
parent 2d97915d86
commit b3fc86c696
13 changed files with 160 additions and 271 deletions

View File

@ -16,11 +16,12 @@
Added:
<ul>
<li style="color: red;">Brand new "service plugin system" - HIGHLY EXPERIMENTAL and REWRITTEN from scratch. Some UI features (for example drag-drop) are temporarily unavailable. Expect bugs and misunderstandings now!</li>
<li style="color: red;">Brand new "service plugin system" - HIGHLY EXPERIMENTAL and REWRITTEN from scratch. Some UI features (for example drag-drop) are temporarily unavailable. Expect bugs and misunderstandings now! Major parts of RSS Guard were completely rewritten.</li>
</ul>
Fixed:
<ul>
<li>Encoding selection widget in feed add/edit dialog now detects encodings via case insensitive string matching.</li>
<li>When removing download item from download manager via DELETE key, then "Cleanup" button is correctly disabled.</li>
</ul>

View File

@ -26,7 +26,8 @@
RootItem::RootItem(RootItem *parent_item)
: m_kind(RootItemKind::Root),
: QObject(NULL),
m_kind(RootItemKind::Root),
m_id(NO_PARENT_CATEGORY),
m_title(QString()),
m_description(QString()),
@ -50,6 +51,26 @@ void RootItem::setupFonts() {
m_boldFont = m_normalFont;
m_boldFont.setBold(true);
}
QFont RootItem::boldFont() const
{
return m_boldFont;
}
void RootItem::setBoldFont(const QFont &boldFont)
{
m_boldFont = boldFont;
}
QFont RootItem::normalFont() const
{
return m_normalFont;
}
void RootItem::setNormalFont(const QFont &normalFont)
{
m_normalFont = normalFont;
}
int RootItem::row() const {
if (m_parentItem) {
@ -65,8 +86,56 @@ QVariant RootItem::data(int column, int role) const {
Q_UNUSED(column)
Q_UNUSED(role)
// Do not return anything for the root item.
return QVariant();
switch (role) {
case Qt::EditRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return title();
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return countOfUnreadMessages();
}
else {
return QVariant();
}
case Qt::FontRole:
return countOfUnreadMessages() > 0 ? boldFont() : normalFont();
case Qt::DisplayRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return title();
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
int count_all = countOfAllMessages();
int count_unread = countOfUnreadMessages();
return qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString()
.replace(PLACEHOLDER_UNREAD_COUNTS, count_unread < 0 ? QSL('-') : QString::number(count_unread))
.replace(PLACEHOLDER_ALL_COUNTS, count_all < 0 ? QSL('-') : QString::number(count_all));
}
else {
return QVariant();
}
case Qt::DecorationRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return icon();
}
else {
return QVariant();
}
case Qt::TextAlignmentRole:
if (column == FDS_MODEL_COUNTS_INDEX) {
return Qt::AlignCenter;
}
else {
return QVariant();
}
default:
return QVariant();
}
}
int RootItem::countOfAllMessages() const {
@ -206,16 +275,3 @@ bool RootItem::removeChild(int index) {
return false;
}
}
bool RootItem::isEqual(RootItem *lhs, RootItem *rhs) {
return (lhs->kind() == rhs->kind()) && (lhs->id() == rhs->id());
}
bool RootItem::lessThan(RootItem *lhs, RootItem *rhs) {
if (lhs->kind() == rhs->kind()) {
return lhs->id() < rhs->id();
}
else {
return false;
}
}

View File

@ -127,6 +127,10 @@ class RootItem : public QObject {
return m_childItems;
}
inline void setChildItems(QList<RootItem*> child_items) {
m_childItems = child_items;
}
// Checks whether THIS object is child (direct or indirect)
// of the given root.
bool isChildOf(RootItem *root) {
@ -183,6 +187,10 @@ class RootItem : public QObject {
return m_kind;
}
inline void setKind(RootItemKind::Kind kind) {
m_kind = kind;
}
// Each item can have icon.
inline QIcon icon() const {
return m_icon;
@ -226,16 +234,18 @@ class RootItem : public QObject {
m_description = description;
}
QFont normalFont() const;
void setNormalFont(const QFont &normalFont);
QFont boldFont() const;
void setBoldFont(const QFont &boldFont);
// Converters
Category *toCategory();
Feed *toFeed();
ServiceRoot *toServiceRoot();
// Compares two model items.
static bool isEqual(RootItem *lhs, RootItem *rhs);
static bool lessThan(RootItem *lhs, RootItem *rhs);
protected:
private:
void setupFonts();
RootItemKind::Kind m_kind;

View File

@ -70,8 +70,6 @@ class Feed : public RootItem {
// Get ALL undeleted messages from this feed in one single list.
virtual QList<Message> undeletedMessages() const = 0;
//virtual bool markRead(ReadStatus read_status) = 0;
inline int autoUpdateInitialInterval() const {
return m_autoUpdateInitialInterval;
}
@ -107,7 +105,7 @@ class Feed : public RootItem {
m_status = status;
}
protected:
private:
Status m_status;
AutoUpdateType m_autoUpdateType;
int m_autoUpdateInitialInterval;

View File

@ -21,7 +21,7 @@
ServiceRoot::ServiceRoot(FeedsModel *feeds_model, RootItem *parent) : RootItem(parent), m_feedsModel(feeds_model) {
m_kind = RootItemKind::ServiceRoot;
setKind(RootItemKind::ServiceRoot);
}
ServiceRoot::~ServiceRoot() {

View File

@ -372,7 +372,7 @@ void FormStandardFeedDetails::setEditableFeed(StandardFeed *editable_feed) {
m_ui->m_txtDescription->lineEdit()->setText(editable_feed->description());
m_ui->m_btnIcon->setIcon(editable_feed->icon());
m_ui->m_cmbType->setCurrentIndex(m_ui->m_cmbType->findData(QVariant::fromValue((int) editable_feed->type())));
m_ui->m_cmbEncoding->setCurrentIndex(m_ui->m_cmbEncoding->findData(editable_feed->encoding(), Qt::DisplayRole));
m_ui->m_cmbEncoding->setCurrentIndex(m_ui->m_cmbEncoding->findData(editable_feed->encoding(), Qt::DisplayRole, Qt::MatchFixedString));
m_ui->m_gbAuthentication->setChecked(editable_feed->passwordProtected());
m_ui->m_txtUsername->lineEdit()->setText(editable_feed->username());
m_ui->m_txtPassword->lineEdit()->setText(editable_feed->password());

View File

@ -42,14 +42,15 @@ StandardCategory::StandardCategory(RootItem *parent_item) : Category(parent_item
StandardCategory::StandardCategory(const StandardCategory &other)
: Category(NULL) {
m_kind = other.kind();
m_id = other.id();
m_title = other.title();
m_description = other.description();
m_icon = other.icon();
m_creationDate = other.creationDate();
m_childItems = other.childItems();
m_parentItem = other.parent();
init();
setId(other.id());
setTitle(other.title());
setDescription(other.description());
setIcon(other.icon());
setCreationDate(other.creationDate());
setChildItems(other.childItems());
setParent(other.parent());
}
StandardCategory::~StandardCategory() {
@ -61,7 +62,7 @@ StandardServiceRoot *StandardCategory::serviceRoot() {
}
void StandardCategory::init() {
m_kind = RootItemKind::Category;
setKind(RootItemKind::Category);
}
QVariant StandardCategory::data(int column, int role) const {
@ -70,9 +71,9 @@ QVariant StandardCategory::data(int column, int role) const {
if (column == FDS_MODEL_TITLE_INDEX) {
//: Tooltip for standard feed.
return tr("%1 (category)"
"%2%3").arg(m_title,
m_description.isEmpty() ? QString() : QString('\n') + m_description,
m_childItems.size() == 0 ?
"%2%3").arg(title(),
description().isEmpty() ? QString() : QSL('\n') + description(),
childCount() == 0 ?
tr("\nThis category does not contain any nested items.") :
QString());
}
@ -84,51 +85,8 @@ QVariant StandardCategory::data(int column, int role) const {
return QVariant();
}
case Qt::EditRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return countOfUnreadMessages();
}
else {
return QVariant();
}
case Qt::FontRole:
return countOfUnreadMessages() > 0 ? m_boldFont : m_normalFont;
case Qt::DisplayRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString()
.replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
.replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
}
else {
return QVariant();
}
case Qt::DecorationRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_icon;
}
else {
return QVariant();
}
case Qt::TextAlignmentRole:
if (column == FDS_MODEL_COUNTS_INDEX) {
return Qt::AlignCenter;
}
else {
return QVariant();
}
default:
return QVariant();
return Category::data(column, role);
}
}
@ -148,7 +106,7 @@ bool StandardCategory::removeItself() {
bool children_removed = true;
// Remove all child items (feeds, categories.)
foreach (RootItem *child, m_childItems) {
foreach (RootItem *child, childItems()) {
if (child->kind() == RootItemKind::Category) {
children_removed &= static_cast<StandardCategory*>(child)->removeItself();
}
@ -158,7 +116,7 @@ bool StandardCategory::removeItself() {
}
if (children_removed) {
// Children are removed, remove this standard category too.
// Children are removed, remove this standard category too.
QSqlDatabase database = qApp->database()->connection(QSL("Category"), DatabaseFactory::FromSettings);
QSqlQuery query_remove(database);

View File

@ -44,7 +44,8 @@
#include <QXmlStreamReader>
void StandardFeed::init() {
StandardFeed::StandardFeed(RootItem *parent_item)
: Feed(parent_item) {
m_passwordProtected = false;
m_username = QString();
m_password = QString();
@ -54,12 +55,8 @@ void StandardFeed::init() {
m_unreadCount = 0;
m_encoding = QString();
m_url = QString();
m_kind = RootItemKind::Feed;
}
StandardFeed::StandardFeed(RootItem *parent_item)
: Feed(parent_item) {
init();
setKind(RootItemKind::Feed);
}
StandardFeed::StandardFeed(const StandardFeed &other)
@ -73,18 +70,20 @@ StandardFeed::StandardFeed(const StandardFeed &other)
m_unreadCount = other.countOfUnreadMessages();
m_encoding = other.encoding();
m_url = other.url();
m_kind = RootItemKind::Feed;
m_title = other.title();
m_id = other.id();
m_icon = other.icon();
m_childItems = other.childItems();
m_parentItem = other.parent();
m_creationDate = other.creationDate();
m_description = other.description();
m_status = other.status();
m_autoUpdateType = other.autoUpdateType();
m_autoUpdateInitialInterval = other.autoUpdateInitialInterval();
m_autoUpdateRemainingInterval = other.autoUpdateRemainingInterval();
setStatus(other.status());
setAutoUpdateType(other.autoUpdateType());
setAutoUpdateInitialInterval(other.autoUpdateInitialInterval());
setAutoUpdateRemainingInterval(other.autoUpdateRemainingInterval());
setKind(RootItemKind::Feed);
setTitle(other.title());
setId(other.id());
setIcon(other.icon());
setChildItems(other.childItems());
setParent(other.parent());
setCreationDate(other.creationDate());
setDescription(other.description());
}
StandardFeed::~StandardFeed() {
@ -182,8 +181,8 @@ void StandardFeed::updateCounts(bool including_total_count, bool update_feed_sta
if (query_all.exec(QString("SELECT count(*) FROM Messages WHERE feed = %1 AND is_deleted = 0 AND is_read = 0;").arg(id())) && query_all.next()) {
int new_unread_count = query_all.value(0).toInt();
if (update_feed_statuses && m_status == NewMessages && new_unread_count < m_unreadCount) {
m_status = Normal;
if (update_feed_statuses && status() == NewMessages && new_unread_count < m_unreadCount) {
setStatus(Normal);
}
m_unreadCount = new_unread_count;
@ -361,43 +360,11 @@ QPair<StandardFeed*,QNetworkReply::NetworkError> StandardFeed::guessFeed(const Q
QVariant StandardFeed::data(int column, int role) const {
switch (role) {
case Qt::DisplayRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString()
.replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
.replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
}
else {
return QVariant();
}
case Qt::EditRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return countOfUnreadMessages();
}
else {
return QVariant();
}
case Qt::DecorationRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_icon;
}
else {
return QVariant();
}
case Qt::ToolTipRole:
if (column == FDS_MODEL_TITLE_INDEX) {
QString auto_update_string;
switch (m_autoUpdateType) {
switch (autoUpdateType()) {
case DontAutoUpdate:
//: Describes feed auto-update status.
auto_update_string = tr("does not use auto-update");
@ -414,7 +381,7 @@ QVariant StandardFeed::data(int column, int role) const {
auto_update_string = tr("uses specific settings "
"(%n minute(s) to next auto-update)",
0,
m_autoUpdateRemainingInterval);
autoUpdateRemainingInterval());
break;
}
@ -423,10 +390,10 @@ QVariant StandardFeed::data(int column, int role) const {
"%3\n\n"
"Network status: %6\n"
"Encoding: %4\n"
"Auto-update status: %5").arg(m_title,
StandardFeed::typeToString(m_type),
m_description.isEmpty() ? QString() : QString('\n') + m_description,
m_encoding,
"Auto-update status: %5").arg(title(),
StandardFeed::typeToString(type()),
description().isEmpty() ? QString() : QString('\n') + description(),
encoding(),
auto_update_string,
NetworkFactory::networkErrorText(m_networkError));
}
@ -438,19 +405,8 @@ QVariant StandardFeed::data(int column, int role) const {
return QVariant();
}
case Qt::TextAlignmentRole:
if (column == FDS_MODEL_COUNTS_INDEX) {
return Qt::AlignCenter;
}
else {
return QVariant();
}
case Qt::FontRole:
return countOfUnreadMessages() > 0 ? m_boldFont : m_normalFont;
case Qt::ForegroundRole:
switch (m_status) {
switch (status()) {
case NewMessages:
return QColor(Qt::blue);
@ -462,7 +418,7 @@ QVariant StandardFeed::data(int column, int role) const {
}
default:
return QVariant();
return Feed::data(column, role);
}
}
@ -474,11 +430,11 @@ int StandardFeed::update() {
if (m_networkError != QNetworkReply::NoError) {
qWarning("Error during fetching of new messages for feed '%s' (id %d).", qPrintable(url()), id());
m_status = NetworkError;
setStatus(NetworkError);
return 0;
}
else {
m_status = Normal;
setStatus(Normal);
}
// Encode downloaded data for further parsing.
@ -762,8 +718,7 @@ QNetworkReply::NetworkError StandardFeed::networkError() const {
}
StandardFeed::StandardFeed(const QSqlRecord &record) : Feed(NULL) {
m_kind = RootItemKind::Feed;
setKind(RootItemKind::Feed);
setTitle(record.value(FDS_DB_TITLE_INDEX).toString());
setId(record.value(FDS_DB_ID_INDEX).toInt());
setDescription(record.value(FDS_DB_DESCRIPTION_INDEX).toString());

View File

@ -162,9 +162,6 @@ class StandardFeed : public Feed {
// available.
int updateMessages(const QList<Message> &messages);
private:
void init();
private:
bool m_passwordProtected;
QString m_username;

View File

@ -25,13 +25,12 @@
StandardRecycleBin::StandardRecycleBin(RootItem *parent)
: RootItem(parent) {
m_kind = RootItemKind::Bin;
m_icon = qApp->icons()->fromTheme(QSL("folder-recycle-bin"));
m_id = ID_RECYCLE_BIN;
m_title = tr("Recycle bin");
m_description = tr("Recycle bin contains all deleted messages from all feeds.");
m_creationDate = QDateTime::currentDateTime();
setKind(RootItemKind::Bin);
setIcon(qApp->icons()->fromTheme(QSL("folder-recycle-bin")));
setId(ID_RECYCLE_BIN);
setTitle(tr("Recycle bin"));
setDescription(tr("Recycle bin contains all deleted messages from all feeds."));
setCreationDate(QDateTime::currentDateTime());
updateCounts(true);
}
@ -59,7 +58,7 @@ QVariant StandardRecycleBin::data(int column, int role) const {
switch (role) {
case Qt::DisplayRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
return title();
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString()
@ -72,7 +71,7 @@ QVariant StandardRecycleBin::data(int column, int role) const {
case Qt::EditRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
return title();
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return countOfUnreadMessages();
@ -82,11 +81,12 @@ QVariant StandardRecycleBin::data(int column, int role) const {
}
case Qt::FontRole:
return countOfUnreadMessages() > 0 ? m_boldFont : m_normalFont;
// TODO: přesunout společny části do předka a volat ho odtud.
return countOfUnreadMessages() > 0 ? boldFont() : normalFont();
case Qt::DecorationRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_icon;
return icon();
}
else {
return QVariant();

View File

@ -38,10 +38,10 @@
StandardServiceRoot::StandardServiceRoot(bool load_from_db, FeedsModel *feeds_model, RootItem *parent)
: ServiceRoot(feeds_model, parent), m_recycleBin(new StandardRecycleBin(this)),
m_addItemMenu(QList<QAction*>()), m_feedContextMenu(QList<QAction*>()), m_actionFeedFetchMetadata(NULL) {
m_title = qApp->system()->getUsername() + QL1S("@") + QL1S(APP_LOW_NAME);
m_icon = StandardServiceEntryPoint().icon();
m_description = tr("This is obligatory service account for standard RSS/RDF/ATOM feeds.");
m_creationDate = QDateTime::currentDateTime();
setTitle(qApp->system()->getUsername() + QL1S("@") + QL1S(APP_LOW_NAME));
setIcon(StandardServiceEntryPoint().icon());
setDescription(tr("This is obligatory service account for standard RSS/RDF/ATOM feeds."));
setCreationDate(QDateTime::currentDateTime());
if (load_from_db) {
loadFromDatabase();
@ -63,38 +63,6 @@ bool StandardServiceRoot::canBeDeleted() {
QVariant StandardServiceRoot::data(int column, int role) const {
switch (role) {
case Qt::DisplayRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString()
.replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
.replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
}
else {
return QVariant();
}
case Qt::EditRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return countOfUnreadMessages();
}
else {
return QVariant();
}
case Qt::DecorationRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_icon;
}
else {
return QVariant();
}
case Qt::ToolTipRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return tr("This is service account for standard RSS/RDF/ATOM feeds.");
@ -107,19 +75,8 @@ QVariant StandardServiceRoot::data(int column, int role) const {
return QVariant();
}
case Qt::TextAlignmentRole:
if (column == FDS_MODEL_COUNTS_INDEX) {
return Qt::AlignCenter;
}
else {
return QVariant();
}
case Qt::FontRole:
return countOfUnreadMessages() > 0 ? m_boldFont : m_normalFont;
default:
return QVariant();
return ServiceRoot::data(column, role);
}
}

View File

@ -46,6 +46,9 @@ class StandardServiceRoot : public ServiceRoot {
bool canBeDeleted();
QVariant data(int column, int role) const;
// Return "add feed" and "add category" items.
QList<QAction*> addItemMenu();
// Returns all standard categories which are lying under given root node.
// This does NOT include the root node even if the node is category.
QHash<int,StandardCategory*> categoriesForItem(RootItem *root);
@ -65,9 +68,6 @@ class StandardServiceRoot : public ServiceRoot {
// NOTE: This is used for import/export of the model.
bool mergeImportExportModel(FeedsImportExportModel *model, QString &output_message);
// Return "add feed" and "add category" items.
QList<QAction*> addItemMenu();
private:
void loadFromDatabase();

View File

@ -26,8 +26,8 @@
TtRssServiceRoot::TtRssServiceRoot(FeedsModel *feeds_model, RootItem *parent) : ServiceRoot(feeds_model, parent) {
// TODO: nadpis se bude měnit podle nastavení uživatelského
// jména a serveru tohoto ttrss učtu
m_title = qApp->system()->getUsername() + "@ttrss";
m_icon = TtRssServiceEntryPoint().icon();
setTitle(qApp->system()->getUsername() + "@ttrss");
setIcon(TtRssServiceEntryPoint().icon());
}
TtRssServiceRoot::~TtRssServiceRoot() {
@ -48,38 +48,6 @@ bool TtRssServiceRoot::canBeDeleted() {
QVariant TtRssServiceRoot::data(int column, int role) const {
switch (role) {
case Qt::DisplayRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::CountFormat)).toString()
.replace(PLACEHOLDER_UNREAD_COUNTS, QString::number(countOfUnreadMessages()))
.replace(PLACEHOLDER_ALL_COUNTS, QString::number(countOfAllMessages()));
}
else {
return QVariant();
}
case Qt::EditRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_title;
}
else if (column == FDS_MODEL_COUNTS_INDEX) {
return countOfUnreadMessages();
}
else {
return QVariant();
}
case Qt::DecorationRole:
if (column == FDS_MODEL_TITLE_INDEX) {
return m_icon;
}
else {
return QVariant();
}
case Qt::ToolTipRole:
// TODO: zobrazovat pokročile informace a statistiky.
if (column == FDS_MODEL_TITLE_INDEX) {
@ -93,19 +61,8 @@ QVariant TtRssServiceRoot::data(int column, int role) const {
return QVariant();
}
case Qt::TextAlignmentRole:
if (column == FDS_MODEL_COUNTS_INDEX) {
return Qt::AlignCenter;
}
else {
return QVariant();
}
case Qt::FontRole:
return countOfUnreadMessages() > 0 ? m_boldFont : m_normalFont;
default:
return QVariant();
return ServiceRoot::data(column, role);
}
}