Initial implementation of newspaper view.
This commit is contained in:
parent
37f631193e
commit
9149b90042
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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"));
|
||||
|
@ -17,7 +17,7 @@ class FeedsModelRootItem;
|
||||
class FormCategoryDetailsAnswer {
|
||||
public:
|
||||
int m_dialogCode;
|
||||
FeedsModelCategory *m_outputItem;
|
||||
FeedsModelCategory *m_outputCategory;
|
||||
FeedsModelRootItem *m_outputParentItem;
|
||||
};
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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 "newspaper mode" tab.</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user