Initial implementation of newspaper view.

This commit is contained in:
Martin Rotter 2014-01-04 14:09:38 +01:00
parent 37f631193e
commit 9149b90042
13 changed files with 105 additions and 32 deletions

View File

@ -4,6 +4,7 @@
#include "core/databasefactory.h"
#include "core/feedsmodelstandardcategory.h"
#include "core/feedsmodelstandardfeed.h"
#include "core/textfactory.h"
#include "gui/iconthemefactory.h"
#include "gui/iconfactory.h"
@ -130,6 +131,37 @@ int FeedsModel::rowCount(const QModelIndex &parent) const {
return parent_item->childCount();
}
QList<Message> FeedsModel::messagesForFeeds(const QList<FeedsModelFeed *> &feeds) {
QList<Message> messages;
QSqlDatabase database = DatabaseFactory::getInstance()->addConnection(objectName());
QSqlQuery query_read_msg(database);
query_read_msg.setForwardOnly(true);
query_read_msg.prepare("SELECT title, url, author, date_created, contents "
"FROM Messages "
"WHERE deleted = 0 AND feed = :feed;");
foreach (FeedsModelFeed *feed, feeds) {
query_read_msg.bindValue(":feed", feed->id());
if (query_read_msg.exec()) {
while (query_read_msg.next()) {
Message message;
message.m_title = query_read_msg.value(0).toString();
message.m_url = query_read_msg.value(1).toString();
message.m_author = query_read_msg.value(2).toString();
message.m_created = TextFactory::parseDateTime(query_read_msg.value(3).value<qint64>());
message.m_contents = query_read_msg.value(4).toString();
messages.append(message);
}
}
}
return messages;
}
int FeedsModel::columnCount(const QModelIndex &parent) const {
if (parent.isValid()) {
return static_cast<FeedsModelRootItem*>(parent.internalPointer())->columnCount();
@ -316,7 +348,7 @@ void FeedsModel::loadFromDatabase() {
QList<FeedsModelFeed*> FeedsModel::feedsForIndex(const QModelIndex &index) {
FeedsModelRootItem *item = itemForIndex(index);
return getFeeds(item);
return feedsForItem(item);
}
FeedsModelFeed *FeedsModel::feedForIndex(const QModelIndex &index) {
@ -423,11 +455,11 @@ bool FeedsModel::markFeedsDeleted(const QList<FeedsModelFeed *> &feeds,
}
}
QHash<int, FeedsModelCategory*> FeedsModel::getAllCategories() {
return getCategories(m_rootItem);
QHash<int, FeedsModelCategory*> FeedsModel::allCategories() {
return categoriesForItem(m_rootItem);
}
QHash<int, FeedsModelCategory*> FeedsModel::getCategories(FeedsModelRootItem *root) {
QHash<int, FeedsModelCategory*> FeedsModel::categoriesForItem(FeedsModelRootItem *root) {
QHash<int, FeedsModelCategory*> categories;
QList<FeedsModelRootItem*> parents;
@ -453,11 +485,11 @@ QHash<int, FeedsModelCategory*> FeedsModel::getCategories(FeedsModelRootItem *ro
return categories;
}
QList<FeedsModelFeed*> FeedsModel::getAllFeeds() {
return getFeeds(m_rootItem);
QList<FeedsModelFeed*> FeedsModel::allFeeds() {
return feedsForItem(m_rootItem);
}
QList<FeedsModelFeed*> FeedsModel::getFeeds(FeedsModelRootItem *root) {
QList<FeedsModelFeed*> FeedsModel::feedsForItem(FeedsModelRootItem *root) {
QList<FeedsModelFeed*> feeds;
if (root->kind() == FeedsModelRootItem::Feed) {
@ -491,7 +523,7 @@ QList<FeedsModelFeed*> FeedsModel::getFeeds(FeedsModelRootItem *root) {
}
void FeedsModel::assembleFeeds(FeedAssignment feeds) {
QHash<int, FeedsModelCategory*> categories = getAllCategories();
QHash<int, FeedsModelCategory*> categories = allCategories();
foreach (const FeedAssignmentItem &feed, feeds) {
if (feed.first == NO_PARENT_CATEGORY) {

View File

@ -2,6 +2,9 @@
#define FEEDSMODEL_H
#include <QAbstractItemModel>
#include "core/messagesmodel.h"
#include <QIcon>
@ -30,20 +33,23 @@ class FeedsModel : public QAbstractItemModel {
int columnCount(const QModelIndex &parent) const;
int rowCount(const QModelIndex &parent) const;
// Returns all (undeleted) messages for given feeds.
QList<Message> messagesForFeeds(const QList<FeedsModelFeed*> &feeds);
// Returns all categories, each pair
// consists of ID of parent item and pointer to category.
QHash<int, FeedsModelCategory*> getAllCategories();
QHash<int, FeedsModelCategory*> allCategories();
// Returns categories from the subtree with given root node, each pair
// consists of ID of parent item and pointer to category.
QHash<int, FeedsModelCategory*> getCategories(FeedsModelRootItem *root);
QHash<int, FeedsModelCategory*> categoriesForItem(FeedsModelRootItem *root);
// Returns list of all feeds contained in the model.
QList<FeedsModelFeed*> getAllFeeds();
QList<FeedsModelFeed*> allFeeds();
// Get list of feeds from tree with particular item
// as root. If root itself is a feed, then it is returned.
QList<FeedsModelFeed*> getFeeds(FeedsModelRootItem *root);
QList<FeedsModelFeed*> feedsForItem(FeedsModelRootItem *root);
// Returns list of feeds which belong to given indexes.
// NOTE: If index is "category", then all child feeds are contained in the
@ -84,6 +90,7 @@ class FeedsModel : public QAbstractItemModel {
// Signals that SOME data of this model need
// to be reloaded by ALL attached views.
// NOTE: This reloads all parent valid indexes too.
void reloadChangedLayout(QModelIndexList list);
protected:

View File

@ -136,10 +136,6 @@ void FeedMessageViewer::createConnections() {
m_messagesBrowser, SLOT(clear()));
connect(m_messagesView, SIGNAL(currentMessageChanged(Message)),
m_messagesBrowser, SLOT(navigateToMessage(Message)));
connect(m_messagesView, SIGNAL(openMessagesInNewspaperViewRequested(QList<Message>)),
m_messagesBrowser, SLOT(navigateToMessages(QList<Message>)));
connect(m_messagesView, SIGNAL(openMessageNewTabRequested(Message)),
FormMain::getInstance()->m_ui->m_tabWidget,
SLOT(addBrowserWithMessage(Message)));
@ -152,6 +148,9 @@ void FeedMessageViewer::createConnections() {
m_feedsView, SLOT(updateCountsOfSelectedFeeds()));
connect(m_feedsView, SIGNAL(feedsNeedToBeReloaded(int)),
m_messagesView, SLOT(reloadSelections(int)));
connect(m_feedsView, SIGNAL(newspaperModeRequested(QList<Message>)),
FormMain::getInstance()->m_ui->m_tabWidget,
SLOT(addBrowserWithMessages(QList<Message>)));
// Downloader connections.
connect(m_feedDownloaderThread, SIGNAL(finished()),
@ -194,6 +193,8 @@ void FeedMessageViewer::createConnections() {
SIGNAL(triggered()), m_feedsView, SLOT(addNewCategory()));
connect(FormMain::getInstance()->m_ui->m_actionEditSelectedFeedCategory,
SIGNAL(triggered()), m_feedsView, SLOT(editSelectedItem()));
connect(FormMain::getInstance()->m_ui->m_actionViewSelectedItemsNewspaperMode,
SIGNAL(triggered()), m_feedsView, SLOT(openSelectedFeedsInNewspaperMode()));
}
void FeedMessageViewer::initialize() {

View File

@ -3,6 +3,8 @@
#include "gui/tabcontent.h"
#include "core/messagesmodel.h"
class WebBrowser;
class FeedsView;
@ -33,10 +35,12 @@ class FeedMessageViewer : public TabContent {
void quitDownloader();
public slots:
// Feed updates.
void updateSelectedFeeds();
void updateAllFeeds();
protected slots:
protected slots:
// Reacts on feed updates.
void onFeedUpdatesProgress(FeedsModelFeed *feed, int current, int total);
void onFeedUpdatesFinished();

View File

@ -53,7 +53,7 @@ QList<FeedsModelFeed *> FeedsView::selectedFeeds() const {
}
QList<FeedsModelFeed *> FeedsView::allFeeds() const {
return m_sourceModel->getAllFeeds();
return m_sourceModel->allFeeds();
}
FeedsModelCategory *FeedsView::isCurrentIndexCategory() const {
@ -133,6 +133,17 @@ void FeedsView::markAllFeedsRead() {
markAllFeedsReadStatus(1);
}
void FeedsView::openSelectedFeedsInNewspaperMode() {
// TODO: oznacit vybrane feedy jako prectene zde
// protoze je uzivatel otvira v newspaperu -> jsou prectene automaticky
QList<Message> messages = m_sourceModel->messagesForFeeds(selectedFeeds());
if (!messages.isEmpty()) {
emit newspaperModeRequested(messages);
}
}
void FeedsView::updateCountsOfSelectedFeeds(bool update_total_too) {
foreach (FeedsModelFeed *feed, selectedFeeds()) {
feed->updateCounts(update_total_too);

View File

@ -3,6 +3,8 @@
#include <QTreeView>
#include "core/messagesmodel.h"
// TODO: http://soundguyrob.files.wordpress.com/2011/03/screen-shot-2011-03-01-at-7-45-23-pm.jpg
// přepsat počet nepřečtených zpráv podle screenshotu (tedy smazat asi sloupec "unread")
@ -54,6 +56,9 @@ class FeedsView : public QTreeView {
void markAllFeedsReadStatus(int read);
void markAllFeedsRead();
// Newspaper accessors.
void openSelectedFeedsInNewspaperMode();
// Feed clearers.
void setSelectedFeedsClearStatus(int clear);
void clearSelectedFeeds();
@ -68,6 +73,7 @@ class FeedsView : public QTreeView {
// Reloads counts for all feeds.
void updateCountsOfAllFeeds(bool update_total_too = true);
// Reloads counts for particular feed.
void updateCountsOfParticularFeed(FeedsModelFeed *feed, bool update_total_too = true);
protected:
@ -92,6 +98,9 @@ class FeedsView : public QTreeView {
// Emitted if user selects new feeds.
void feedsSelected(const QList<int> &feed_ids);
// Requests opening of given messages in newspaper mode.
void newspaperModeRequested(const QList<Message> &messages);
private:
QMenu *m_contextMenuCategoriesFeeds;
QMenu *m_contextMenuEmptySpace;

View File

@ -15,7 +15,7 @@
FormCategoryDetails::FormCategoryDetails(FeedsModel *model, QWidget *parent)
: QDialog(parent), m_editableCategory(NULL) {
initialize();
loadCategories(model->getAllCategories().values(),
loadCategories(model->allCategories().values(),
model->rootItem());
setWindowTitle(tr("Add new category"));

View File

@ -17,7 +17,7 @@ class FeedsModelRootItem;
class FormCategoryDetailsAnswer {
public:
int m_dialogCode;
FeedsModelCategory *m_outputItem;
FeedsModelCategory *m_outputCategory;
FeedsModelRootItem *m_outputParentItem;
};

View File

@ -233,6 +233,7 @@ void FormMain::setupIcons() {
m_ui->m_actionOpenSelectedSourceArticlesInternally->setIcon(IconThemeFactory::getInstance()->fromTheme("document-open"));
m_ui->m_actionOpenSelectedSourceArticlesExternally->setIcon(IconThemeFactory::getInstance()->fromTheme("document-open"));
m_ui->m_actionOpenSelectedMessagesInternally->setIcon(IconThemeFactory::getInstance()->fromTheme("document-open"));
m_ui->m_actionViewSelectedItemsNewspaperMode->setIcon(IconThemeFactory::getInstance()->fromTheme("document-multiple"));
// Setup icons for underlying components: opened web browsers...
foreach (WebBrowser *browser, WebBrowser::runningWebBrowsers()) {

View File

@ -15,16 +15,7 @@
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<property name="margin">
<number>0</number>
</property>
<item>
@ -48,7 +39,7 @@
<x>0</x>
<y>0</y>
<width>979</width>
<height>21</height>
<height>20</height>
</rect>
</property>
<widget class="QMenu" name="m_menuFile">
@ -102,6 +93,7 @@
<addaction name="m_actionEditSelectedFeedCategory"/>
<addaction name="m_actionDeleteSelectedFeedsCategories"/>
<addaction name="separator"/>
<addaction name="m_actionViewSelectedItemsNewspaperMode"/>
<addaction name="m_actionMarkAllFeedsRead"/>
<addaction name="m_actionMarkFeedsAsRead"/>
<addaction name="m_actionMarkFeedsAsUnread"/>
@ -392,6 +384,14 @@
<string>Mark all messages in all feeds read. This does not take message filters into account.</string>
</property>
</action>
<action name="m_actionViewSelectedItemsNewspaperMode">
<property name="text">
<string>View selected items in newspaper mode</string>
</property>
<property name="toolTip">
<string>Displays all messages from selected feeds/categories in a new &quot;newspaper mode&quot; tab.</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -181,6 +181,12 @@ int TabWidget::addBrowserWithMessage(const Message &message) {
return new_index;
}
int TabWidget::addBrowserWithMessages(const QList<Message> &messages) {
int new_index = addBrowser(false, true);
static_cast<WebBrowser*>(widget(new_index))->navigateToMessages(messages);
return new_index;
}
int TabWidget::addEmptyBrowser() {
return addBrowser(false, true);
}

View File

@ -77,7 +77,9 @@ class TabWidget : public QTabWidget {
// Closes all "closable" tabs except the active tab.
void closeAllTabsExceptCurrent();
// Open single or multiple (newspaper mode) messages in new tab.
int addBrowserWithMessage(const Message &message);
int addBrowserWithMessages(const QList<Message> &messages);
// Adds new WebBrowser tab to global TabWidget.
int addEmptyBrowser();

View File

@ -174,7 +174,7 @@ void WebBrowser::navigateToMessage(const Message &message) {
message.m_contents,
message.m_created.toString(Qt::DefaultLocaleShortDate));
QString layout_wrapper = SkinFactory::getInstance()->getCurrentMarkupLayout().arg(tr("Newspaper view"),
QString layout_wrapper = SkinFactory::getInstance()->getCurrentMarkupLayout().arg(message.m_title,
message_layout);
m_webView->setHtml(layout_wrapper);