diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0df1f5a53..cd6c78b8a 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -417,6 +417,7 @@ set(APP_SOURCES
# ABSTRACT service sources.
src/services/abstract/serviceentrypoint.cpp
src/services/abstract/feed.cpp
+ src/services/abstract/category.cpp
src/services/abstract/serviceroot.cpp
# STANDARD feed service sources.
@@ -429,6 +430,7 @@ set(APP_SOURCES
src/services/standard/standardserviceentrypoint.cpp
src/services/standard/standardserviceroot.cpp
src/services/standard/standardrecyclebin.cpp
+ src/services/standard/standarditem.cpp
# TT-RSS feed service sources.
src/services/tt-rss/ttrssserviceentrypoint.cpp
diff --git a/resources/text/CHANGELOG b/resources/text/CHANGELOG
index 936cec063..030cf17d3 100644
--- a/resources/text/CHANGELOG
+++ b/resources/text/CHANGELOG
@@ -12,6 +12,19 @@
+ 2.5.3
+
+ Added:
+
+
+ Fixed:
+
+
+
2.5.2
Added:
diff --git a/src/core/feedsmodel.cpp b/src/core/feedsmodel.cpp
index cd6bc51e7..494d12bc8 100755
--- a/src/core/feedsmodel.cpp
+++ b/src/core/feedsmodel.cpp
@@ -232,42 +232,15 @@ bool FeedsModel::removeItem(const QModelIndex &index) {
return false;
}
-bool FeedsModel::addCategory(StandardCategory *category, RootItem *parent) {
+void FeedsModel::assignNodeToNewParent(RootItem *item, RootItem *parent) {
// Get index of parent item (parent standard category).
QModelIndex parent_index = indexForItem(parent);
- bool result = category->addItself(parent);
- if (result) {
- // Category was added to the persistent storage,
- // so add it to the model.
- beginInsertRows(parent_index, parent->childCount(), parent->childCount());
- parent->appendChild(category);
- endInsertRows();
- }
- else {
- // We cannot delete (*this) in its method, thus delete it here.
- delete category;
- }
+ // TODO: todle jde sloučit s metodou reassignNodeToNewParent.
- return result;
-}
-
-bool FeedsModel::addFeed(StandardFeed *feed, RootItem *parent) {
- // Get index of parent item (parent standard category or root item).
- QModelIndex parent_index = indexForItem(parent);
- bool result = feed->addItself(parent);
-
- if (result) {
- // Feed was added to the persistent storage so add it to the model.
- beginInsertRows(parent_index, parent->childCount(), parent->childCount());
- parent->appendChild(feed);
- endInsertRows();
- }
- else {
- delete feed;
- }
-
- return result;
+ beginInsertRows(parent_index, parent->childCount(), parent->childCount());
+ parent->appendChild(item);
+ endInsertRows();
}
void FeedsModel::reassignNodeToNewParent(RootItem *original_node, RootItem *new_parent) {
@@ -378,10 +351,10 @@ RootItem *FeedsModel::itemForIndex(const QModelIndex &index) const {
}
}
-StandardCategory *FeedsModel::categoryForIndex(const QModelIndex &index) const {
+Category *FeedsModel::categoryForIndex(const QModelIndex &index) const {
RootItem *item = itemForIndex(index);
- if (item->kind() == RootItem::Cattegory) {
+ if (item->kind() == RootItemKind::Category) {
return item->toCategory();
}
else {
@@ -390,14 +363,14 @@ StandardCategory *FeedsModel::categoryForIndex(const QModelIndex &index) const {
}
QModelIndex FeedsModel::indexForItem(RootItem *item) const {
- if (item == NULL || item->kind() == RootItem::Root) {
+ if (item == NULL || item->kind() == RootItemKind::Root) {
// Root item lies on invalid index.
return QModelIndex();
}
QStack chain;
- while (item->kind() != RootItem::Root) {
+ while (item->kind() != RootItemKind::Root) {
chain.push(item);
item = item->parent();
}
@@ -424,84 +397,6 @@ bool FeedsModel::hasAnyFeedNewMessages() {
return false;
}
-bool FeedsModel::mergeModel(FeedsImportExportModel *model, QString &output_message) {
- if (model == NULL || model->rootItem() == NULL) {
- output_message = tr("Invalid tree data.");
- qDebug("Root item for merging two models is null.");
- return false;
- }
-
- QStack original_parents; original_parents.push(m_rootItem);
- QStack new_parents; new_parents.push(model->rootItem());
- bool some_feed_category_error = false;
-
- // We are definitely about to add some new items into the model.
- //emit layoutAboutToBeChanged();
-
- // Iterate all new items we would like to merge into current model.
- while (!new_parents.isEmpty()) {
- RootItem *target_parent = original_parents.pop();
- RootItem *source_parent = new_parents.pop();
-
- foreach (RootItem *source_item, source_parent->childItems()) {
- if (!model->isItemChecked(source_item)) {
- // We can skip this item, because it is not checked and should not be imported.
- // NOTE: All descendants are thus skipped too.
- continue;
- }
-
- if (source_item->kind() == RootItem::Cattegory) {
- StandardCategory *source_category = source_item->toCategory();
- StandardCategory *new_category = new StandardCategory(*source_category);
-
- // Add category to model.
- new_category->clearChildren();
-
- if (addCategory(new_category, target_parent)) {
- // Process all children of this category.
- original_parents.push(new_category);
- new_parents.push(source_category);
- }
- else {
- // Add category failed, but this can mean that the same category (with same title)
- // already exists. If such a category exists in current parent, then find it and
- // add descendants to it.
- RootItem *existing_category = target_parent->child(RootItem::Cattegory, new_category->title());
-
- if (existing_category != NULL) {
- original_parents.push(existing_category);
- new_parents.push(source_category);
- }
- else {
- some_feed_category_error = true;
- }
- }
- }
- else if (source_item->kind() == RootItem::Feeed) {
- StandardFeed *source_feed = source_item->toFeed();
- StandardFeed *new_feed = new StandardFeed(*source_feed);
-
- // Append this feed and end this iteration.
- if (!addFeed(new_feed, target_parent)) {
- some_feed_category_error = true;
- }
- }
- }
- }
-
- // Changes are done now. Finalize the new model.
- //emit layoutChanged();
-
- if (some_feed_category_error) {
- output_message = tr("Import successfull, but some feeds/categories were not imported due to error.");
- }
- else {
- output_message = tr("Import was completely successfull.");
- }
-
- return !some_feed_category_error;
-}
-
void FeedsModel::reloadChangedLayout(QModelIndexList list) {
while (!list.isEmpty()) {
QModelIndex indx = list.takeFirst();
@@ -535,7 +430,7 @@ void FeedsModel::loadActivatedServiceAccounts() {
foreach (ServiceEntryPoint *entry_point, qApp->feedServices()) {
// Load all stored root nodes from the entry point and add those to the model.
- QList roots = entry_point->initializeSubtree();
+ QList roots = entry_point->initializeSubtree(this);
foreach (ServiceRoot *root, roots) {
m_rootItem->appendChild(root);
@@ -551,8 +446,8 @@ QList FeedsModel::feedsForIndex(const QModelIndex &index) {
Feed *FeedsModel::feedForIndex(const QModelIndex &index) {
RootItem *item = itemForIndex(index);
- if (item->kind() == RootItem::Feeed) {
- return static_cast(item);
+ if (item->kind() == RootItemKind::Feed) {
+ return item->toFeed();
}
else {
return NULL;
@@ -579,7 +474,7 @@ QList FeedsModel::feedsForIndexes(const QModelIndexList &indexes) {
return feeds;
}
-bool FeedsModel::markFeedsRead(const QList &feeds, int read) {
+bool FeedsModel::markFeedsRead(const QList &feeds, int read) {
QSqlDatabase db_handle = qApp->database()->connection(objectName(), DatabaseFactory::FromSettings);
if (!db_handle.transaction()) {
@@ -660,36 +555,6 @@ bool FeedsModel::markFeedsDeleted(const QList &feeds, int deleted, bool r
}
}
-QHash FeedsModel::allCategories() {
- return categoriesForItem(m_rootItem);
-}
-
-QHash FeedsModel::categoriesForItem(RootItem *root) {
- QHash categories;
- QList parents;
-
- parents.append(root->childItems());
-
- while (!parents.isEmpty()) {
- RootItem *item = parents.takeFirst();
-
- if (item->kind() == RootItem::Cattegory) {
- // This item is category, add it to the output list and
- // scan its children.
- int category_id = item->id();
- StandardCategory *category = item->toCategory();
-
- if (!categories.contains(category_id)) {
- categories.insert(category_id, category);
- }
-
- parents.append(category->childItems());
- }
- }
-
- return categories;
-}
-
QList FeedsModel::allFeeds() {
return feedsForItem(m_rootItem);
}
@@ -699,8 +564,10 @@ QList FeedsModel::feedsForItem(RootItem *root) {
QList feeds;
foreach (RootItem *child, children) {
- if (child->kind() == RootItem::Feeed) {
- feeds.append(child->toFeed());
+ Feed *converted = dynamic_cast(child);
+
+ if (converted != NULL) {
+ feeds.append(converted);
}
}
diff --git a/src/core/feedsmodel.h b/src/core/feedsmodel.h
index e8854e403..4470ccc0d 100755
--- a/src/core/feedsmodel.h
+++ b/src/core/feedsmodel.h
@@ -26,9 +26,9 @@
#include
+class Category;
class StandardCategory;
class Feed;
-class StandardRecycleBin;
class FeedsImportExportModel;
class QTimer;
@@ -64,11 +64,8 @@ class FeedsModel : public QAbstractItemModel {
// Removes item with given index.
bool removeItem(const QModelIndex &index);
- // Standard category manipulators.
- bool addCategory(StandardCategory *category, RootItem *parent);
-
- // Standard feed manipulators.
- bool addFeed(StandardFeed *feed, RootItem *parent);
+ // Assigns item to the new parent.
+ void assignNodeToNewParent(RootItem *item, RootItem *parent);
// Checks if new parent node is different from one used by original node.
// If it is, then it reassigns original_node to new parent.
@@ -86,14 +83,6 @@ class FeedsModel : public QAbstractItemModel {
// in "newspaper" mode.
QList messagesForFeeds(const QList &feeds);
- // Returns all categories, each pair
- // consists of ID of parent item and pointer to category.
- QHash allCategories();
-
- // Returns categories from the subtree with given root node, each pair
- // consists of ID of parent item and pointer to category.
- QHash categoriesForItem(RootItem *root);
-
// Returns list of all feeds contained in the model.
QList allFeeds();
@@ -113,7 +102,7 @@ class FeedsModel : public QAbstractItemModel {
// Returns pointer to category if it lies on given index
// or NULL if no category lies on given index.
- StandardCategory *categoryForIndex(const QModelIndex &index) const;
+ Category *categoryForIndex(const QModelIndex &index) const;
// Returns feed/category which lies at the specified index or
// root item if index is invalid.
@@ -130,10 +119,6 @@ class FeedsModel : public QAbstractItemModel {
return m_rootItem;
}
- // Takes structure residing under given root item and adds feeds/categories from
- // it to active structure.
- bool mergeModel(FeedsImportExportModel *model, QString &output_message);
-
// Resets global auto-update intervals according to settings
// and starts/stop the timer as needed.
void updateAutoUpdateStatus();
diff --git a/src/core/feedsproxymodel.cpp b/src/core/feedsproxymodel.cpp
index 9c1b54f6c..d2b6fbd9f 100755
--- a/src/core/feedsproxymodel.cpp
+++ b/src/core/feedsproxymodel.cpp
@@ -155,15 +155,15 @@ bool FeedsProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right
return QString::localeAwareCompare(left_item->title(), right_item->title()) < 0;
}
}
- else if (left_item->kind() == RootItem::Bin) {
+ else if (left_item->kind() == RootItemKind::Bin) {
// Left item is recycle bin. Make sure it is "biggest" item if we have selected ascending order.
return sortOrder() == Qt::DescendingOrder;
}
- else if (right_item->kind() == RootItem::Bin) {
+ else if (right_item->kind() == RootItemKind::Bin) {
// Right item is recycle bin. Make sure it is "smallest" item if we have selected descending order.
return sortOrder() == Qt::AscendingOrder;
}
- else if (left_item->kind() == RootItem::Feeed) {
+ else if (left_item->kind() == RootItemKind::Feed) {
// Left item is feed, right item is category.
return false;
}
@@ -193,7 +193,7 @@ bool FeedsProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source
RootItem *item = m_sourceModel->itemForIndex(idx);
- if (item->kind() == RootItem::Bin) {
+ if (item->kind() == RootItemKind::Bin) {
// Recycle bin is always displayed.
return true;
}
diff --git a/src/core/feedsselection.cpp b/src/core/feedsselection.cpp
index e01624d21..ba563eb95 100755
--- a/src/core/feedsselection.cpp
+++ b/src/core/feedsselection.cpp
@@ -39,11 +39,11 @@ FeedsSelection::SelectionMode FeedsSelection::mode() {
}
switch (m_selectedItem->kind()) {
- case RootItem::Bin:
+ case RootItemKind::Bin:
return FeedsSelection::MessagesFromRecycleBin;
- case RootItem::Cattegory:
- case RootItem::Feeed:
+ case RootItemKind::Category:
+ case RootItemKind::Feed:
return FeedsSelection::MessagesFromFeeds;
default:
@@ -57,12 +57,12 @@ RootItem *FeedsSelection::selectedItem() const {
QString FeedsSelection::generateListOfIds() {
if (m_selectedItem != NULL &&
- (m_selectedItem->kind() == RootItem::Feeed || m_selectedItem->kind() == RootItem::Cattegory)) {
+ (m_selectedItem->kind() == RootItemKind::Feed || m_selectedItem->kind() == RootItemKind::Category)) {
QList children = m_selectedItem->getRecursiveChildren();
QStringList stringy_ids;
foreach (RootItem *child, children) {
- if (child->kind() == RootItem::Feeed) {
+ if (child->kind() == RootItemKind::Feed) {
stringy_ids.append(QString::number(child->id()));
}
}
diff --git a/src/core/rootitem.cpp b/src/core/rootitem.cpp
index 79bac83e7..62f7cf587 100755
--- a/src/core/rootitem.cpp
+++ b/src/core/rootitem.cpp
@@ -25,7 +25,7 @@
RootItem::RootItem(RootItem *parent_item)
- : m_kind(RootItem::Root),
+ : m_kind(RootItemKind::Root),
m_id(NO_PARENT_CATEGORY),
m_title(QString()),
m_description(QString()),
@@ -77,8 +77,9 @@ int RootItem::countOfAllMessages() const {
QList RootItem::getRecursiveChildren() {
QList children;
- if (kind() == RootItem::Feeed) {
- // Root itself is a FEED.
+ if (childCount() == 0) {
+ // Root itself has no children, it is either feed or
+ // empty category?
children.append(this);
}
else {
@@ -89,14 +90,14 @@ QList RootItem::getRecursiveChildren() {
// Iterate all nested categories.
while (!traversable_items.isEmpty()) {
- RootItem *active_category = traversable_items.takeFirst();
+ RootItem *active_item = traversable_items.takeFirst();
- foreach (RootItem *child, active_category->childItems()) {
- if (child->kind() == RootItem::Feeed) {
- // This child is feed.
+ foreach (RootItem *child, active_item->childItems()) {
+ if (child->childCount() == 0) {
+ // This child is feed or empty category.
children.append(child);
}
- else if (child->kind() == RootItem::Cattegory) {
+ else {
// This child is category, add its child feeds too.
traversable_items.append(child);
}
@@ -111,25 +112,12 @@ bool RootItem::removeChild(RootItem *child) {
return m_childItems.removeOne(child);
}
-StandardCategory *RootItem::toCategory() {
- return static_cast(this);
+Category *RootItem::toCategory() {
+ return static_cast(this);
}
-StandardFeed *RootItem::toFeed() {
- return static_cast(this);
-}
-
-RootItem *RootItem::child(RootItem::Kind kind_of_child, const QString &identifier) {
- foreach (RootItem *child, childItems()) {
- if (child->kind() == kind_of_child) {
- if ((kind_of_child == Cattegory && child->title() == identifier) ||
- (kind_of_child == Feeed && child->toFeed()->url() == identifier)) {
- return child;
- }
- }
- }
-
- return NULL;
+Feed *RootItem::toFeed() {
+ return static_cast(this);
}
int RootItem::countOfUnreadMessages() const {
diff --git a/src/core/rootitem.h b/src/core/rootitem.h
index 6e8fca168..812528ed9 100755
--- a/src/core/rootitem.h
+++ b/src/core/rootitem.h
@@ -22,23 +22,24 @@
#include
#include
-class StandardRecycleBin;
-class StandardCategory;
-class StandardFeed;
+class Category;
+class Feed;
+
+namespace RootItemKind {
+ // Describes the kind of the item.
+ enum Kind {
+ Root = 1001,
+ Bin = 1002,
+ Feed = 1003,
+ Category = 1004
+ };
+}
// Represents ROOT item of FeedsModel.
// NOTE: This class is derived to add functionality for
// all other non-root items of FeedsModel.
class RootItem {
public:
- // Describes the kind of the item.
- enum Kind {
- Root = 1001,
- Bin = 1002,
- Feeed = 1003,
- Cattegory = 1004
- };
-
// Constructors and destructors.
explicit RootItem(RootItem *parent_item = NULL);
virtual ~RootItem();
@@ -56,8 +57,6 @@ class RootItem {
return m_childItems.value(row);
}
- virtual RootItem *child(RootItem::Kind kind_of_child, const QString &identifier);
-
inline virtual int childCount() const {
return m_childItems.size();
}
@@ -110,7 +109,7 @@ class RootItem {
RootItem *this_item = this;
- while (this_item->kind() != RootItem::Root) {
+ while (this_item->kind() != RootItemKind::Root) {
if (root->childItems().contains(this_item)) {
return true;
}
@@ -122,6 +121,7 @@ class RootItem {
return false;
}
+ // Is "this" item parent if given child?
bool isParentOf(RootItem *child) {
if (child == NULL) {
return false;
@@ -144,7 +144,7 @@ class RootItem {
bool removeChild(int index);
bool removeChild(RootItem *child);
- inline Kind kind() const {
+ inline RootItemKind::Kind kind() const {
return m_kind;
}
@@ -192,8 +192,8 @@ class RootItem {
}
// Converters
- StandardCategory *toCategory();
- StandardFeed *toFeed();
+ Category *toCategory();
+ Feed *toFeed();
// Compares two model items.
static bool isEqual(RootItem *lhs, RootItem *rhs);
@@ -202,7 +202,7 @@ class RootItem {
protected:
void setupFonts();
- Kind m_kind;
+ RootItemKind::Kind m_kind;
int m_id;
QString m_title;
QString m_description;
diff --git a/src/gui/dialogs/formmain.cpp b/src/gui/dialogs/formmain.cpp
index 1c06b20d1..4baef3183 100755
--- a/src/gui/dialogs/formmain.cpp
+++ b/src/gui/dialogs/formmain.cpp
@@ -401,17 +401,25 @@ void FormMain::loadWebBrowserMenu(int index) {
}
void FormMain::exportFeeds() {
+ // TODO: dodelat globalni pristup ke globalnimu standard service rootu,
+ // ten předat
+ /*
QPointer form = new FormStandardImportExport(this);
form.data()->setMode(FeedsImportExportModel::Export);
form.data()->exec();
delete form.data();
+ */
}
void FormMain::importFeeds() {
+ // TODO: dodelat globalni pristup ke globalnimu standard service rootu,
+ // ten předat
+ /*
QPointer form = new FormStandardImportExport(this);
form.data()->setMode(FeedsImportExportModel::Import);
form.data()->exec();
delete form.data();
+ */
}
void FormMain::backupDatabaseSettings() {
diff --git a/src/gui/feedmessageviewer.cpp b/src/gui/feedmessageviewer.cpp
index 94ec10de0..df6fc5af8 100755
--- a/src/gui/feedmessageviewer.cpp
+++ b/src/gui/feedmessageviewer.cpp
@@ -209,9 +209,12 @@ void FeedMessageViewer::loadInitialFeeds() {
model.importAsOPML20(IOFactory::readTextFile(file_to_load));
model.checkAllItems();
+ // TODO: dodělat, předpokládá nějaký rozumný přístup k standardnímu root servicu.
+ /*
if (m_feedsView->sourceModel()->mergeModel(&model, output_msg)) {
m_feedsView->expandAll();
}
+ */
}
catch (ApplicationException &ex) {
MessageBox::show(this, QMessageBox::Critical, tr("Error when loading initial feeds"), ex.message());
diff --git a/src/gui/feedsview.cpp b/src/gui/feedsview.cpp
index fe501e073..d780bcf61 100755
--- a/src/gui/feedsview.cpp
+++ b/src/gui/feedsview.cpp
@@ -96,7 +96,7 @@ RootItem *FeedsView::selectedItem() const {
return selected_item == m_sourceModel->rootItem() ? NULL : selected_item;
}
-StandardCategory *FeedsView::selectedCategory() const {
+Category *FeedsView::selectedCategory() const {
QModelIndex current_mapped = m_proxyModel->mapToSource(currentIndex());
return m_sourceModel->categoryForIndex(current_mapped);
}
@@ -109,22 +109,27 @@ Feed *FeedsView::selectedFeed() const {
void FeedsView::saveExpandedStates() {
Settings *settings = qApp->settings();
+ // TODO: doědlat
+
// Iterate all categories and save their expand statuses.
- foreach (StandardCategory *category, sourceModel()->allCategories().values()) {
+
+ /*foreach (Category *category, sourceModel()->allCategories().values()) {
settings->setValue(GROUP(Categories),
QString::number(category->id()),
isExpanded(model()->mapFromSource(sourceModel()->indexForItem(category))));
- }
+ }*/
}
void FeedsView::loadExpandedStates() {
Settings *settings = qApp->settings();
+ // TODO: doědlat
+
// Iterate all categories and save their expand statuses.
- foreach (StandardCategory *category, sourceModel()->allCategories().values()) {
+ /*foreach (Category *category, sourceModel()->allCategories().values()) {
setExpanded(model()->mapFromSource(sourceModel()->indexForItem(category)),
settings->value(GROUP(Categories), QString::number(category->id()), true).toBool());
- }
+ }*/
}
void FeedsView::invalidateReadFeedsFilter(bool set_new_value, bool show_unread_only) {
@@ -185,48 +190,6 @@ void FeedsView::clearAllFeeds() {
setAllFeedsClearStatus(1);
}
-void FeedsView::addNewCategory() {
- if (!qApp->feedUpdateLock()->tryLock()) {
- // Lock was not obtained because
- // it is used probably by feed updater or application
- // is quitting.
- qApp->showGuiMessage(tr("Cannot add standard category"),
- tr("You cannot add new standard category now because another critical operation is ongoing."),
- QSystemTrayIcon::Warning, qApp->mainForm(), true);
- return;
- }
-
- QPointer form_pointer = new FormStandardCategoryDetails(m_sourceModel, this);
-
- form_pointer.data()->exec(NULL, selectedItem());
-
- delete form_pointer.data();
-
- // Changes are done, unlock the update master lock.
- qApp->feedUpdateLock()->unlock();
-}
-
-void FeedsView::addNewFeed() {
- if (!qApp->feedUpdateLock()->tryLock()) {
- // Lock was not obtained because
- // it is used probably by feed updater or application
- // is quitting.
- qApp->showGuiMessage(tr("Cannot add standard feed"),
- tr("You cannot add new standard feed now because another critical operation is ongoing."),
- QSystemTrayIcon::Warning, qApp->mainForm(), true);
- return;
- }
-
- QPointer form_pointer = new FormStandardFeedDetails(m_sourceModel, this);
-
- form_pointer.data()->exec(NULL, selectedItem());
-
- delete form_pointer.data();
-
- // Changes are done, unlock the update master lock.
- qApp->feedUpdateLock()->unlock();
-}
-
void FeedsView::receiveMessageCountsChange(FeedsSelection::SelectionMode mode,
bool total_msg_count_changed,
bool any_msg_restored) {
@@ -594,7 +557,7 @@ void FeedsView::contextMenuEvent(QContextMenuEvent *event) {
QModelIndex mapped_index = model()->mapToSource(clicked_index);
RootItem *clicked_item = sourceModel()->itemForIndex(mapped_index);
- if (clicked_item->kind() == RootItem::Cattegory) {
+ if (clicked_item->kind() == RootItemKind::Category) {
// Display context menu for categories.
if (m_contextMenuCategories == NULL) {
// Context menu is not initialized, initialize.
@@ -603,7 +566,7 @@ void FeedsView::contextMenuEvent(QContextMenuEvent *event) {
m_contextMenuCategories->exec(event->globalPos());
}
- else if (clicked_item->kind() == RootItem::Feeed) {
+ else if (clicked_item->kind() == RootItemKind::Feed) {
// Display context menu for feeds.
if (m_contextMenuFeeds == NULL) {
// Context menu is not initialized, initialize.
diff --git a/src/gui/feedsview.h b/src/gui/feedsview.h
index d96a61932..c1725f2c6 100755
--- a/src/gui/feedsview.h
+++ b/src/gui/feedsview.h
@@ -29,6 +29,7 @@
class FeedsProxyModel;
class Feed;
+class Category;
class StandardCategory;
class QTimer;
@@ -59,7 +60,7 @@ class FeedsView : public QTreeView {
// Returns pointers to selected feed/category if they are really
// selected.
RootItem *selectedItem() const;
- StandardCategory *selectedCategory() const;
+ Category *selectedCategory() const;
Feed *selectedFeed() const;
// Saves/loads expand states of all nodes (feeds/categories) of the list to/from settings.
@@ -101,12 +102,6 @@ class FeedsView : public QTreeView {
void editSelectedItem();
void deleteSelectedItem();
- // Standard category manipulators.
- void addNewCategory();
-
- // Standard feed manipulators.
- void addNewFeed();
-
// Is called when counts of messages are changed externally,
// typically from message view.
void receiveMessageCountsChange(FeedsSelection::SelectionMode mode, bool total_msg_count_changed, bool any_msg_restored);
diff --git a/src/miscellaneous/application.h b/src/miscellaneous/application.h
index d23a7a847..c9aa87cb5 100755
--- a/src/miscellaneous/application.h
+++ b/src/miscellaneous/application.h
@@ -55,6 +55,8 @@ class Application : public QtSingleApplication {
explicit Application(const QString &id, int &argc, char **argv);
virtual ~Application();
+ // List of all installed "feed service plugins", including obligatory
+ // "standard" service entry point.
QList feedServices();
QList userActions();
diff --git a/src/miscellaneous/settings.h b/src/miscellaneous/settings.h
index 5c9d4ac7a..c254e7cee 100755
--- a/src/miscellaneous/settings.h
+++ b/src/miscellaneous/settings.h
@@ -360,6 +360,7 @@ class Settings : public QSettings {
// Creates settings file in correct location.
static Settings *setupSettings(QObject *parent);
+ // Returns properties of the actual application-wide settings.
static SettingsProperties determineProperties();
private:
diff --git a/src/network-web/webbrowser.cpp b/src/network-web/webbrowser.cpp
index eda30878a..c1da07cae 100755
--- a/src/network-web/webbrowser.cpp
+++ b/src/network-web/webbrowser.cpp
@@ -214,7 +214,9 @@ void WebBrowser::onIconChanged() {
void WebBrowser::addFeedFromWebsite(const QString &feed_link) {
qApp->clipboard()->setText(feed_link);
- qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->addNewFeed();
+
+ // TODO: dodělat
+ //qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->addNewFeed();
}
void WebBrowser::onTitleChanged(const QString &new_title) {
diff --git a/src/services/abstract/category.cpp b/src/services/abstract/category.cpp
new file mode 100755
index 000000000..52707e0ac
--- /dev/null
+++ b/src/services/abstract/category.cpp
@@ -0,0 +1,9 @@
+#include "services/abstract/category.h"
+
+
+Category::Category(RootItem *parent) : RootItem(parent) {
+}
+
+Category::~Category() {
+}
+
diff --git a/src/services/abstract/category.h b/src/services/abstract/category.h
new file mode 100755
index 000000000..aaf55caef
--- /dev/null
+++ b/src/services/abstract/category.h
@@ -0,0 +1,13 @@
+#ifndef CATEGORY_H
+#define CATEGORY_H
+
+#include "core/rootitem.h"
+
+
+class Category : public RootItem {
+ public:
+ explicit Category(RootItem *parent = NULL);
+ virtual ~Category();
+};
+
+#endif // CATEGORY_H
diff --git a/src/services/abstract/feed.cpp b/src/services/abstract/feed.cpp
index b3d8c61e8..c7a030a5f 100755
--- a/src/services/abstract/feed.cpp
+++ b/src/services/abstract/feed.cpp
@@ -34,3 +34,7 @@ int Feed::childCount() const {
// Because feed has no children.
return 0;
}
+
+void Feed::appendChild(RootItem *child) {
+ Q_UNUSED(child)
+}
diff --git a/src/services/abstract/feed.h b/src/services/abstract/feed.h
index df2b28776..62ba9d2b2 100755
--- a/src/services/abstract/feed.h
+++ b/src/services/abstract/feed.h
@@ -37,7 +37,9 @@ class Feed : public RootItem {
enum Status {
Normal = 0,
NewMessages = 1,
- NetworkError = 2
+ NetworkError = 2,
+ ParsingError = 3,
+ OtherError = 4
};
// Constructors.
@@ -47,6 +49,9 @@ class Feed : public RootItem {
// Returns 0, feeds have no children.
int childCount() const;
+ // Appending of childs to feed is not allowed.
+ void appendChild(RootItem *child);
+
// Performs synchronous update and returns number of newly updated messages.
virtual int update() = 0;
diff --git a/src/services/abstract/serviceentrypoint.h b/src/services/abstract/serviceentrypoint.h
index f6a257989..ecfc75334 100755
--- a/src/services/abstract/serviceentrypoint.h
+++ b/src/services/abstract/serviceentrypoint.h
@@ -24,6 +24,7 @@
class ServiceRoot;
+class FeedsModel;
// TOP LEVEL class which provides basic information about the "service"
class ServiceEntryPoint {
@@ -36,7 +37,7 @@ class ServiceEntryPoint {
// point from persistent DB.
// Returns list of root nodes which will be afterwards added
// to the global feed model.
- virtual QList initializeSubtree() = 0;
+ virtual QList initializeSubtree(FeedsModel *main_model) = 0;
// Must this service account be activated by default?
// NOTE: This is true particularly for "standard" service
diff --git a/src/services/abstract/serviceroot.cpp b/src/services/abstract/serviceroot.cpp
index 109f00ead..5a455e306 100755
--- a/src/services/abstract/serviceroot.cpp
+++ b/src/services/abstract/serviceroot.cpp
@@ -17,10 +17,11 @@
#include "services/abstract/serviceroot.h"
+#include "core/feedsmodel.h"
-ServiceRoot::ServiceRoot(RootItem *parent) : RootItem(parent) {
+
+ServiceRoot::ServiceRoot(FeedsModel *feeds_model, RootItem *parent) : RootItem(parent), m_feedsModel(feeds_model) {
}
ServiceRoot::~ServiceRoot() {
}
-
diff --git a/src/services/abstract/serviceroot.h b/src/services/abstract/serviceroot.h
index 1355f1fb7..94e6b472e 100755
--- a/src/services/abstract/serviceroot.h
+++ b/src/services/abstract/serviceroot.h
@@ -21,13 +21,22 @@
#include "core/rootitem.h"
+class FeedsModel;
+
// THIS IS the root node of the service.
// NOTE: The root usually contains some core functionality of the
// service like service account username/password etc.
class ServiceRoot : public RootItem {
public:
- explicit ServiceRoot(RootItem *parent = NULL);
+ explicit ServiceRoot(FeedsModel *feeds_model, RootItem *parent = NULL);
virtual ~ServiceRoot();
+
+ inline FeedsModel *feedsModel() const {
+ return m_feedsModel;
+ }
+
+ protected:
+ FeedsModel *m_feedsModel;
};
#endif // SERVICEROOT_H
diff --git a/src/services/standard/gui/formstandardcategorydetails.cpp b/src/services/standard/gui/formstandardcategorydetails.cpp
index 34bba3718..b3fd72720 100755
--- a/src/services/standard/gui/formstandardcategorydetails.cpp
+++ b/src/services/standard/gui/formstandardcategorydetails.cpp
@@ -20,13 +20,14 @@
#include "definitions/definitions.h"
#include "core/rootitem.h"
#include "core/feedsmodel.h"
-#include "services/standard/standardcategory.h"
#include "miscellaneous/iconfactory.h"
#include "gui/feedsview.h"
#include "gui/baselineedit.h"
#include "gui/messagebox.h"
#include "gui/systemtrayicon.h"
#include "gui/dialogs/formmain.h"
+#include "services/standard/standardcategory.h"
+#include "services/standard/standardserviceroot.h"
#include
#include
@@ -38,9 +39,8 @@
#include
-FormStandardCategoryDetails::FormStandardCategoryDetails(FeedsModel *model, QWidget *parent) : QDialog(parent),
- m_editableCategory(NULL),
- m_feedsModel(model) {
+FormStandardCategoryDetails::FormStandardCategoryDetails(StandardServiceRoot *service_root, QWidget *parent)
+ : QDialog(parent), m_editableCategory(NULL), m_serviceRoot(service_root) {
initialize();
createConnections();
@@ -76,7 +76,7 @@ void FormStandardCategoryDetails::setEditableCategory(StandardCategory *editable
int FormStandardCategoryDetails::exec(StandardCategory *input_category, RootItem *parent_to_select) {
// Load categories.
- loadCategories(m_feedsModel->allCategories().values(), m_feedsModel->rootItem(), input_category);
+ loadCategories(m_serviceRoot->allCategories().values(), m_serviceRoot, input_category);
if (input_category == NULL) {
// User is adding new category.
@@ -88,10 +88,10 @@ int FormStandardCategoryDetails::exec(StandardCategory *input_category, RootItem
// Load parent from suggested item.
if (parent_to_select != NULL) {
- if (parent_to_select->kind() == RootItem::Cattegory) {
+ if (parent_to_select->kind() == RootItemKind::Category) {
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select)));
}
- else if (parent_to_select->kind() == RootItem::Feeed) {
+ else if (parent_to_select->kind() == RootItemKind::Feed) {
int target_item = m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select->parent()));
if (target_item >= 0) {
@@ -122,10 +122,12 @@ void FormStandardCategoryDetails::apply() {
if (m_editableCategory == NULL) {
// Add the category.
- if (m_feedsModel->addCategory(new_category, parent)) {
+ if (new_category->addItself(parent)) {
+ m_serviceRoot->feedsModel()->assignNodeToNewParent(new_category, parent);
accept();
}
else {
+ delete new_category;
qApp->showGuiMessage(tr("Cannot add category"),
tr("Category was not added due to error."),
QSystemTrayIcon::Critical,
@@ -136,7 +138,7 @@ void FormStandardCategoryDetails::apply() {
bool edited = m_editableCategory->editItself(new_category);
if (edited) {
- m_feedsModel->reassignNodeToNewParent(m_editableCategory, new_category->parent());
+ m_serviceRoot->feedsModel()->reassignNodeToNewParent(m_editableCategory, new_category->parent());
// Remove new temporary feed data holder object.
delete new_category;
@@ -245,8 +247,8 @@ void FormStandardCategoryDetails::initialize() {
}
void FormStandardCategoryDetails::loadCategories(const QList categories,
- RootItem *root_item,
- StandardCategory *input_category) {
+ RootItem *root_item,
+ StandardCategory *input_category) {
m_ui->m_cmbParentCategory->addItem(root_item->icon(),
root_item->title(),
QVariant::fromValue((void*) root_item));
diff --git a/src/services/standard/gui/formstandardcategorydetails.h b/src/services/standard/gui/formstandardcategorydetails.h
index 51c9f60c4..3717b3251 100755
--- a/src/services/standard/gui/formstandardcategorydetails.h
+++ b/src/services/standard/gui/formstandardcategorydetails.h
@@ -28,7 +28,7 @@ namespace Ui {
}
class StandardCategory;
-class StandardCategory;
+class StandardServiceRoot;
class FeedsModel;
class RootItem;
class QMenu;
@@ -39,7 +39,7 @@ class FormStandardCategoryDetails : public QDialog {
public:
// Constructors and destructors.
- explicit FormStandardCategoryDetails(FeedsModel *model, QWidget *parent = 0);
+ explicit FormStandardCategoryDetails(StandardServiceRoot *service_root, QWidget *parent = 0);
virtual ~FormStandardCategoryDetails();
public slots:
@@ -77,7 +77,7 @@ class FormStandardCategoryDetails : public QDialog {
private:
Ui::FormStandardCategoryDetails *m_ui;
StandardCategory *m_editableCategory;
- FeedsModel *m_feedsModel;
+ StandardServiceRoot *m_serviceRoot;
QMenu *m_iconMenu;
QAction *m_actionLoadIconFromFile;
diff --git a/src/services/standard/gui/formstandardfeeddetails.cpp b/src/services/standard/gui/formstandardfeeddetails.cpp
index adf3cf666..7fa6d6c8c 100755
--- a/src/services/standard/gui/formstandardfeeddetails.cpp
+++ b/src/services/standard/gui/formstandardfeeddetails.cpp
@@ -20,6 +20,7 @@
#include "definitions/definitions.h"
#include "core/feedsmodel.h"
#include "core/rootitem.h"
+#include "services/standard/standardserviceroot.h"
#include "services/standard/standardcategory.h"
#include "services/standard/standardfeed.h"
#include "miscellaneous/textfactory.h"
@@ -39,10 +40,10 @@
#include
-FormStandardFeedDetails::FormStandardFeedDetails(FeedsModel *model, QWidget *parent)
+FormStandardFeedDetails::FormStandardFeedDetails(StandardServiceRoot *service_root, QWidget *parent)
: QDialog(parent),
m_editableFeed(NULL),
- m_feedsModel(model) {
+ m_serviceRoot(service_root) {
initialize();
createConnections();
@@ -60,7 +61,7 @@ FormStandardFeedDetails::~FormStandardFeedDetails() {
int FormStandardFeedDetails::exec(StandardFeed *input_feed, RootItem *parent_to_select) {
// Load categories.
- loadCategories(m_feedsModel->allCategories().values(), m_feedsModel->rootItem());
+ loadCategories(m_serviceRoot->allCategories().values(), m_serviceRoot);
if (input_feed == NULL) {
// User is adding new category.
@@ -77,10 +78,10 @@ int FormStandardFeedDetails::exec(StandardFeed *input_feed, RootItem *parent_to_
}
if (parent_to_select != NULL) {
- if (parent_to_select->kind() == RootItem::Cattegory) {
+ if (parent_to_select->kind() == RootItemKind::Category) {
m_ui->m_cmbParentCategory->setCurrentIndex(m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select)));
}
- else if (parent_to_select->kind() == RootItem::Feeed) {
+ else if (parent_to_select->kind() == RootItemKind::Feed) {
int target_item = m_ui->m_cmbParentCategory->findData(QVariant::fromValue((void*) parent_to_select->parent()));
if (target_item >= 0) {
@@ -240,10 +241,12 @@ void FormStandardFeedDetails::apply() {
if (m_editableFeed == NULL) {
// Add the feed.
- if (m_feedsModel->addFeed(new_feed, parent)) {
+ if (new_feed->addItself(parent)) {
+ m_serviceRoot->feedsModel()->assignNodeToNewParent(new_feed, parent);
accept();
}
else {
+ delete new_feed;
qApp->showGuiMessage(tr("Cannot add feed"),
tr("Feed was not added due to error."),
QSystemTrayIcon::Critical, this, true);
@@ -254,7 +257,7 @@ void FormStandardFeedDetails::apply() {
bool edited = m_editableFeed->editItself(new_feed);
if (edited) {
- m_feedsModel->reassignNodeToNewParent(m_editableFeed, new_feed->parent());
+ m_serviceRoot->feedsModel()->reassignNodeToNewParent(m_editableFeed, new_feed->parent());
// Remove new temporary feed data holder object.
delete new_feed;
diff --git a/src/services/standard/gui/formstandardfeeddetails.h b/src/services/standard/gui/formstandardfeeddetails.h
index 6b3ed95a7..d3651f969 100755
--- a/src/services/standard/gui/formstandardfeeddetails.h
+++ b/src/services/standard/gui/formstandardfeeddetails.h
@@ -27,7 +27,7 @@ namespace Ui {
class FormStandardFeedDetails;
}
-class FeedsModel;
+class StandardServiceRoot;
class StandardFeed;
class StandardCategory;
class RootItem;
@@ -37,7 +37,7 @@ class FormStandardFeedDetails : public QDialog {
public:
// Constructors and destructors.
- explicit FormStandardFeedDetails(FeedsModel *model, QWidget *parent = 0);
+ explicit FormStandardFeedDetails(StandardServiceRoot *service_root, QWidget *parent = 0);
virtual ~FormStandardFeedDetails();
public slots:
@@ -84,7 +84,7 @@ class FormStandardFeedDetails : public QDialog {
private:
Ui::FormStandardFeedDetails *m_ui;
StandardFeed *m_editableFeed;
- FeedsModel *m_feedsModel;
+ StandardServiceRoot *m_serviceRoot;
QMenu *m_iconMenu;
QAction *m_actionLoadIconFromFile;
diff --git a/src/services/standard/gui/formstandardimportexport.cpp b/src/services/standard/gui/formstandardimportexport.cpp
index e0c4188b3..d8e4cf418 100755
--- a/src/services/standard/gui/formstandardimportexport.cpp
+++ b/src/services/standard/gui/formstandardimportexport.cpp
@@ -18,6 +18,7 @@
#include "services/standard/gui/formstandardimportexport.h"
#include "services/standard/standardfeedsimportexportmodel.h"
+#include "services/standard/standardserviceroot.h"
#include "core/feedsmodel.h"
#include "miscellaneous/application.h"
#include "gui/feedmessageviewer.h"
@@ -28,8 +29,8 @@
#include
-FormStandardImportExport::FormStandardImportExport(QWidget *parent)
- : QDialog(parent), m_ui(new Ui::FormStandardImportExport) {
+FormStandardImportExport::FormStandardImportExport(StandardServiceRoot *service_root, QWidget *parent)
+ : QDialog(parent), m_ui(new Ui::FormStandardImportExport), m_serviceRoot(service_root) {
m_ui->setupUi(this);
m_model = new FeedsImportExportModel(m_ui->m_treeFeeds);
@@ -54,7 +55,7 @@ void FormStandardImportExport::setMode(const FeedsImportExportModel::Mode &mode)
switch (mode) {
case FeedsImportExportModel::Export: {
- m_model->setRootItem(qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->rootItem());
+ m_model->setRootItem(m_serviceRoot);
m_model->checkAllItems();
m_ui->m_treeFeeds->setModel(m_model);
m_ui->m_treeFeeds->expandAll();
@@ -117,7 +118,6 @@ void FormStandardImportExport::selectExportFile() {
selected_file += QL1S(".opml");
}
}
- // NOTE: Add other types here.
m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(selected_file), tr("File is selected."));
}
@@ -141,7 +141,6 @@ void FormStandardImportExport::selectImportFile() {
if (selected_filter == filter_opml20) {
m_conversionType = OPML20;
}
- // NOTE: Add other types here.
m_ui->m_lblSelectFile->setStatus(WidgetWithStatus::Ok, QDir::toNativeSeparators(selected_file), tr("File is selected."));
parseImportFile(selected_file);
@@ -241,7 +240,8 @@ void FormStandardImportExport::exportFeeds() {
void FormStandardImportExport::importFeeds() {
QString output_message;
- if (qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel()->mergeModel(m_model, output_message)) {
+ if (m_serviceRoot->mergeImportExportModel(m_model, output_message)) {
+ // TODO: Hate this global access, what about signal?
qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->expandAll();
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, output_message, output_message);
}
diff --git a/src/services/standard/gui/formstandardimportexport.h b/src/services/standard/gui/formstandardimportexport.h
index fc1fa85dd..4b36f1ebc 100755
--- a/src/services/standard/gui/formstandardimportexport.h
+++ b/src/services/standard/gui/formstandardimportexport.h
@@ -23,11 +23,12 @@
#include "ui_formstandardimportexport.h"
#include "services/standard/standardfeedsimportexportmodel.h"
-
namespace Ui {
class FormStandardImportExport;
}
+class StandardServiceRoot;
+
class FormStandardImportExport : public QDialog {
Q_OBJECT
@@ -37,7 +38,7 @@ class FormStandardImportExport : public QDialog {
};
// Constructors.
- explicit FormStandardImportExport(QWidget *parent = 0);
+ explicit FormStandardImportExport(StandardServiceRoot *service_root, QWidget *parent = 0);
virtual ~FormStandardImportExport();
void setMode(const FeedsImportExportModel::Mode &mode);
@@ -57,6 +58,7 @@ class FormStandardImportExport : public QDialog {
Ui::FormStandardImportExport *m_ui;
ConversionType m_conversionType;
FeedsImportExportModel *m_model;
+ StandardServiceRoot *m_serviceRoot;
};
#endif // FORMEXPORT_H
diff --git a/src/services/standard/standardcategory.cpp b/src/services/standard/standardcategory.cpp
index 41e46b865..7d822c215 100755
--- a/src/services/standard/standardcategory.cpp
+++ b/src/services/standard/standardcategory.cpp
@@ -34,12 +34,12 @@
#include
-StandardCategory::StandardCategory(RootItem *parent_item) : RootItem(parent_item) {
+StandardCategory::StandardCategory(RootItem *parent_item) : Category(parent_item) {
init();
}
StandardCategory::StandardCategory(const StandardCategory &other)
- : RootItem(NULL) {
+ : Category(NULL) {
m_kind = other.kind();
m_id = other.id();
m_title = other.title();
@@ -55,7 +55,7 @@ StandardCategory::~StandardCategory() {
}
void StandardCategory::init() {
- m_kind = RootItem::Cattegory;
+ m_kind = RootItemKind::Category;
}
QVariant StandardCategory::data(int column, int role) const {
@@ -127,13 +127,16 @@ QVariant StandardCategory::data(int column, int role) const {
}
void StandardCategory::editViaDialog() {
- // TODO: fix passing of the model
+ // TODO: předávat service root.
+/*
QPointer form_pointer = new FormStandardCategoryDetails(qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel(),
qApp->mainForm());
+
form_pointer.data()->exec(this, NULL);
delete form_pointer.data();
+ */
}
bool StandardCategory::removeItself() {
@@ -230,7 +233,7 @@ bool StandardCategory::editItself(StandardCategory *new_category_data) {
return true;
}
-StandardCategory::StandardCategory(const QSqlRecord &record) : RootItem(NULL) {
+StandardCategory::StandardCategory(const QSqlRecord &record) : Category(NULL) {
init();
setId(record.value(CAT_DB_ID_INDEX).toInt());
diff --git a/src/services/standard/standardcategory.h b/src/services/standard/standardcategory.h
index 9affc61b6..b50f2bfaf 100755
--- a/src/services/standard/standardcategory.h
+++ b/src/services/standard/standardcategory.h
@@ -18,7 +18,7 @@
#ifndef FEEDSMODELCATEGORY_H
#define FEEDSMODELCATEGORY_H
-#include "core/rootitem.h"
+#include "services/abstract/category.h"
#include
#include
@@ -29,8 +29,8 @@ class FeedsModel;
// Base class for all categories contained in FeedsModel.
// NOTE: This class should be derived to create PARTICULAR category types.
// NOTE: This class should not be instantiated directly.
-class StandardCategory : public RootItem {
- Q_DECLARE_TR_FUNCTIONS(Category)
+class StandardCategory : public Category {
+ Q_DECLARE_TR_FUNCTIONS(StandardCategory)
public:
// Constructors and destructors
diff --git a/src/services/standard/standardfeed.cpp b/src/services/standard/standardfeed.cpp
index 5d83d2626..6091e2f77 100755
--- a/src/services/standard/standardfeed.cpp
+++ b/src/services/standard/standardfeed.cpp
@@ -53,7 +53,7 @@ void StandardFeed::init() {
m_unreadCount = 0;
m_encoding = QString();
m_url = QString();
- m_kind = RootItem::Feeed;
+ m_kind = RootItemKind::Feed;
}
StandardFeed::StandardFeed(RootItem *parent_item)
@@ -76,7 +76,7 @@ StandardFeed::StandardFeed(const StandardFeed &other)
m_autoUpdateRemainingInterval = other.autoUpdateRemainingInterval();
m_encoding = other.encoding();
m_url = other.url();
- m_kind = RootItem::Feeed;
+ m_kind = RootItemKind::Feed;
m_title = other.title();
m_id = other.id();
m_icon = other.icon();
@@ -100,11 +100,14 @@ int StandardFeed::countOfUnreadMessages() const {
void StandardFeed::editViaDialog() {
// TODO: fix passing of the model
+
+ /*
QPointer form_pointer = new FormStandardFeedDetails(qApp->mainForm()->tabWidget()->feedMessageViewer()->feedsView()->sourceModel(),
qApp->mainForm());
form_pointer.data()->exec(this, NULL);
delete form_pointer.data();
+ */
}
QString StandardFeed::typeToString(StandardFeed::Type type) {
@@ -716,7 +719,7 @@ QNetworkReply::NetworkError StandardFeed::networkError() const {
}
StandardFeed::StandardFeed(const QSqlRecord &record) : Feed(NULL) {
- m_kind = RootItem::Feeed;
+ m_kind = RootItemKind::Feed;
setTitle(record.value(FDS_DB_TITLE_INDEX).toString());
setId(record.value(FDS_DB_ID_INDEX).toInt());
diff --git a/src/services/standard/standardfeedsimportexportmodel.cpp b/src/services/standard/standardfeedsimportexportmodel.cpp
index 96c01a16f..3133be8a3 100755
--- a/src/services/standard/standardfeedsimportexportmodel.cpp
+++ b/src/services/standard/standardfeedsimportexportmodel.cpp
@@ -99,7 +99,7 @@ bool FeedsImportExportModel::exportToOMPL20(QByteArray &result) {
}
switch (child_item->kind()) {
- case RootItem::Cattegory: {
+ case RootItemKind::Category: {
QDomElement outline_category = opml_document.createElement(QSL("outline"));
outline_category.setAttribute(QSL("text"), child_item->title());
outline_category.setAttribute(QSL("description"), child_item->description());
@@ -110,8 +110,8 @@ bool FeedsImportExportModel::exportToOMPL20(QByteArray &result) {
break;
}
- case RootItem::Feeed: {
- StandardFeed *child_feed = child_item->toFeed();
+ case RootItemKind::Feed: {
+ StandardFeed *child_feed = static_cast(child_item);
QDomElement outline_feed = opml_document.createElement("outline");
outline_feed.setAttribute(QSL("text"), child_feed->title());
outline_feed.setAttribute(QSL("xmlUrl"), child_feed->url());
@@ -264,7 +264,7 @@ void FeedsImportExportModel::setMode(const FeedsImportExportModel::Mode &mode) {
void FeedsImportExportModel::checkAllItems() {
foreach (RootItem *root_child, m_rootItem->childItems()) {
- if (root_child->kind() != RootItem::Bin) {
+ if (root_child->kind() != RootItemKind::Bin) {
setData(indexForItem(root_child), Qt::Checked, Qt::CheckStateRole);
}
}
@@ -272,7 +272,7 @@ void FeedsImportExportModel::checkAllItems() {
void FeedsImportExportModel::uncheckAllItems() {
foreach (RootItem *root_child, m_rootItem->childItems()) {
- if (root_child->kind() != RootItem::Bin) {
+ if (root_child->kind() != RootItemKind::Bin) {
setData(indexForItem(root_child), Qt::Unchecked, Qt::CheckStateRole);
}
}
@@ -295,7 +295,7 @@ QModelIndex FeedsImportExportModel::index(int row, int column, const QModelIndex
}
QModelIndex FeedsImportExportModel::indexForItem(RootItem *item) const {
- if (item == NULL || item->kind() == RootItem::Root) {
+ if (item == NULL || item->kind() == RootItemKind::Root) {
// Root item lies on invalid index.
return QModelIndex();
}
@@ -324,7 +324,7 @@ QModelIndex FeedsImportExportModel::indexForItem(RootItem *item) const {
for (int i = 0; i < row_count; i++) {
RootItem *possible_category = active_item->child(i);
- if (possible_category->kind() == RootItem::Cattegory) {
+ if (possible_category->kind() == RootItemKind::Category) {
parents << index(i, 0, active_index);
}
}
@@ -362,7 +362,6 @@ int FeedsImportExportModel::rowCount(const QModelIndex &parent) const {
int FeedsImportExportModel::columnCount(const QModelIndex &parent) const {
Q_UNUSED(parent)
-
return 1;
}
@@ -383,9 +382,9 @@ QVariant FeedsImportExportModel::data(const QModelIndex &index, int role) const
}
else if (role == Qt::DecorationRole) {
switch (item->kind()) {
- case RootItem::Cattegory:
- case RootItem::Bin:
- case RootItem::Feeed:
+ case RootItemKind::Category:
+ case RootItemKind::Bin:
+ case RootItemKind::Feed:
return item->icon();
default:
@@ -394,10 +393,10 @@ QVariant FeedsImportExportModel::data(const QModelIndex &index, int role) const
}
else if (role == Qt::DisplayRole) {
switch (item->kind()) {
- case RootItem::Cattegory:
+ case RootItemKind::Category:
return QVariant(item->data(index.column(), role).toString() + tr(" (category)"));
- case RootItem::Feeed:
+ case RootItemKind::Feed:
return QVariant(item->data(index.column(), role).toString() + tr(" (feed)"));
default:
@@ -462,7 +461,7 @@ bool FeedsImportExportModel::setData(const QModelIndex &index, const QVariant &v
}
Qt::ItemFlags FeedsImportExportModel::flags(const QModelIndex &index) const {
- if (!index.isValid() || itemForIndex(index)->kind() == RootItem::Bin) {
+ if (!index.isValid() || itemForIndex(index)->kind() == RootItemKind::Bin) {
return Qt::NoItemFlags;
}
diff --git a/src/services/standard/standardfeedsimportexportmodel.h b/src/services/standard/standardfeedsimportexportmodel.h
index 972ed5e3c..e5bc8c54f 100755
--- a/src/services/standard/standardfeedsimportexportmodel.h
+++ b/src/services/standard/standardfeedsimportexportmodel.h
@@ -73,7 +73,6 @@ class FeedsImportExportModel : public QAbstractItemModel {
QHash m_checkStates;
RootItem *m_rootItem;
- // When it's true, then
bool m_recursiveChange;
Mode m_mode;
};
diff --git a/src/services/standard/standarditem.cpp b/src/services/standard/standarditem.cpp
new file mode 100755
index 000000000..bde2b13d8
--- /dev/null
+++ b/src/services/standard/standarditem.cpp
@@ -0,0 +1,18 @@
+#include "services/standard/standarditem.h"
+
+#include "services/standard/standardserviceroot.h"
+
+
+StandardItem::StandardItem(StandardServiceRoot *service_root) : m_serviceRoot(service_root) {
+}
+
+StandardItem::~StandardItem() {
+}
+
+StandardServiceRoot *StandardItem::serviceRoot() const {
+ return m_serviceRoot;
+}
+
+void StandardItem::setServiceRoot(StandardServiceRoot *service_root) {
+ m_serviceRoot = service_root;
+}
diff --git a/src/services/standard/standarditem.h b/src/services/standard/standarditem.h
new file mode 100755
index 000000000..efe3210d1
--- /dev/null
+++ b/src/services/standard/standarditem.h
@@ -0,0 +1,19 @@
+#ifndef STANDARDITEM_H
+#define STANDARDITEM_H
+
+
+class StandardServiceRoot;
+
+class StandardItem {
+ public:
+ explicit StandardItem(StandardServiceRoot *service_root);
+ virtual ~StandardItem();
+
+ StandardServiceRoot *serviceRoot() const;
+ void setServiceRoot(StandardServiceRoot *service_root);
+
+ protected:
+ StandardServiceRoot *m_serviceRoot;
+};
+
+#endif // STANDARDITEM_H
diff --git a/src/services/standard/standardrecyclebin.cpp b/src/services/standard/standardrecyclebin.cpp
index fa26177ba..ace8c3ee9 100755
--- a/src/services/standard/standardrecyclebin.cpp
+++ b/src/services/standard/standardrecyclebin.cpp
@@ -25,7 +25,7 @@
StandardRecycleBin::StandardRecycleBin(RootItem *parent)
: RootItem(parent) {
- m_kind = RootItem::Bin;
+ m_kind = RootItemKind::Bin;
m_icon = qApp->icons()->fromTheme(QSL("folder-recycle-bin"));
m_id = ID_RECYCLE_BIN;
m_title = tr("Recycle bin");
diff --git a/src/services/standard/standardserviceentrypoint.cpp b/src/services/standard/standardserviceentrypoint.cpp
index 01f85fda8..de70987d7 100755
--- a/src/services/standard/standardserviceentrypoint.cpp
+++ b/src/services/standard/standardserviceentrypoint.cpp
@@ -69,8 +69,8 @@ QIcon StandardServiceEntryPoint::icon() {
return QIcon(APP_ICON_PATH);
}
-QList StandardServiceEntryPoint::initializeSubtree() {
- StandardServiceRoot *root = new StandardServiceRoot();
+QList StandardServiceEntryPoint::initializeSubtree(FeedsModel *main_model) {
+ StandardServiceRoot *root = new StandardServiceRoot(main_model);
QList roots;
roots.append(root);
diff --git a/src/services/standard/standardserviceentrypoint.h b/src/services/standard/standardserviceentrypoint.h
index 6729922dd..1bf1e1654 100755
--- a/src/services/standard/standardserviceentrypoint.h
+++ b/src/services/standard/standardserviceentrypoint.h
@@ -37,7 +37,7 @@ class StandardServiceEntryPoint : public ServiceEntryPoint {
QString author();
QIcon icon();
- QList initializeSubtree();
+ QList initializeSubtree(FeedsModel *main_model);
};
#endif // STANDARDSERVICEENTRYPOINT_H
diff --git a/src/services/standard/standardserviceroot.cpp b/src/services/standard/standardserviceroot.cpp
index 12592850d..adf773f35 100755
--- a/src/services/standard/standardserviceroot.cpp
+++ b/src/services/standard/standardserviceroot.cpp
@@ -20,17 +20,20 @@
#include "definitions/definitions.h"
#include "miscellaneous/application.h"
#include "miscellaneous/settings.h"
+#include "core/feedsmodel.h"
#include "services/standard/standardserviceentrypoint.h"
#include "services/standard/standardrecyclebin.h"
#include "services/standard/standardfeed.h"
#include "services/standard/standardcategory.h"
+#include "services/standard/standardfeedsimportexportmodel.h"
#include
#include
+#include
-StandardServiceRoot::StandardServiceRoot(RootItem *parent)
- : ServiceRoot(parent), m_recycleBin(new StandardRecycleBin(this)) {
+StandardServiceRoot::StandardServiceRoot(FeedsModel *feeds_model, RootItem *parent)
+ : ServiceRoot(feeds_model, parent), m_recycleBin(new StandardRecycleBin(this)) {
m_title = qApp->system()->getUsername() + "@" + APP_LOW_NAME;
m_icon = StandardServiceEntryPoint().icon();
@@ -113,7 +116,6 @@ QVariant StandardServiceRoot::data(int column, int role) const {
}
void StandardServiceRoot::loadFromDatabase(){
- // TODO: todo
QSqlDatabase database = qApp->database()->connection("StandardServiceRoot", DatabaseFactory::FromSettings);
CategoryAssignment categories;
FeedAssignment feeds;
@@ -175,8 +177,8 @@ void StandardServiceRoot::loadFromDatabase(){
appendChild(m_recycleBin);
}
-QHash StandardServiceRoot::categoriesForItem(RootItem *root) {
- QHash categories;
+QHash StandardServiceRoot::categoriesForItem(RootItem *root) {
+ QHash categories;
QList parents;
parents.append(root->childItems());
@@ -184,11 +186,11 @@ QHash StandardServiceRoot::categoriesForItem(RootItem *r
while (!parents.isEmpty()) {
RootItem *item = parents.takeFirst();
- if (item->kind() == RootItem::Cattegory) {
+ if (item->kind() == RootItemKind::Category) {
// This item is category, add it to the output list and
// scan its children.
int category_id = item->id();
- StandardCategory *category = item->toCategory();
+ StandardCategory *category = static_cast(item);
if (!categories.contains(category_id)) {
categories.insert(category_id, category);
@@ -201,8 +203,12 @@ QHash StandardServiceRoot::categoriesForItem(RootItem *r
return categories;
}
+QHash StandardServiceRoot::allCategories() {
+ return categoriesForItem(this);
+}
+
void StandardServiceRoot::assembleFeeds(FeedAssignment feeds) {
- QHash categories = categoriesForItem(this);
+ QHash categories = categoriesForItem(this);
foreach (const FeedAssignmentItem &feed, feeds) {
if (feed.first == NO_PARENT_CATEGORY) {
@@ -223,6 +229,86 @@ StandardRecycleBin *StandardServiceRoot::recycleBin() const {
return m_recycleBin;
}
+bool StandardServiceRoot::mergeImportExportModel(FeedsImportExportModel *model, QString &output_message) {
+ QStack original_parents; original_parents.push(this);
+ QStack new_parents; new_parents.push(model->rootItem());
+ bool some_feed_category_error = false;
+
+ // Iterate all new items we would like to merge into current model.
+ while (!new_parents.isEmpty()) {
+ RootItem *target_parent = original_parents.pop();
+ RootItem *source_parent = new_parents.pop();
+
+ foreach (RootItem *source_item, source_parent->childItems()) {
+ if (!model->isItemChecked(source_item)) {
+ // We can skip this item, because it is not checked and should not be imported.
+ // NOTE: All descendants are thus skipped too.
+ continue;
+ }
+
+ if (source_item->kind() == RootItemKind::Category) {
+ StandardCategory *source_category = static_cast(source_item);
+ StandardCategory *new_category = new StandardCategory(*source_category);
+ QString new_category_title = new_category->title();
+
+ // Add category to model.
+ new_category->clearChildren();
+
+ if (new_category->addItself(target_parent)) {
+ m_feedsModel->assignNodeToNewParent(new_category, target_parent);
+
+ // Process all children of this category.
+ original_parents.push(new_category);
+ new_parents.push(source_category);
+ }
+ else {
+ delete new_category;
+
+ // Add category failed, but this can mean that the same category (with same title)
+ // already exists. If such a category exists in current parent, then find it and
+ // add descendants to it.
+ RootItem *existing_category = NULL;
+ foreach (RootItem *child, target_parent->childItems()) {
+ if (child->kind() == RootItemKind::Category && child->title() == new_category_title) {
+ existing_category = child;
+ }
+ }
+
+ if (existing_category != NULL) {
+ original_parents.push(existing_category);
+ new_parents.push(source_category);
+ }
+ else {
+ some_feed_category_error = true;
+ }
+ }
+ }
+ else if (source_item->kind() == RootItemKind::Feed) {
+ StandardFeed *source_feed = static_cast(source_item);
+ StandardFeed *new_feed = new StandardFeed(*source_feed);
+
+ // Append this feed and end this iteration.
+ if (!new_feed->addItself(target_parent)) {
+ delete new_feed;
+ some_feed_category_error = true;
+ }
+ }
+ }
+ }
+
+ // Changes are done now. Finalize the new model.
+ //emit layoutChanged();
+
+ if (some_feed_category_error) {
+ output_message = tr("Import successfull, but some feeds/categories were not imported due to error.");
+ }
+ else {
+ output_message = tr("Import was completely successfull.");
+ }
+
+ return !some_feed_category_error;
+}
+
void StandardServiceRoot::assembleCategories(CategoryAssignment categories) {
QHash assignments;
assignments.insert(NO_PARENT_CATEGORY, this);
@@ -235,8 +321,7 @@ void StandardServiceRoot::assembleCategories(CategoryAssignment categories) {
assignments.value(categories.at(i).first)->appendChild(categories.at(i).second);
// Now, added category can be parent for another categories, add it.
- assignments.insert(categories.at(i).second->id(),
- categories.at(i).second);
+ assignments.insert(categories.at(i).second->id(), categories.at(i).second);
// Remove the category from the list, because it was
// added to the final collection.
diff --git a/src/services/standard/standardserviceroot.h b/src/services/standard/standardserviceroot.h
index 5e1013feb..f43d08239 100755
--- a/src/services/standard/standardserviceroot.h
+++ b/src/services/standard/standardserviceroot.h
@@ -26,6 +26,7 @@
class StandardRecycleBin;
class StandardCategory;
class StandardFeed;
+class FeedsImportExportModel;
typedef QList > CategoryAssignment;
typedef QPair CategoryAssignmentItem;
@@ -37,7 +38,7 @@ class StandardServiceRoot : public ServiceRoot {
Q_DECLARE_TR_FUNCTIONS(StandardServiceRoot)
public:
- explicit StandardServiceRoot(RootItem *parent = NULL);
+ explicit StandardServiceRoot(FeedsModel *feeds_model, RootItem *parent = NULL);
virtual ~StandardServiceRoot();
bool canBeEdited();
@@ -46,11 +47,20 @@ class StandardServiceRoot : public ServiceRoot {
// 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 categoriesForItem(RootItem *root);
+ QHash categoriesForItem(RootItem *root);
+
+ // Returns all categories from this root, each pair
+ // consists of ID of parent item and pointer to category.
+ QHash allCategories();
// Access to standard recycle bin.
StandardRecycleBin *recycleBin() const;
+ // Takes structure residing under given root item and adds feeds/categories from
+ // it to active structure.
+ // NOTE: This is used for import/export of the model.
+ bool mergeImportExportModel(FeedsImportExportModel *model, QString &output_message);
+
private:
void loadFromDatabase();
diff --git a/src/services/tt-rss/ttrssserviceentrypoint.cpp b/src/services/tt-rss/ttrssserviceentrypoint.cpp
index 7efd1d1f1..c37c17f2a 100755
--- a/src/services/tt-rss/ttrssserviceentrypoint.cpp
+++ b/src/services/tt-rss/ttrssserviceentrypoint.cpp
@@ -69,6 +69,6 @@ QIcon TtRssServiceEntryPoint::icon() {
return QIcon(APP_ICON_PATH);
}
-QList TtRssServiceEntryPoint::initializeSubtree() {
+QList TtRssServiceEntryPoint::initializeSubtree(FeedsModel *main_model) {
return QList();
}
diff --git a/src/services/tt-rss/ttrssserviceentrypoint.h b/src/services/tt-rss/ttrssserviceentrypoint.h
index 63402ffdd..6447cc567 100755
--- a/src/services/tt-rss/ttrssserviceentrypoint.h
+++ b/src/services/tt-rss/ttrssserviceentrypoint.h
@@ -38,7 +38,7 @@ class TtRssServiceEntryPoint : public ServiceEntryPoint {
QString author();
QIcon icon();
- QList initializeSubtree();
+ QList initializeSubtree(FeedsModel *main_model);
};
#endif // TTRSSSERVICEENTRYPOINT_H
diff --git a/src/services/tt-rss/ttrssserviceroot.cpp b/src/services/tt-rss/ttrssserviceroot.cpp
index e1e52c269..07dd463f8 100755
--- a/src/services/tt-rss/ttrssserviceroot.cpp
+++ b/src/services/tt-rss/ttrssserviceroot.cpp
@@ -20,9 +20,10 @@
#include "miscellaneous/application.h"
#include "miscellaneous/settings.h"
#include "services/tt-rss/ttrssserviceentrypoint.h"
+#include "core/feedsmodel.h"
-TtRssServiceRoot::TtRssServiceRoot(RootItem *parent) : ServiceRoot(parent) {
+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";
diff --git a/src/services/tt-rss/ttrssserviceroot.h b/src/services/tt-rss/ttrssserviceroot.h
index 986c99e21..a747a9773 100755
--- a/src/services/tt-rss/ttrssserviceroot.h
+++ b/src/services/tt-rss/ttrssserviceroot.h
@@ -23,11 +23,13 @@
#include
+class FeedsModel;
+
class TtRssServiceRoot : public ServiceRoot {
Q_DECLARE_TR_FUNCTIONS(StandardServiceRoot)
public:
- explicit TtRssServiceRoot(RootItem *parent = NULL);
+ explicit TtRssServiceRoot(FeedsModel *feeds_model, RootItem *parent = NULL);
virtual ~TtRssServiceRoot();
bool canBeEdited();