diff --git a/localization/rssguard_cs.ts b/localization/rssguard_cs.ts
index e06cfde02..170450a47 100644
--- a/localization/rssguard_cs.ts
+++ b/localization/rssguard_cs.ts
@@ -108,6 +108,37 @@
<body>RSS Guard je (velmi) jednoduchá čtečka kanálů.<br><br>Tento software je šířen pod licencí GNU General Public License, verze 3.<br><br>Kontakty:<ul><li><a href="mailto://%1">%1</a> ~email</li><li><a href="%2">%2</a> ~webová stránka</li></ul>Zdrojové kódy aplikace lze získat z jejího web.u<br><br><br>Copyright (C) 2011-%3 %4</body>
+
+ FormCategoryDetails
+
+
+
+
+
+
+
+
+
+
+ Nadpis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
FormMain
@@ -170,10 +201,6 @@
Zavřít aktivní &panel
-
-
- &Kanály
-
&Zprávy
@@ -254,18 +281,6 @@
Zavřít aktuální panel webového prohlížeče..
-
-
- Aktualizov&at vše
-
-
-
- Aktualizovat vybrané kanál&y
-
-
-
- Smazat vybrané kanály/kategor&ie
-
Smazat vybrané zprávy.
@@ -314,18 +329,10 @@
Uprav&it vybraní kanál/kategorii
-
-
- Označit vybrané kanály jako &přečtené
-
Označí všechny zprávy z vybraných kanálů jako přečtené, neuvažuje filtry zpráv.
-
-
- Označit vybrané kanály jako nepřečtené
-
Označí všechny zprávy z vybraných kanálů jako nepřečtené, neuvažuje filtry zpráv.
@@ -334,10 +341,6 @@
&Smazat vybrané zprávy
-
-
- Promazat vybrané kanály
-
Smaže všechny zprávy z vybraných kanálů.
@@ -350,6 +353,42 @@
Žádná akce není právě dostupná.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
FormSettings
diff --git a/localization/rssguard_en.ts b/localization/rssguard_en.ts
index 89f079c15..fa894975a 100644
--- a/localization/rssguard_en.ts
+++ b/localization/rssguard_en.ts
@@ -108,6 +108,37 @@
+
+ FormCategoryDetails
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
FormMain
@@ -170,10 +201,6 @@
-
-
-
-
@@ -254,18 +281,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -314,18 +329,10 @@
-
-
-
-
-
-
-
-
@@ -334,10 +341,6 @@
-
-
-
-
@@ -350,6 +353,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
FormSettings
diff --git a/localization/rssguard_nl.ts b/localization/rssguard_nl.ts
index 750eff89c..e203de85e 100644
--- a/localization/rssguard_nl.ts
+++ b/localization/rssguard_nl.ts
@@ -108,6 +108,37 @@
<body>RSS Guard is een (zeer) makelijk om te gebruiken feed lezer.<br><br>Dit programma is beschikbaar onder te termenvan de GNU General Public License versie 3.<br><br>Contacts:<ul><li><a href="mailto://%1">%1</a> ~email</li><li><a ref="%2">%2</a> ~website </li><ul>U kunt de broncode voor RSS Guard verkrijgen op de website.<br><br><br>Auteursrecht(C)2011-%3 %4</body>
+
+ FormCategoryDetails
+
+
+
+
+
+
+
+
+
+
+ Titel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
FormMain
@@ -170,10 +201,6 @@
Sluit huidig &tabblad
-
-
-
-
&Berichten
@@ -254,18 +281,6 @@
Sluit huidige webbrowser tabblad.
-
-
- Update a&lle feeds
-
-
-
- Update ge&selecteerde feeds
-
-
-
- &Verwijder geselecteerde feed(s)/categorie(ën)
-
Verwijder geselecteerde berichten.
@@ -314,18 +329,10 @@
-
-
-
-
-
-
-
-
@@ -334,10 +341,6 @@
-
-
-
-
@@ -350,6 +353,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
FormSettings
diff --git a/src/core/databasefactory.cpp b/src/core/databasefactory.cpp
index b50683002..60a56b5cf 100644
--- a/src/core/databasefactory.cpp
+++ b/src/core/databasefactory.cpp
@@ -76,6 +76,7 @@ QSqlDatabase DatabaseFactory::initialize(const QString &connection_name) {
else {
QSqlQuery query_db(database);
+ query_db.setForwardOnly(true);
query_db.exec("PRAGMA encoding = \"UTF-8\"");
query_db.exec("PRAGMA synchronous = OFF");
query_db.exec("PRAGMA journal_mode = MEMORY");
diff --git a/src/core/defs.h.in b/src/core/defs.h.in
index 8c2b9f5a6..be6408fa3 100755
--- a/src/core/defs.h.in
+++ b/src/core/defs.h.in
@@ -31,7 +31,9 @@
#define TRAY_ICON_BUBBLE_TIMEOUT 15000
#define KEY_MESSAGES_VIEW "messages_view_column_"
#define CLOSE_LOCK_TIMEOUT 3000
+#define DOWNLOAD_TIMEOUT 5000
#define MESSAGES_VIEW_DEFAULT_COL 170
+#define ELLIPSIS_LENGTH 3
#define APP_DB_INIT_FILE "db_init.sql"
#define APP_DB_INIT_SPLIT "-- !\n"
diff --git a/src/core/feedsmodel.cpp b/src/core/feedsmodel.cpp
index b0d076be8..af7ce7ee8 100644
--- a/src/core/feedsmodel.cpp
+++ b/src/core/feedsmodel.cpp
@@ -11,7 +11,6 @@
#include
#include
#include
-#include
#include
@@ -23,9 +22,7 @@ FeedsModel::FeedsModel(QObject *parent) : QAbstractItemModel(parent) {
m_rootItem->setId(NO_PARENT_CATEGORY);
m_rootItem->setTitle(tr("root"));
m_rootItem->setIcon(IconThemeFactory::getInstance()->fromTheme("folder-red"));
-
m_countsIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-unread");
-
m_headerData << tr("Title");
m_tooltipData << tr("Titles of feeds/categories.") <<
tr("Counts of unread/all meesages.");
@@ -204,50 +201,6 @@ QModelIndex FeedsModel::indexForItem(FeedsModelRootItem *item) const {
return QModelIndex();
}
-/*
-QModelIndex FeedsModel::indexForItem(FeedsModelRootItem *item) const {
- if (item->kind() == FeedsModelRootItem::RootItem) {
- // Root item lies on invalid index.
- return QModelIndex();
- }
-
- // TODO: Rewrite for better performance.
-
- QModelIndexList parents;
-
- // Start with invalid index (so that we start from the root
- // item).
- parents << QModelIndex();
-
- while (!parents.isEmpty()) {
- QModelIndex active_index = parents.takeFirst();
- int row_count = rowCount(active_index);
-
- // Iterate all childs of this parent.
- for (int i = 0; i < row_count; i++) {
- QModelIndex candidate_index = index(i, 0, active_index);
-
- // This index could be our target item.
- FeedsModelRootItem *target_item = itemForIndex(candidate_index);
-
- if (target_item != NULL) {
- if (FeedsModelRootItem::isEqual(target_item, item)) {
- // We found our target index, it's good.
- return candidate_index;
- }
- else if (hasChildren(candidate_index)) {
- // This is not our target index but it has children,
- // scan them too.
- parents << candidate_index;
- }
- }
- }
-
- }
-
- return QModelIndex();
-}*/
-
void FeedsModel::reloadChangedLayout(QModelIndexList list) {
while (!list.isEmpty()) {
QModelIndex ix = list.takeLast();
@@ -293,9 +246,11 @@ void FeedsModel::loadFromDatabase() {
FeedAssignment feeds;
// Obtain data for categories from the database.
- QSqlQuery query_categories("SELECT * FROM Categories;", database);
+ QSqlQuery query_categories(database);
+ query_categories.setForwardOnly(true);
- if (query_categories.lastError().isValid()) {
+ if (!query_categories.exec("SELECT * FROM Categories;") ||
+ query_categories.lastError().isValid()) {
qFatal("Query for obtaining categories failed.");
}
@@ -322,9 +277,11 @@ void FeedsModel::loadFromDatabase() {
}
// All categories are now loaded.
- QSqlQuery query_feeds("SELECT * FROM Feeds;", database);
+ QSqlQuery query_feeds(database);
+ query_feeds.setForwardOnly(true);
- if (query_feeds.lastError().isValid()) {
+ if (!query_feeds.exec("SELECT * FROM Feeds;") ||
+ query_feeds.lastError().isValid()) {
qFatal("Query for obtaining feeds failed.");
}
@@ -403,6 +360,8 @@ bool FeedsModel::markFeedsRead(const QList &feeds,
}
QSqlQuery query_read_msg(db_handle);
+ query_read_msg.setForwardOnly(true);
+
if (!query_read_msg.prepare(QString("UPDATE messages SET read = :read "
"WHERE feed IN (%1) AND deleted = 0").arg(textualFeedIds(feeds).join(", ")))) {
qWarning("Query preparation failed for feeds read change.");
@@ -437,6 +396,8 @@ bool FeedsModel::markFeedsDeleted(const QList &feeds,
}
QSqlQuery query_delete_msg(db_handle);
+ query_delete_msg.setForwardOnly(true);
+
if (!query_delete_msg.prepare(QString("UPDATE messages SET deleted = :deleted "
"WHERE feed IN (%1) AND deleted = 0").arg(textualFeedIds(feeds).join(", ")))) {
qWarning("Query preparation failed for feeds clearing.");
@@ -498,13 +459,13 @@ QList FeedsModel::getFeeds(FeedsModelRootItem *root) {
}
else {
// Root itself is a CATEGORY or ROOT item.
- QQueue traversable_items;
+ QList traversable_items;
- traversable_items.enqueue(root);
+ traversable_items.append(root);
// Iterate all nested categories.
while (!traversable_items.isEmpty()) {
- FeedsModelRootItem *active_category = traversable_items.dequeue();
+ FeedsModelRootItem *active_category = traversable_items.takeFirst();
foreach (FeedsModelRootItem *child, active_category->childItems()) {
if (child->kind() == FeedsModelRootItem::Feed) {
@@ -513,7 +474,7 @@ QList FeedsModel::getFeeds(FeedsModelRootItem *root) {
}
else if (child->kind() == FeedsModelRootItem::Category) {
// This child is category, add its child feeds too.
- traversable_items.enqueue(static_cast(child));
+ traversable_items.append(static_cast(child));
}
}
}
diff --git a/src/core/feedsmodelcategory.cpp b/src/core/feedsmodelcategory.cpp
index 638b6b653..8f06de9a5 100755
--- a/src/core/feedsmodelcategory.cpp
+++ b/src/core/feedsmodelcategory.cpp
@@ -3,8 +3,6 @@
#include "core/feedsmodelstandardcategory.h"
#include "core/feedsmodelstandardfeed.h"
-#include
-
FeedsModelCategory::FeedsModelCategory(FeedsModelRootItem *parent_item)
: FeedsModelRootItem(parent_item) {
diff --git a/src/core/feedsmodelfeed.cpp b/src/core/feedsmodelfeed.cpp
index a62bf74c1..190948679 100755
--- a/src/core/feedsmodelfeed.cpp
+++ b/src/core/feedsmodelfeed.cpp
@@ -68,6 +68,7 @@ QString FeedsModelFeed::typeToString(FeedsModelFeed::Type type) {
void FeedsModelFeed::updateCounts(bool including_total_count) {
QSqlDatabase database = DatabaseFactory::getInstance()->addConnection("FeedsModelFeed");
QSqlQuery query_all(database);
+ query_all.setForwardOnly(true);
if (including_total_count) {
if (query_all.exec(QString("SELECT count() FROM messages "
diff --git a/src/core/feedsmodelstandardfeed.cpp b/src/core/feedsmodelstandardfeed.cpp
index a2add5354..3d280a7f8 100755
--- a/src/core/feedsmodelstandardfeed.cpp
+++ b/src/core/feedsmodelstandardfeed.cpp
@@ -149,7 +149,7 @@ void FeedsModelStandardFeed::update() {
QByteArray feed_contents;
int download_timeout = Settings::getInstance()->value(APP_CFG_FEEDS,
"download_timeout",
- 5000).toInt();
+ DOWNLOAD_TIMEOUT).toInt();
// TODO: Provide download time-measures debugging
// outputs here.
@@ -211,9 +211,11 @@ void FeedsModelStandardFeed::updateMessages(const QList &messages) {
QSqlQuery query_select(database);
QSqlQuery query_insert(database);
+ query_select.setForwardOnly(true);
query_select.prepare("SELECT id, feed, date_created FROM Messages "
"WHERE feed = :feed AND title = :title AND url = :url;");
+ query_insert.setForwardOnly(true);
query_insert.prepare("INSERT INTO Messages "
"(feed, title, url, author, date_created, contents) "
"VALUES (:feed, :title, :url, :author, :date_created, :contents);");
@@ -257,6 +259,11 @@ void FeedsModelStandardFeed::updateMessages(const QList &messages) {
// Message is already persistently stored.
// TODO: Update message if it got updated in the
// online feed.
+ if (message.m_createdFromFeed) {
+ // Creation data of the message was obtained from
+ // feed itself.
+
+ }
}
}
diff --git a/src/core/messagesmodel.cpp b/src/core/messagesmodel.cpp
index 7727a190f..836617070 100644
--- a/src/core/messagesmodel.cpp
+++ b/src/core/messagesmodel.cpp
@@ -233,9 +233,11 @@ bool MessagesModel::setMessageRead(int row_index, int read) {
}
int message_id;
- QSqlQuery query_delete_msg(db_handle);
- if (!query_delete_msg.prepare("UPDATE messages SET read = :read "
- "WHERE id = :id")) {
+ QSqlQuery query_read_msg(db_handle);
+ query_read_msg.setForwardOnly(true);
+
+ if (!query_read_msg.prepare("UPDATE messages SET read = :read "
+ "WHERE id = :id")) {
qWarning("Query preparation failed for message read change.");
db_handle.rollback();
@@ -244,9 +246,9 @@ bool MessagesModel::setMessageRead(int row_index, int read) {
// Rewrite the actual data in the database itself.
message_id = messageId(row_index);
- query_delete_msg.bindValue(":id", message_id);
- query_delete_msg.bindValue(":read", read);
- query_delete_msg.exec();
+ query_read_msg.bindValue(":id", message_id);
+ query_read_msg.bindValue(":read", read);
+ query_read_msg.exec();
// Commit changes.
if (db_handle.commit()) {
@@ -287,9 +289,11 @@ bool MessagesModel::switchMessageImportance(int row_index) {
}
int message_id;
- QSqlQuery query_delete_msg(db_handle);
- if (!query_delete_msg.prepare("UPDATE messages SET important = :important "
- "WHERE id = :id")) {
+ QSqlQuery query_importance_msg(db_handle);
+ query_importance_msg.setForwardOnly(true);
+
+ if (!query_importance_msg.prepare("UPDATE messages SET important = :important "
+ "WHERE id = :id")) {
qWarning("Query preparation failed for message importance switch.");
db_handle.rollback();
@@ -297,10 +301,10 @@ bool MessagesModel::switchMessageImportance(int row_index) {
}
message_id = messageId(row_index);
- query_delete_msg.bindValue(":id", message_id);
- query_delete_msg.bindValue(":important",
- current_importance == 1 ? 0 : 1);
- query_delete_msg.exec();
+ query_importance_msg.bindValue(":id", message_id);
+ query_importance_msg.bindValue(":important",
+ current_importance == 1 ? 0 : 1);
+ query_importance_msg.exec();
// Commit changes.
if (db_handle.commit()) {
@@ -324,9 +328,11 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages
}
int message_id, importance;
- QSqlQuery query_delete_msg(db_handle);
- if (!query_delete_msg.prepare("UPDATE messages SET important = :important "
- "WHERE id = :id")) {
+ QSqlQuery query_importance_msg(db_handle);
+ query_importance_msg.setForwardOnly(true);
+
+ if (!query_importance_msg.prepare("UPDATE messages SET important = :important "
+ "WHERE id = :id")) {
qWarning("Query preparation failed for message importance switch.");
db_handle.rollback();
@@ -337,10 +343,10 @@ bool MessagesModel::switchBatchMessageImportance(const QModelIndexList &messages
message_id = messageId(message.row());
importance = data(message.row(), MSG_DB_IMPORTANT_INDEX, Qt::EditRole).toInt();
- query_delete_msg.bindValue(":id", message_id);
- query_delete_msg.bindValue(":important",
- importance == 1 ? 0 : 1);
- query_delete_msg.exec();
+ query_importance_msg.bindValue(":id", message_id);
+ query_importance_msg.bindValue(":important",
+ importance == 1 ? 0 : 1);
+ query_importance_msg.exec();
}
// Commit changes.
@@ -365,6 +371,8 @@ bool MessagesModel::setBatchMessagesDeleted(const QModelIndexList &messages, int
int message_id;
QSqlQuery query_delete_msg(db_handle);
+ query_delete_msg.setForwardOnly(true);
+
if (!query_delete_msg.prepare("UPDATE messages SET deleted = :deleted "
"WHERE id = :id")) {
qWarning("Query preparation failed for message deletion.");
@@ -404,8 +412,10 @@ bool MessagesModel::setBatchMessagesRead(const QModelIndexList &messages, int re
int message_id;
QSqlQuery query_read_msg(db_handle);
+ query_read_msg.setForwardOnly(true);
+
if (!query_read_msg.prepare("UPDATE messages SET read = :read "
- "WHERE id = :id")) {
+ "WHERE id = :id")) {
qWarning("Query preparation failed for message read change.");
db_handle.rollback();
diff --git a/src/core/networkfactory.cpp b/src/core/networkfactory.cpp
index 4fe741792..e4922e150 100644
--- a/src/core/networkfactory.cpp
+++ b/src/core/networkfactory.cpp
@@ -59,10 +59,12 @@ QNetworkReply::NetworkError NetworkFactory::downloadFile(const QString &url,
}
// In this phase, some part of downloading process is completed.
+ QUrl redirection_url = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
- if (reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl().isValid()) {
+ if (redirection_url.isValid()) {
// Communication indicates that HTTP redirection is needed.
- request.setUrl(reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl());
+ // Setup redirection URL and download again.
+ request.setUrl(redirection_url);
}
else {
// No redirection is indicated. Final file is obtained
diff --git a/src/core/textfactory.cpp b/src/core/textfactory.cpp
index f5b836319..f0d438c96 100644
--- a/src/core/textfactory.cpp
+++ b/src/core/textfactory.cpp
@@ -40,7 +40,7 @@ QDateTime TextFactory::parseDateTime(const QString &date_time) {
QString TextFactory::shorten(const QString &input, int text_length_limit) {
if (input.size() > text_length_limit) {
- return input.left(text_length_limit - 3) + QString(3, '.');
+ return input.left(text_length_limit - ELLIPSIS_LENGTH) + QString(ELLIPSIS_LENGTH, '.');
}
else {
return input;
diff --git a/src/gui/messagesview.cpp b/src/gui/messagesview.cpp
index 644bbb19f..1759941aa 100644
--- a/src/gui/messagesview.cpp
+++ b/src/gui/messagesview.cpp
@@ -248,8 +248,16 @@ void MessagesView::openSelectedSourceArticlesExternally() {
void MessagesView::openSelectedSourceMessagesInternally() {
foreach (const QModelIndex &index, selectionModel()->selectedRows()) {
- // TODO: What to do with messages w/o link?
- emit openLinkMessageNewTabRequested(m_sourceModel->messageAt(m_proxyModel->mapToSource(index).row()).m_url);
+ Message message = m_sourceModel->messageAt(m_proxyModel->mapToSource(index).row());
+
+ if (message.m_url.isEmpty()) {
+ QMessageBox::warning(this,
+ tr("Meesage without URL"),
+ tr("Message '%s' does not contain URL.").arg(message.m_title));
+ }
+ else {
+ emit openLinkMessageNewTabRequested(message.m_url);
+ }
}
}