fix #344, polish docs a bit
This commit is contained in:
parent
c25daeac29
commit
a567674634
8 changed files with 84 additions and 29 deletions
|
@ -30,7 +30,7 @@
|
||||||
<url type="donation">https://martinrotter.github.io/donate/</url>
|
<url type="donation">https://martinrotter.github.io/donate/</url>
|
||||||
<content_rating type="oars-1.1" />
|
<content_rating type="oars-1.1" />
|
||||||
<releases>
|
<releases>
|
||||||
<release version="3.9.0" date="2021-04-19"/>
|
<release version="3.9.0" date="2021-04-20"/>
|
||||||
</releases>
|
</releases>
|
||||||
<content_rating type="oars-1.0">
|
<content_rating type="oars-1.0">
|
||||||
<content_attribute id="violence-cartoon">none</content_attribute>
|
<content_attribute id="violence-cartoon">none</content_attribute>
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
* [RSS Guard 3 vs. RSS Guard 4](#rss-guard-3-vs-rss-guard-4)
|
* [RSS Guard 3 vs. RSS Guard 4](#rss-guard-3-vs-rss-guard-4)
|
||||||
* [Features](#features)
|
* [Features](#features)
|
||||||
* [List of main features](#list-of-main-features)
|
* [List of main features](#list-of-main-features)
|
||||||
|
* [Core concepts](#core-concepts)
|
||||||
* [Supported feed formats and online feed services](Feed-formats.md)
|
* [Supported feed formats and online feed services](Feed-formats.md)
|
||||||
* [Message filtering](Message-filters.md)
|
* [Message filtering](Message-filters.md)
|
||||||
* [Database backends](#database-backends)
|
* [Database backends](#database-backends)
|
||||||
|
@ -120,8 +121,7 @@ RSS Guard is simple (yet powerful) feed reader. It is able to fetch the most kno
|
||||||
* support for all feed formats (RSS/RDF/ATOM/JSON),
|
* support for all feed formats (RSS/RDF/ATOM/JSON),
|
||||||
* full support of podcasts (RSS/ATOM/JSON),
|
* full support of podcasts (RSS/ATOM/JSON),
|
||||||
* import/export of feeds to/from OPML 2.0,
|
* import/export of feeds to/from OPML 2.0,
|
||||||
* universal plugin for online services with [Google Reader API](#google-reader-api),
|
* possibility of using custom 3rd-party feed [synchronization services](Feed-formats.md),
|
||||||
* possibility of using custom 3rd-party feed synchronization services,
|
|
||||||
* feed metadata fetching including icons,
|
* feed metadata fetching including icons,
|
||||||
* support for [scraping websites](#websites-scraping) which do not offer RSS/ATOM feeds and other related advanced features,
|
* support for [scraping websites](#websites-scraping) which do not offer RSS/ATOM feeds and other related advanced features,
|
||||||
* simple internal Chromium-based web viewer (or alternative version with simpler and much more lightweight internal viewer),
|
* simple internal Chromium-based web viewer (or alternative version with simpler and much more lightweight internal viewer),
|
||||||
|
@ -144,7 +144,6 @@ RSS Guard is simple (yet powerful) feed reader. It is able to fetch the most kno
|
||||||
* support for `feed://` URI scheme.
|
* support for `feed://` URI scheme.
|
||||||
* user interface:
|
* user interface:
|
||||||
* message list filter with regular expressions,
|
* message list filter with regular expressions,
|
||||||
* drag-n-drop for feed list,
|
|
||||||
* able to show unread feeds/messages only,
|
* able to show unread feeds/messages only,
|
||||||
* can be controlled via keyboard,
|
* can be controlled via keyboard,
|
||||||
* fully adjustable toolbars (changeable buttons and style),
|
* fully adjustable toolbars (changeable buttons and style),
|
||||||
|
@ -155,9 +154,18 @@ RSS Guard is simple (yet powerful) feed reader. It is able to fetch the most kno
|
||||||
* tabbed interface,
|
* tabbed interface,
|
||||||
* ability to hide list of feeds/categories,
|
* ability to hide list of feeds/categories,
|
||||||
* desktop integration via tray icon,
|
* desktop integration via tray icon,
|
||||||
* localizations to some languages,
|
* localizations to many languages,
|
||||||
* ability to tweak columns in displayed list of messages.
|
* ability to tweak columns in displayed list of messages.
|
||||||
|
|
||||||
|
## Core concepts
|
||||||
|
RSS Guard is multi-protocol and multi-account application. If you start it for the first time, `Add account` dialog will pop-up.
|
||||||
|
|
||||||
|
<img src="images/add-acc.png">
|
||||||
|
|
||||||
|
You can also display this dialog from main menu `Accounts -> Add new account`.
|
||||||
|
|
||||||
|
You must have added some account to start using RSS Guard. Each account provides access to some specific online service while `Standard online feeds` account is there to provide access to classic `RSS` and `ATOM` feeds. You can have activated many accounts in the same time and even multiple accounts of the same type, for example two distinct `Gmail` accounts.
|
||||||
|
|
||||||
## Database backends
|
## Database backends
|
||||||
RSS Guard offers switchable database backends which hold your data. At this point, two backends are available:
|
RSS Guard offers switchable database backends which hold your data. At this point, two backends are available:
|
||||||
* MariaDB,
|
* MariaDB,
|
||||||
|
@ -187,7 +195,6 @@ Note that even when all Google Reader API enabled services should follow the API
|
||||||
For example The Old Reader does not seem to offer tags/labels functionality, therefore tags/labels in RSS Guard are not synchronized, but you can still use offline labels.
|
For example The Old Reader does not seem to offer tags/labels functionality, therefore tags/labels in RSS Guard are not synchronized, but you can still use offline labels.
|
||||||
|
|
||||||
## Websites scraping
|
## Websites scraping
|
||||||
|
|
||||||
> **Only proceed if you consider yourself to be a power user and you know what you are doing!**
|
> **Only proceed if you consider yourself to be a power user and you know what you are doing!**
|
||||||
|
|
||||||
RSS Guard 3.9.0+ offers extra advanced features which are inspired by [Liferea](https://lzone.de/liferea/).
|
RSS Guard 3.9.0+ offers extra advanced features which are inspired by [Liferea](https://lzone.de/liferea/).
|
||||||
|
|
|
@ -12,7 +12,7 @@ Official downloads are available [here](https://github.com/martinrotter/rssguard
|
||||||
Development builds can be downloaded [here](https://github.com/martinrotter/rssguard/releases/tag/devbuild).
|
Development builds can be downloaded [here](https://github.com/martinrotter/rssguard/releases/tag/devbuild).
|
||||||
|
|
||||||
## Installation packages naming
|
## Installation packages naming
|
||||||
**Windows builds** of RSS Guard are generated automatically by the tool called AppVeyor. These builds have auto-generated names. In RSS Guard [downloads page](https://github.com/martinrotter/rssguard/releases) you can see filenames like:
|
**All builds** of RSS Guard are generated automatically by GitHub. These builds have auto-generated names. In RSS Guard [downloads page](https://github.com/martinrotter/rssguard/releases) you can see filenames like:
|
||||||
* `rssguard-3.4.2-7bad9d1-nowebengine-win32.7z`,
|
* `rssguard-3.4.2-7bad9d1-nowebengine-win32.7z`,
|
||||||
* `rssguard-3.4.2-7bad9d1-win32.7z`,
|
* `rssguard-3.4.2-7bad9d1-win32.7z`,
|
||||||
* `rssguard-3.4.2-95ee6be-nowebengine-win32.exe`,
|
* `rssguard-3.4.2-95ee6be-nowebengine-win32.exe`,
|
||||||
|
@ -26,3 +26,5 @@ The structure of these filenames is quite trivial and easily understandable for
|
||||||
* `<fileformat>` = `exe` (This is self-explanatory.).
|
* `<fileformat>` = `exe` (This is self-explanatory.).
|
||||||
|
|
||||||
Note that same file naming scheme for development builds might be little different. Specifically, `<version>` field is omitted.
|
Note that same file naming scheme for development builds might be little different. Specifically, `<version>` field is omitted.
|
||||||
|
|
||||||
|
If you use `7z` packages on Windows, then you need to manually install all needed MSVC++ runtime libraries. Their installers are included inside the archive.
|
BIN
resources/docs/images/add-acc.png
Executable file
BIN
resources/docs/images/add-acc.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
|
@ -190,6 +190,7 @@ QList<QAction*> FormMain::allActions() const {
|
||||||
actions << m_ui->m_actionSelectPreviousMessage;
|
actions << m_ui->m_actionSelectPreviousMessage;
|
||||||
actions << m_ui->m_actionSelectNextUnreadMessage;
|
actions << m_ui->m_actionSelectNextUnreadMessage;
|
||||||
actions << m_ui->m_actionExpandCollapseItem;
|
actions << m_ui->m_actionExpandCollapseItem;
|
||||||
|
actions << m_ui->m_actionExpandCollapseItemRecursively;
|
||||||
actions << m_ui->m_actionMessageFilters;
|
actions << m_ui->m_actionMessageFilters;
|
||||||
|
|
||||||
#if defined(USE_WEBENGINE)
|
#if defined(USE_WEBENGINE)
|
||||||
|
@ -448,7 +449,8 @@ void FormMain::updateFeedButtonsAvailability() {
|
||||||
m_ui->m_actionUpdateSelectedItemsWithCustomTimers->setEnabled(!critical_action_running);
|
m_ui->m_actionUpdateSelectedItemsWithCustomTimers->setEnabled(!critical_action_running);
|
||||||
m_ui->m_actionUpdateSelectedItems->setEnabled(!critical_action_running && (feed_selected || category_selected || service_selected));
|
m_ui->m_actionUpdateSelectedItems->setEnabled(!critical_action_running && (feed_selected || category_selected || service_selected));
|
||||||
m_ui->m_actionViewSelectedItemsNewspaperMode->setEnabled(anything_selected);
|
m_ui->m_actionViewSelectedItemsNewspaperMode->setEnabled(anything_selected);
|
||||||
m_ui->m_actionExpandCollapseItem->setEnabled(anything_selected);
|
m_ui->m_actionExpandCollapseItem->setEnabled(category_selected || service_selected);
|
||||||
|
m_ui->m_actionExpandCollapseItemRecursively->setEnabled(category_selected || service_selected);
|
||||||
m_ui->m_actionServiceDelete->setEnabled(service_selected);
|
m_ui->m_actionServiceDelete->setEnabled(service_selected);
|
||||||
m_ui->m_actionServiceEdit->setEnabled(service_selected);
|
m_ui->m_actionServiceEdit->setEnabled(service_selected);
|
||||||
m_ui->m_actionAddFeedIntoSelectedItem->setEnabled(anything_selected);
|
m_ui->m_actionAddFeedIntoSelectedItem->setEnabled(anything_selected);
|
||||||
|
@ -545,6 +547,7 @@ void FormMain::setupIcons() {
|
||||||
m_ui->m_actionShowOnlyUnreadItems->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-unread")));
|
m_ui->m_actionShowOnlyUnreadItems->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-unread")));
|
||||||
m_ui->m_actionShowOnlyUnreadMessages->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-unread")));
|
m_ui->m_actionShowOnlyUnreadMessages->setIcon(icon_theme_factory->fromTheme(QSL("mail-mark-unread")));
|
||||||
m_ui->m_actionExpandCollapseItem->setIcon(icon_theme_factory->fromTheme(QSL("format-indent-more")));
|
m_ui->m_actionExpandCollapseItem->setIcon(icon_theme_factory->fromTheme(QSL("format-indent-more")));
|
||||||
|
m_ui->m_actionExpandCollapseItemRecursively->setIcon(icon_theme_factory->fromTheme(QSL("format-indent-more")));
|
||||||
m_ui->m_actionRestoreSelectedMessages->setIcon(icon_theme_factory->fromTheme(QSL("view-refresh")));
|
m_ui->m_actionRestoreSelectedMessages->setIcon(icon_theme_factory->fromTheme(QSL("view-refresh")));
|
||||||
m_ui->m_actionRestoreAllRecycleBins->setIcon(icon_theme_factory->fromTheme(QSL("view-refresh")));
|
m_ui->m_actionRestoreAllRecycleBins->setIcon(icon_theme_factory->fromTheme(QSL("view-refresh")));
|
||||||
m_ui->m_actionEmptyAllRecycleBins->setIcon(icon_theme_factory->fromTheme(QSL("edit-clear")));
|
m_ui->m_actionEmptyAllRecycleBins->setIcon(icon_theme_factory->fromTheme(QSL("edit-clear")));
|
||||||
|
@ -741,7 +744,17 @@ void FormMain::createConnections() {
|
||||||
connect(m_ui->m_actionMarkSelectedItemsAsRead,
|
connect(m_ui->m_actionMarkSelectedItemsAsRead,
|
||||||
&QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::markSelectedItemRead);
|
&QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::markSelectedItemRead);
|
||||||
connect(m_ui->m_actionExpandCollapseItem,
|
connect(m_ui->m_actionExpandCollapseItem,
|
||||||
&QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::expandCollapseCurrentItem);
|
&QAction::triggered,
|
||||||
|
tabWidget()->feedMessageViewer()->feedsView(),
|
||||||
|
[this]() {
|
||||||
|
tabWidget()->feedMessageViewer()->feedsView()->expandCollapseCurrentItem(false);
|
||||||
|
});
|
||||||
|
connect(m_ui->m_actionExpandCollapseItemRecursively,
|
||||||
|
&QAction::triggered,
|
||||||
|
tabWidget()->feedMessageViewer()->feedsView(),
|
||||||
|
[this]() {
|
||||||
|
tabWidget()->feedMessageViewer()->feedsView()->expandCollapseCurrentItem(true);
|
||||||
|
});
|
||||||
connect(m_ui->m_actionMarkSelectedItemsAsUnread,
|
connect(m_ui->m_actionMarkSelectedItemsAsUnread,
|
||||||
&QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::markSelectedItemUnread);
|
&QAction::triggered, tabWidget()->feedMessageViewer()->feedsView(), &FeedsView::markSelectedItemUnread);
|
||||||
connect(m_ui->m_actionClearSelectedItems,
|
connect(m_ui->m_actionClearSelectedItems,
|
||||||
|
|
|
@ -120,6 +120,7 @@
|
||||||
<addaction name="m_actionAutoExpandItemsWhenSelected"/>
|
<addaction name="m_actionAutoExpandItemsWhenSelected"/>
|
||||||
<addaction name="m_actionShowTreeBranches"/>
|
<addaction name="m_actionShowTreeBranches"/>
|
||||||
<addaction name="m_actionExpandCollapseItem"/>
|
<addaction name="m_actionExpandCollapseItem"/>
|
||||||
|
<addaction name="m_actionExpandCollapseItemRecursively"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="m_actionSelectNextItem"/>
|
<addaction name="m_actionSelectNextItem"/>
|
||||||
<addaction name="m_actionSelectPreviousItem"/>
|
<addaction name="m_actionSelectPreviousItem"/>
|
||||||
|
@ -805,6 +806,11 @@
|
||||||
<string>Message viewer toolbars</string>
|
<string>Message viewer toolbars</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="m_actionExpandCollapseItemRecursively">
|
||||||
|
<property name="text">
|
||||||
|
<string>Expand/collapse selected item &recursively</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
@ -191,7 +191,7 @@ void FeedsView::addCategoryIntoSelectedAccount() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsView::expandCollapseCurrentItem() {
|
void FeedsView::expandCollapseCurrentItem(bool recursive) {
|
||||||
if (selectionModel()->selectedRows().size() == 1) {
|
if (selectionModel()->selectedRows().size() == 1) {
|
||||||
QModelIndex index = selectionModel()->selectedRows().at(0);
|
QModelIndex index = selectionModel()->selectedRows().at(0);
|
||||||
|
|
||||||
|
@ -200,8 +200,33 @@ void FeedsView::expandCollapseCurrentItem() {
|
||||||
index = index.parent();
|
index = index.parent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (recursive) {
|
||||||
|
QList<QModelIndex> to_process = { index };
|
||||||
|
bool expa = !isExpanded(index);
|
||||||
|
|
||||||
|
while (!to_process.isEmpty()) {
|
||||||
|
auto idx = to_process.takeFirst();
|
||||||
|
|
||||||
|
if (idx.isValid()) {
|
||||||
|
setExpanded(idx, expa);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_proxyModel->rowCount(idx); i++) {
|
||||||
|
auto new_idx = m_proxyModel->index(i, 0, idx);
|
||||||
|
|
||||||
|
if (new_idx.isValid()) {
|
||||||
|
to_process << new_idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
isExpanded(index) ? collapse(index) : expand(index);
|
isExpanded(index) ? collapse(index) : expand(index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FeedsView::updateSelectedItems() {
|
void FeedsView::updateSelectedItems() {
|
||||||
|
@ -460,14 +485,15 @@ QMenu* FeedsView::initializeContextMenuService(RootItem* clicked_item) {
|
||||||
|
|
||||||
QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList();
|
QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList();
|
||||||
|
|
||||||
m_contextMenuService->addActions(QList<QAction*>() <<
|
m_contextMenuService->addActions({ qApp->mainForm()->m_ui->m_actionUpdateSelectedItems,
|
||||||
qApp->mainForm()->m_ui->m_actionUpdateSelectedItems <<
|
qApp->mainForm()->m_ui->m_actionEditSelectedItem,
|
||||||
qApp->mainForm()->m_ui->m_actionEditSelectedItem <<
|
qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed,
|
||||||
qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed <<
|
qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode,
|
||||||
qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode <<
|
qApp->mainForm()->m_ui->m_actionExpandCollapseItem,
|
||||||
qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead <<
|
qApp->mainForm()->m_ui->m_actionExpandCollapseItemRecursively,
|
||||||
qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread <<
|
qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead,
|
||||||
qApp->mainForm()->m_ui->m_actionDeleteSelectedItem);
|
qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread,
|
||||||
|
qApp->mainForm()->m_ui->m_actionDeleteSelectedItem });
|
||||||
|
|
||||||
auto cat_add = clicked_item->getParentServiceRoot()->supportsCategoryAdding();
|
auto cat_add = clicked_item->getParentServiceRoot()->supportsCategoryAdding();
|
||||||
auto feed_add = clicked_item->getParentServiceRoot()->supportsFeedAdding();
|
auto feed_add = clicked_item->getParentServiceRoot()->supportsFeedAdding();
|
||||||
|
@ -545,14 +571,15 @@ QMenu* FeedsView::initializeContextMenuCategories(RootItem* clicked_item) {
|
||||||
|
|
||||||
QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList();
|
QList<QAction*> specific_actions = clicked_item->contextMenuFeedsList();
|
||||||
|
|
||||||
m_contextMenuCategories->addActions(QList<QAction*>() <<
|
m_contextMenuCategories->addActions({ qApp->mainForm()->m_ui->m_actionUpdateSelectedItems,
|
||||||
qApp->mainForm()->m_ui->m_actionUpdateSelectedItems <<
|
qApp->mainForm()->m_ui->m_actionEditSelectedItem,
|
||||||
qApp->mainForm()->m_ui->m_actionEditSelectedItem <<
|
qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed,
|
||||||
qApp->mainForm()->m_ui->m_actionCopyUrlSelectedFeed <<
|
qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode,
|
||||||
qApp->mainForm()->m_ui->m_actionViewSelectedItemsNewspaperMode <<
|
qApp->mainForm()->m_ui->m_actionExpandCollapseItem,
|
||||||
qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead <<
|
qApp->mainForm()->m_ui->m_actionExpandCollapseItemRecursively,
|
||||||
qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread <<
|
qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsRead,
|
||||||
qApp->mainForm()->m_ui->m_actionDeleteSelectedItem);
|
qApp->mainForm()->m_ui->m_actionMarkSelectedItemsAsUnread,
|
||||||
|
qApp->mainForm()->m_ui->m_actionDeleteSelectedItem });
|
||||||
|
|
||||||
auto cat_add = clicked_item->getParentServiceRoot()->supportsCategoryAdding();
|
auto cat_add = clicked_item->getParentServiceRoot()->supportsCategoryAdding();
|
||||||
auto feed_add = clicked_item->getParentServiceRoot()->supportsFeedAdding();
|
auto feed_add = clicked_item->getParentServiceRoot()->supportsFeedAdding();
|
||||||
|
|
|
@ -45,7 +45,7 @@ class RSSGUARD_DLLSPEC FeedsView : public QTreeView {
|
||||||
|
|
||||||
void addFeedIntoSelectedAccount();
|
void addFeedIntoSelectedAccount();
|
||||||
void addCategoryIntoSelectedAccount();
|
void addCategoryIntoSelectedAccount();
|
||||||
void expandCollapseCurrentItem();
|
void expandCollapseCurrentItem(bool recursive);
|
||||||
|
|
||||||
// Feed updating.
|
// Feed updating.
|
||||||
void updateSelectedItems();
|
void updateSelectedItems();
|
||||||
|
|
Loading…
Add table
Reference in a new issue