This commit is contained in:
Martin Rotter 2014-01-10 08:36:08 +01:00
parent 6cff2dcd0b
commit a3e189671c
16 changed files with 76 additions and 44 deletions

View File

@ -120,11 +120,11 @@
</message>
<message>
<source>Title</source>
<translation type="unfinished">Nadpis</translation>
<translation>Název</translation>
</message>
<message>
<source>Title of the category</source>
<translation type="unfinished"></translation>
<translation>Název kategorie</translation>
</message>
<message>
<source>Description</source>
@ -359,11 +359,11 @@
</message>
<message>
<source>Update &amp;all items</source>
<translation type="unfinished"></translation>
<translation>Aktualizov&amp;at všechny položky</translation>
</message>
<message>
<source>Update &amp;selected items</source>
<translation type="unfinished"></translation>
<translation>Aktualizovat v&amp;ybrané položky</translation>
</message>
<message>
<source>&amp;Delete selected feeds/categories</source>
@ -371,31 +371,31 @@
</message>
<message>
<source>Mark &amp;selected items read</source>
<translation type="unfinished"></translation>
<translation>Označit vybrané položky jako přečte&amp;</translation>
</message>
<message>
<source>Mark selected items unread</source>
<translation type="unfinished"></translation>
<translation>Označit vybrané položky jako nepřečtené</translation>
</message>
<message>
<source>Clear selected items</source>
<translation type="unfinished"></translation>
<translation>Vyprázdnit vybrané položky</translation>
</message>
<message>
<source>Mark all &amp;items read</source>
<translation type="unfinished"></translation>
<translation>Označ&amp;it všechny položky jako přečtené</translation>
</message>
<message>
<source>Mark all messages in all feeds read. This does not take message filters into account.</source>
<translation type="unfinished"></translation>
<translation>Označí všechny zprávy ve všech kanálech jako přečtené. Toto nebere v potaz filtry zpráv.</translation>
</message>
<message>
<source>View selected items in newspaper mode</source>
<translation type="unfinished"></translation>
<translation>Zobrazit vybrané položky v novinovém náhledu</translation>
</message>
<message>
<source>Displays all messages from selected feeds/categories in a new &quot;newspaper mode&quot; tab. All selected feeds are marked as read.</source>
<translation type="unfinished"></translation>
<translation>Zobrazí všechny zprávy z vybraných kanálů v novinovém náhledu v novém panelu.</translation>
</message>
</context>
<context>
@ -874,11 +874,11 @@
</message>
<message>
<source>Meesage without URL</source>
<translation type="unfinished"></translation>
<translation>Zpráva bez URL</translation>
</message>
<message>
<source>Message &apos;%s&apos; does not contain URL.</source>
<translation type="unfinished"></translation>
<translation>Zpráva &apos;%s&apos; neobsahuje URL.</translation>
</message>
</context>
<context>

View File

@ -51,7 +51,8 @@ QNetworkReply *BaseNetworkAccessManager::createRequest(QNetworkAccessManager::Op
// This rapidly speeds up loading of web sites.
// NOTE: https://en.wikipedia.org/wiki/HTTP_pipelining
new_request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
new_request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute,
true);
// Setup custom user-agent.
new_request.setRawHeader(USER_AGENT_HTTP_HEADER,

View File

@ -19,6 +19,7 @@ class BaseNetworkAccessManager : public QNetworkAccessManager {
virtual void loadSettings();
protected:
// Creates custom request.
QNetworkReply *createRequest(Operation op,
const QNetworkRequest &request,
QIODevice *outgoingData);

View File

@ -21,7 +21,7 @@ DatabaseFactory::~DatabaseFactory() {
qDebug("Destroying DatabaseFactory object.");
}
DatabaseFactory *DatabaseFactory::getInstance() {
DatabaseFactory *DatabaseFactory::instance() {
if (s_instance.isNull()) {
s_instance = new DatabaseFactory(qApp);
}
@ -126,12 +126,14 @@ QSqlDatabase DatabaseFactory::initialize(const QString &connection_name) {
query_db.finish();
}
// Everything is initialized now.
m_initialized = true;
return database;
}
QSqlDatabase DatabaseFactory::connection(const QString &connection_name) {
if (!m_initialized) {
m_initialized = true;
return initialize(connection_name);
}
else {

View File

@ -23,7 +23,7 @@ class DatabaseFactory : public QObject {
void removeConnection(const QString &connection_name);
// Singleton getter.
static DatabaseFactory *getInstance();
static DatabaseFactory *instance();
private:
// Conctructor.

View File

@ -35,9 +35,7 @@
#define DOWNLOAD_TIMEOUT 5000
#define MESSAGES_VIEW_DEFAULT_COL 170
#define ELLIPSIS_LENGTH 3
#define INTERNAL_URL_SCHEME APP_LOW_NAME
#define INTERNAL_URL_NEWSPAPER "@APP_LOW_NAME@:newspaper"
#define INTERNAL_URL_NEWSPAPER_PATH "newspaper"
#define APP_DB_INIT_FILE "db_init.sql"
#define APP_DB_INIT_SPLIT "-- !\n"

View File

@ -18,6 +18,7 @@ void FeedDownloader::updateFeeds(const QList<FeedsModelFeed *> &feeds) {
qDebug().nospace() << "Performing feed updates in thread: \'" <<
QThread::currentThreadId() << "\'.";
// Job starts now.
emit started();
for (int i = 0, total = feeds.size(); i < total; i++) {

View File

@ -23,7 +23,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_countsIcon = IconThemeFactory::getInstance()->fromTheme("mail-mark-important");
m_headerData << tr("Title");
m_tooltipData << tr("Titles of feeds/categories.") <<
tr("Counts of unread/all meesages.");
@ -34,8 +34,11 @@ FeedsModel::FeedsModel(QObject *parent) : QAbstractItemModel(parent) {
FeedsModel::~FeedsModel() {
qDebug("Destroying FeedsModel instance.");
// Delete all model items.
delete m_rootItem;
DatabaseFactory::getInstance()->removeConnection(objectName());
// Remove connection.
DatabaseFactory::instance()->removeConnection(objectName());
}
QVariant FeedsModel::data(const QModelIndex &index, int role) const {
@ -81,6 +84,8 @@ QModelIndex FeedsModel::index(int row, int column, const QModelIndex &parent) co
FeedsModelRootItem *parent_item;
// TODO: overit zda zde misto internalPointer nepouzit
// metodu itemFornIndex a overit vykonnostni dopady
if (!parent.isValid()) {
parent_item = m_rootItem;
}
@ -103,6 +108,8 @@ QModelIndex FeedsModel::parent(const QModelIndex &child) const {
return QModelIndex();
}
// TODO: overit zda zde misto internalPointer nepouzit
// metodu itemFornIndex a overit vykonnostni dopady
FeedsModelRootItem *child_item = static_cast<FeedsModelRootItem*>(child.internalPointer());
FeedsModelRootItem *parent_item = child_item->parent();
@ -121,6 +128,8 @@ int FeedsModel::rowCount(const QModelIndex &parent) const {
return 0;
}
// TODO: overit zda zde misto internalPointer nepouzit
// metodu itemFornIndex a overit vykonnostni dopady
if (!parent.isValid()) {
parent_item = m_rootItem;
}
@ -157,7 +166,9 @@ bool FeedsModel::removeItems(const QModelIndexList &indexes) {
FeedsModelRootItem *parent_item = itemForIndex(parent_index);
beginRemoveRows(parent_index, index.row(), index.row());
items_for_deletion << parent_item->removeChild(index.row());
if (parent_item->removeChild(index.row())) {
items_for_deletion << item;
}
endRemoveRows();
}
}
@ -167,14 +178,13 @@ bool FeedsModel::removeItems(const QModelIndexList &indexes) {
delete items_for_deletion.takeFirst();
}
return true;
}
QList<Message> FeedsModel::messagesForFeeds(const QList<FeedsModelFeed *> &feeds) {
QList<Message> FeedsModel::messagesForFeeds(const QList<FeedsModelFeed*> &feeds) {
QList<Message> messages;
QSqlDatabase database = DatabaseFactory::getInstance()->connection(objectName());
QSqlDatabase database = DatabaseFactory::instance()->connection(objectName());
QSqlQuery query_read_msg(database);
query_read_msg.setForwardOnly(true);
query_read_msg.prepare("SELECT title, url, author, date_created, contents "
@ -203,6 +213,8 @@ QList<Message> FeedsModel::messagesForFeeds(const QList<FeedsModelFeed *> &feeds
}
int FeedsModel::columnCount(const QModelIndex &parent) const {
// TODO: overit zda zde misto internalPointer nepouzit
// metodu itemFornIndex a overit vykonnostni dopady
if (parent.isValid()) {
return static_cast<FeedsModelRootItem*>(parent.internalPointer())->columnCount();
}
@ -314,7 +326,7 @@ void FeedsModel::loadFromDatabase() {
qDeleteAll(m_rootItem->childItems());
m_rootItem->clearChilds();
QSqlDatabase database = DatabaseFactory::getInstance()->connection(objectName());
QSqlDatabase database = DatabaseFactory::instance()->connection(objectName());
CategoryAssignment categories;
FeedAssignment feeds;
@ -416,7 +428,8 @@ QList<FeedsModelFeed*> FeedsModel::feedsForIndexes(const QModelIndexList &indexe
// example situation where feed and its parent category are both
// selected). So, remove duplicates from the list.
qSort(feeds.begin(), feeds.end(), FeedsModelRootItem::lessThan);
feeds.erase(std::unique(feeds.begin(), feeds.end(), FeedsModelRootItem::isEqual),
feeds.erase(std::unique(feeds.begin(),
feeds.end(), FeedsModelRootItem::isEqual),
feeds.end());
}
@ -425,7 +438,7 @@ QList<FeedsModelFeed*> FeedsModel::feedsForIndexes(const QModelIndexList &indexe
bool FeedsModel::markFeedsRead(const QList<FeedsModelFeed*> &feeds,
int read) {
QSqlDatabase db_handle = DatabaseFactory::getInstance()->connection(objectName());
QSqlDatabase db_handle = DatabaseFactory::instance()->connection(objectName());
if (!db_handle.transaction()) {
qWarning("Starting transaction for feeds read change.");
@ -461,7 +474,7 @@ bool FeedsModel::markFeedsRead(const QList<FeedsModelFeed*> &feeds,
bool FeedsModel::markFeedsDeleted(const QList<FeedsModelFeed *> &feeds,
int deleted) {
QSqlDatabase db_handle = DatabaseFactory::getInstance()->connection(objectName());
QSqlDatabase db_handle = DatabaseFactory::instance()->connection(objectName());
if (!db_handle.transaction()) {
qWarning("Starting transaction for feeds clearing.");

View File

@ -36,7 +36,7 @@ class FeedsModel : public QAbstractItemModel {
// Feed/category manipulators.
bool removeItems(const QModelIndexList &indexes);
// Returns all (undeleted) messages for given feeds.
// Returns (undeleted) messages for given feeds.
QList<Message> messagesForFeeds(const QList<FeedsModelFeed*> &feeds);
// Returns all categories, each pair

View File

@ -58,7 +58,7 @@ QString FeedsModelFeed::typeToString(FeedsModelFeed::Type type) {
}
void FeedsModelFeed::updateCounts(bool including_total_count) {
QSqlDatabase database = DatabaseFactory::getInstance()->connection("FeedsModelFeed");
QSqlDatabase database = DatabaseFactory::instance()->connection("FeedsModelFeed");
QSqlQuery query_all(database);
query_all.setForwardOnly(true);

View File

@ -56,7 +56,7 @@ int FeedsModelRootItem::row() const {
}
int FeedsModelRootItem::childCount() const {
return m_childItems.count();
return m_childItems.size();
}
QVariant FeedsModelRootItem::data(int column, int role) const {
@ -103,12 +103,14 @@ void FeedsModelRootItem::clearChilds() {
m_childItems.clear();
}
FeedsModelRootItem *FeedsModelRootItem::removeChild(int index) {
FeedsModelRootItem *item_to_delete = m_childItems.at(index);
m_childItems.removeAt(index);
return item_to_delete;
bool FeedsModelRootItem::removeChild(int index) {
if (index >= 0 && index < m_childItems.size()) {
m_childItems.removeAt(index);
return true;
}
else {
return false;
}
}

View File

@ -66,7 +66,7 @@ class FeedsModelRootItem {
// Removes particular child at given index.
// NOTE: Child is NOT freed from the memory.
FeedsModelRootItem *removeChild(int index);
bool removeChild(int index);
// Compares two model items.
static bool isEqual(FeedsModelRootItem *lhs, FeedsModelRootItem *rhs);

View File

@ -189,7 +189,7 @@ void FeedsModelStandardFeed::update() {
void FeedsModelStandardFeed::updateMessages(const QList<Message> &messages) {
int feed_id = id(), message_id;
qint64 message_creation_date;
QSqlDatabase database = DatabaseFactory::getInstance()->connection("FeedsModelStandardFeed");
QSqlDatabase database = DatabaseFactory::instance()->connection("FeedsModelStandardFeed");
// Prepare queries.
QSqlQuery query_select(database);

View File

@ -33,8 +33,8 @@ bool FeedsProxyModel::lessThan(const QModelIndex &left,
const QModelIndex &right) const {
if (left.isValid() && right.isValid()) {
// Make necessary castings.
FeedsModelRootItem *left_item = static_cast<FeedsModelRootItem*>(left.internalPointer());
FeedsModelRootItem *right_item = static_cast<FeedsModelRootItem*>(right.internalPointer());
FeedsModelRootItem *left_item = m_sourceModel->itemForIndex(left);
FeedsModelRootItem *right_item = m_sourceModel->itemForIndex(right);
// NOTE: Here we want to accomplish that ALL
// categories are queued one after another and all
@ -59,7 +59,10 @@ bool FeedsProxyModel::lessThan(const QModelIndex &left,
return false;
}
else {
// Left item is category, right item is feed.*/
// Left item is category, right item is feed.
// NOTE: Category is in fact "more" than feed but
// we consider it to be "less" because it should be "placed"
// above the "smalles" feed when ascending sort is used.
return true;
}
}

View File

@ -13,7 +13,7 @@
MessagesModel::MessagesModel(QObject *parent)
: QSqlTableModel(parent,
DatabaseFactory::getInstance()->connection("MessagesModel")) {
DatabaseFactory::instance()->connection("MessagesModel")) {
setObjectName("MessagesModel");
setupFonts();

View File

@ -111,7 +111,18 @@ void FeedsView::deleteSelectedItems() {
QModelIndexList selection = selectionModel()->selectedRows();
QModelIndexList mapped_selection = m_proxyModel->mapListToSource(selection);
FeedsModelRootItem *parent = m_sourceModel->itemForIndex(mapped_selection.at(0).parent());
m_sourceModel->removeItems(mapped_selection);
QModelIndex id = m_sourceModel->indexForItem(parent);
if (id.isValid()) {
selectionModel()->clearSelection();
selectionModel()->select(m_proxyModel->mapFromSource(id),
QItemSelectionModel::Rows |
QItemSelectionModel::Select);
}
}
void FeedsView::markSelectedFeedsReadStatus(int read) {