FeedReader:

- Added favicon

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6069 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2013-01-10 22:51:04 +00:00
parent edd8a2c0ec
commit 3df3850655
12 changed files with 177 additions and 96 deletions

View File

@ -48,12 +48,13 @@
#define ROLE_FEED_SORT Qt::UserRole + 1
#define ROLE_FEED_FOLDER Qt::UserRole + 2
#define ROLE_FEED_UNREAD Qt::UserRole + 3
#define ROLE_FEED_NAME Qt::UserRole + 4
#define ROLE_FEED_WORKSTATE Qt::UserRole + 5
#define ROLE_FEED_LOADING Qt::UserRole + 6
#define ROLE_FEED_ICON Qt::UserRole + 7
#define ROLE_FEED_ERROR Qt::UserRole + 8
#define ROLE_FEED_DEACTIVATED Qt::UserRole + 9
#define ROLE_FEED_NEW Qt::UserRole + 4
#define ROLE_FEED_NAME Qt::UserRole + 5
#define ROLE_FEED_WORKSTATE Qt::UserRole + 6
#define ROLE_FEED_LOADING Qt::UserRole + 7
#define ROLE_FEED_ICON Qt::UserRole + 8
#define ROLE_FEED_ERROR Qt::UserRole + 9
#define ROLE_FEED_DEACTIVATED Qt::UserRole + 10
FeedReaderDialog::FeedReaderDialog(RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent)
: MainPage(parent), mFeedReader(feedReader), mNotify(notify), ui(new Ui::FeedReaderDialog)
@ -404,22 +405,25 @@ void FeedReaderDialog::updateFeeds(const std::string &parentId, QTreeWidgetItem
calculateFeedItems();
}
void FeedReaderDialog::calculateFeedItem(QTreeWidgetItem *item, uint32_t &unreadCount, bool &loading)
void FeedReaderDialog::calculateFeedItem(QTreeWidgetItem *item, uint32_t &unreadCount, uint32_t &newCount, bool &loading)
{
uint32_t unreadCountItem = 0;
uint32_t newCountItem = 0;
bool loadingItem = false;
if (item->data(COLUMN_FEED_DATA, ROLE_FEED_FOLDER).toBool()) {
int childCount = item->childCount();
for (int index = 0; index < childCount; ++index) {
calculateFeedItem(item->child(index), unreadCountItem, loadingItem);
calculateFeedItem(item->child(index), unreadCountItem, newCountItem, loadingItem);
}
} else {
unreadCountItem = item->data(COLUMN_FEED_DATA, ROLE_FEED_UNREAD).toUInt();
newCountItem = item->data(COLUMN_FEED_DATA, ROLE_FEED_NEW).toUInt();
loadingItem = item->data(COLUMN_FEED_DATA, ROLE_FEED_LOADING).toBool();
}
unreadCount += unreadCountItem;
newCount += newCountItem;
loading = loading || loadingItem;
QString name = item->data(COLUMN_FEED_DATA, ROLE_FEED_NAME).toString();
@ -459,6 +463,8 @@ void FeedReaderDialog::calculateFeedItem(QTreeWidgetItem *item, uint32_t &unread
overlayIcon = QImage(":/images/FeedProcessOverlay.png");
} else if (item->data(COLUMN_FEED_DATA, ROLE_FEED_ERROR).toBool()) {
overlayIcon = QImage(":/images/FeedErrorOverlay.png");
} else if (newCountItem) {
overlayIcon = QImage(":/images/FeedNewOverlay.png");
}
if (!overlayIcon.isNull()) {
if (icon.isNull()) {
@ -478,47 +484,56 @@ void FeedReaderDialog::calculateFeedItem(QTreeWidgetItem *item, uint32_t &unread
void FeedReaderDialog::calculateFeedItems()
{
uint32_t unreadCount = 0;
uint32_t newCount = 0;
bool loading = false;
calculateFeedItem(mRootItem, unreadCount, loading);
calculateFeedItem(mRootItem, unreadCount, newCount, loading);
ui->feedTreeWidget->sortItems(COLUMN_FEED_NAME, Qt::AscendingOrder);
}
void FeedReaderDialog::updateFeedItem(QTreeWidgetItem *item, FeedInfo &info)
QIcon FeedReaderDialog::iconFromFeed(const FeedInfo &feedInfo)
{
QIcon icon;
if (info.flag.folder) {
if (feedInfo.flag.folder) {
/* use folder icon */
icon = QIcon(":/images/Folder.png");
} else {
long todo; // show icon from feed
// if (info.icon.empty()) {
if (feedInfo.icon.empty()) {
/* use standard icon */
icon = QIcon(":/images/Feed.png");
// } else {
// /* use icon from feed */
// icon = QIcon(QPixmap::fromImage(QImage((uchar*) QByteArray::fromBase64(info.icon.c_str()).constData(), 16, 16, QImage::Format_RGB32)));
// }
} else {
/* use icon from feed */
QPixmap pixmap;
if (pixmap.loadFromData(QByteArray::fromBase64(feedInfo.icon.c_str()))) {
icon = pixmap.scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
}
}
}
item->setData(COLUMN_FEED_DATA, ROLE_FEED_ICON, icon);
return icon;
}
QString name = QString::fromUtf8(info.name.c_str());
void FeedReaderDialog::updateFeedItem(QTreeWidgetItem *item, const FeedInfo &feedInfo)
{
item->setData(COLUMN_FEED_DATA, ROLE_FEED_ICON, iconFromFeed(feedInfo));
QString name = QString::fromUtf8(feedInfo.name.c_str());
item->setData(COLUMN_FEED_DATA, ROLE_FEED_NAME, name.isEmpty() ? tr("No name") : name);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_WORKSTATE, FeedReaderStringDefs::workState(info.workstate));
item->setData(COLUMN_FEED_DATA, ROLE_FEED_WORKSTATE, FeedReaderStringDefs::workState(feedInfo.workstate));
uint32_t unreadCount;
mFeedReader->getMessageCount(info.feedId, NULL, NULL, &unreadCount);
uint32_t newCount;
mFeedReader->getMessageCount(feedInfo.feedId, NULL, &newCount, &unreadCount);
item->setData(COLUMN_FEED_NAME, ROLE_FEED_SORT, QString("%1_%2").arg(QString(info.flag.folder ? "0" : "1"), name));
item->setData(COLUMN_FEED_NAME, ROLE_FEED_SORT, QString("%1_%2").arg(QString(feedInfo.flag.folder ? "0" : "1"), name));
item->setData(COLUMN_FEED_DATA, ROLE_FEED_UNREAD, unreadCount);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_LOADING, info.workstate != FeedInfo::WAITING);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_ID, QString::fromStdString(info.feedId));
item->setData(COLUMN_FEED_DATA, ROLE_FEED_FOLDER, info.flag.folder);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_DEACTIVATED, info.flag.deactivated);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_ERROR, (bool) (info.errorState != RS_FEED_ERRORSTATE_OK));
item->setToolTip(COLUMN_FEED_NAME, (info.errorState != RS_FEED_ERRORSTATE_OK) ? FeedReaderStringDefs::errorString(info) : "");
item->setData(COLUMN_FEED_DATA, ROLE_FEED_NEW, newCount);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_LOADING, feedInfo.workstate != FeedInfo::WAITING);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_ID, QString::fromStdString(feedInfo.feedId));
item->setData(COLUMN_FEED_DATA, ROLE_FEED_FOLDER, feedInfo.flag.folder);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_DEACTIVATED, feedInfo.flag.deactivated);
item->setData(COLUMN_FEED_DATA, ROLE_FEED_ERROR, (bool) (feedInfo.errorState != RS_FEED_ERRORSTATE_OK));
item->setToolTip(COLUMN_FEED_NAME, (feedInfo.errorState != RS_FEED_ERRORSTATE_OK) ? FeedReaderStringDefs::errorString(feedInfo) : "");
}
void FeedReaderDialog::feedChanged(const QString &feedId, int type)

View File

@ -45,6 +45,8 @@ public:
virtual UserNotify *getUserNotify(QObject *parent);
static QIcon iconFromFeed(const FeedInfo &feedInfo);
protected:
virtual void showEvent(QShowEvent *event);
bool eventFilter(QObject *obj, QEvent *ev);
@ -76,11 +78,11 @@ private:
void addFeedToExpand(const std::string &feedId);
void getExpandedFeedIds(QList<std::string> &feedIds);
void updateFeeds(const std::string &parentId, QTreeWidgetItem *parentItem);
void updateFeedItem(QTreeWidgetItem *item, FeedInfo &info);
void updateFeedItem(QTreeWidgetItem *item, const FeedInfo &feedInfo);
void openFeedInNewTab(const std::string &feedId);
void calculateFeedItems();
void calculateFeedItem(QTreeWidgetItem *item, uint32_t &unreadCount, bool &loading);
void calculateFeedItem(QTreeWidgetItem *item, uint32_t &unreadCount, uint32_t &newCount, bool &loading);
FeedReaderMessageWidget *feedMessageWidget(const std::string &feedId);
FeedReaderMessageWidget *createMessageWidget(const std::string &feedId);

View File

@ -85,7 +85,7 @@
<item>
<widget class="QToolButton" name="feedAddButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Add new feed</string>
@ -102,7 +102,7 @@
<item>
<widget class="QToolButton" name="feedProcessButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Update feed</string>

View File

@ -53,6 +53,18 @@ FeedReaderFeedItem::FeedReaderFeedItem(RsFeedReader *feedReader, FeedReaderNotif
mFeedId = feedInfo.feedId;
mMsgId = msgInfo.msgId;
if (feedInfo.icon.empty()) {
ui->feedIconLabel->hide();
} else {
/* use icon from feed */
QPixmap pixmap;
if (pixmap.loadFromData(QByteArray::fromBase64(feedInfo.icon.c_str()))) {
ui->feedIconLabel->setPixmap(pixmap.scaled(16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
} else {
ui->feedIconLabel->hide();
}
}
ui->titleLabel->setText(QString::fromUtf8(feedInfo.name.c_str()));
ui->msgTitleLabel->setText(QString::fromUtf8(msgInfo.title.c_str()));
ui->descriptionLabel->setText(QString::fromUtf8(msgInfo.description.c_str()));

View File

@ -50,29 +50,47 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="logoLabel">
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="pixmap">
<pixmap resource="FeedReader_images.qrc">:/images/FeedReader.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
<widget class="QLabel" name="logoLabel">
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="pixmap">
<pixmap resource="FeedReader_images.qrc">:/images/FeedReader.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="feedIconLabel">
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="pixmap">
<pixmap resource="FeedReader_images.qrc">:/images/Feed.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
@ -258,6 +276,12 @@ p, li { white-space: pre-wrap; }
</property>
<item>
<widget class="QFrame" name="msgFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>

View File

@ -4,17 +4,18 @@
#include <QClipboard>
#include <QDesktopServices>
#include <QTimer>
#include <QPainter>
#include "FeedReaderMessageWidget.h"
#include "ui_FeedReaderMessageWidget.h"
#include "FeedReaderNotify.h"
#include "FeedReaderConfig.h"
#include "FeedReaderDialog.h"
#include "gui/common/RSTreeWidgetItem.h"
#include "gui/settings/rsharesettings.h"
#include "util/HandleRichText.h"
#include "interface/rsFeedReader.h"
#include "retroshare/rsiface.h"
#define COLUMN_MSG_COUNT 4
@ -37,6 +38,7 @@ FeedReaderMessageWidget::FeedReaderMessageWidget(const std::string &feedId, RsFe
mProcessSettings = false;
mUnreadCount = 0;
mNewCount = 0;
/* connect signals */
connect(mNotify, SIGNAL(feedChanged(QString,int)), this, SLOT(feedChanged(QString,int)));
@ -60,10 +62,10 @@ FeedReaderMessageWidget::FeedReaderMessageWidget(const std::string &feedId, RsFe
connect(ui->feedProcessButton, SIGNAL(clicked()), this, SLOT(processFeed()));
// create timer for navigation
timer = new QTimer(this);
timer->setInterval(300);
timer->setSingleShot(true);
connect(timer, SIGNAL(timeout()), this, SLOT(updateCurrentMessage()));
mTimer = new QTimer(this);
mTimer->setInterval(300);
mTimer->setSingleShot(true);
connect(mTimer, SIGNAL(timeout()), this, SLOT(updateCurrentMessage()));
mMsgCompareRole = new RSTreeWidgetItemCompareRole;
mMsgCompareRole->setRole(COLUMN_MSG_TITLE, ROLE_MSG_SORT);
@ -118,8 +120,8 @@ FeedReaderMessageWidget::FeedReaderMessageWidget(const std::string &feedId, RsFe
FeedReaderMessageWidget::~FeedReaderMessageWidget()
{
// stop and delete timer
timer->stop();
delete(timer);
mTimer->stop();
delete(mTimer);
/* save settings */
processSettings(false);
@ -207,16 +209,14 @@ void FeedReaderMessageWidget::setFeedId(const std::string &feedId)
ui->feedProcessButton->setEnabled(!mFeedId.empty());
if (!mFeedId.empty()) {
FeedInfo feedInfo;
if (mFeedReader->getFeedInfo(mFeedId, feedInfo)) {
mFeedName = QString::fromUtf8(feedInfo.name.c_str());
mFeedReader->getMessageCount(mFeedId, NULL, NULL, &mUnreadCount);
if (mFeedReader->getFeedInfo(mFeedId, mFeedInfo)) {
mFeedReader->getMessageCount(mFeedId, NULL, &mNewCount, &mUnreadCount);
} else {
mFeedId.clear();
mFeedInfo = FeedInfo();
}
} else {
mFeedName.clear();
mFeedInfo = FeedInfo();
}
ui->msgReadAllButton->setEnabled(!mFeedId.empty());
@ -229,7 +229,7 @@ void FeedReaderMessageWidget::setFeedId(const std::string &feedId)
QString FeedReaderMessageWidget::feedName(bool withUnreadCount)
{
QString name = mFeedName.isEmpty() ? tr("No name") : mFeedName;
QString name = mFeedInfo.name.empty() ? tr("No name") : QString::fromUtf8(mFeedInfo.name.c_str());
if (withUnreadCount && mUnreadCount) {
name += QString(" (%1)").arg(mUnreadCount);
@ -240,15 +240,38 @@ QString FeedReaderMessageWidget::feedName(bool withUnreadCount)
QIcon FeedReaderMessageWidget::feedIcon()
{
// if (mThreadQueue->activeRequestExist(TOKEN_TYPE_CURRENTFORUM) || mFillThread) {
// return QIcon(":/images/kalarm.png");
// }
QIcon icon = FeedReaderDialog::iconFromFeed(mFeedInfo);
// if (mNewCount) {
// return QIcon(":/images/message-state-new.png");
// }
if (mFeedInfo.flag.deactivated) {
/* create disabled icon */
icon = icon.pixmap(QSize(16, 16), QIcon::Disabled);
}
return QIcon();
if (!mFeedId.empty()) {
QImage overlayIcon;
if (mFeedInfo.workstate != FeedInfo::WAITING) {
/* overlaying icon */
overlayIcon = QImage(":/images/FeedProcessOverlay.png");
} else if (mFeedInfo.errorState != RS_FEED_ERRORSTATE_OK) {
overlayIcon = QImage(":/images/FeedErrorOverlay.png");
} else if (mNewCount) {
overlayIcon = QImage(":/images/FeedNewOverlay.png");
}
if (!overlayIcon.isNull()) {
if (icon.isNull()) {
icon = QPixmap::fromImage(overlayIcon);
} else {
QPixmap pixmap = icon.pixmap(QSize(16, 16));
QPainter painter(&pixmap);
painter.drawImage(0, 0, overlayIcon.scaled(pixmap.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
painter.end();
icon = pixmap;
}
}
}
return icon;
}
std::string FeedReaderMessageWidget::currentMsgId()
@ -415,16 +438,12 @@ void FeedReaderMessageWidget::feedChanged(const QString &feedId, int type)
}
if (type == NOTIFY_TYPE_MOD) {
FeedInfo feedInfo;
if (!mFeedReader->getFeedInfo(mFeedId, feedInfo)) {
if (!mFeedReader->getFeedInfo(mFeedId, mFeedInfo)) {
setFeedId("");
return;
}
QString name = QString::fromUtf8(feedInfo.name.c_str());
if (name != mFeedName) {
mFeedName = name;
emit feedMessageChanged(this);
}
emit feedMessageChanged(this);
}
}
@ -439,9 +458,11 @@ void FeedReaderMessageWidget::msgChanged(const QString &feedId, const QString &m
}
uint32_t unreadCount;
mFeedReader->getMessageCount(mFeedId, NULL, NULL, &unreadCount);
if (unreadCount != mUnreadCount) {
uint32_t newCount;
mFeedReader->getMessageCount(mFeedId, NULL, &newCount, &unreadCount);
if (unreadCount != mUnreadCount || newCount || mNewCount) {
mUnreadCount = unreadCount;
mNewCount = newCount;
emit feedMessageChanged(this);
}
@ -502,13 +523,13 @@ void FeedReaderMessageWidget::msgItemClicked(QTreeWidgetItem *item, int column)
void FeedReaderMessageWidget::msgItemChanged()
{
timer->stop();
timer->start();
mTimer->stop();
mTimer->start();
}
void FeedReaderMessageWidget::updateCurrentMessage()
{
timer->stop();
mTimer->stop();
long todo; // show link somewhere

View File

@ -3,6 +3,8 @@
#include <QWidget>
#include "interface/rsFeedReader.h"
namespace Ui {
class FeedReaderMessageWidget;
}
@ -17,7 +19,7 @@ class FeedReaderNotify;
class FeedReaderMessageWidget : public QWidget
{
Q_OBJECT
public:
explicit FeedReaderMessageWidget(const std::string &feedId, RsFeedReader *feedReader, FeedReaderNotify *notify, QWidget *parent = 0);
~FeedReaderMessageWidget();
@ -69,9 +71,10 @@ private:
bool mProcessSettings;
RSTreeWidgetItemCompareRole *mMsgCompareRole;
std::string mFeedId;
QString mFeedName;
unsigned int mUnreadCount;
QTimer *timer;
unsigned int mNewCount;
QTimer *mTimer;
FeedInfo mFeedInfo;
// gui interface
RsFeedReader *mFeedReader;

View File

@ -42,7 +42,7 @@
<item>
<widget class="QToolButton" name="msgReadButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Mark messages as read</string>
@ -62,7 +62,7 @@
<item>
<widget class="QToolButton" name="msgUnreadButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Mark messages as unread</string>
@ -79,7 +79,7 @@
<item>
<widget class="QToolButton" name="msgReadAllButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Mark all messages as read</string>
@ -96,7 +96,7 @@
<item>
<widget class="QToolButton" name="msgRemoveButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Remove messages</string>
@ -113,7 +113,7 @@
<item>
<widget class="QToolButton" name="feedProcessButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Update feed</string>
@ -203,7 +203,7 @@
<item>
<widget class="QToolButton" name="linkButton">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="FeedReader_images.qrc">

View File

@ -10,6 +10,7 @@
<file>images/FeedMsgUnread.png</file>
<file>images/FeedProcess.png</file>
<file>images/FeedProcessOverlay.png</file>
<file>images/FeedNewOverlay.png</file>
<file>images/FeedErrorOverlay.png</file>
<file>images/FolderAdd.png</file>
<file>images/FeedAdd.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

View File

@ -906,7 +906,7 @@ RsFeedReaderErrorState p3FeedReaderThread::process(const RsFeedReaderFeed &feed,
}
if (feedFormat == FORMAT_ATOM) {
/* <author><name>... */
/* <author><name>...</name></author> */
xmlNodePtr author = xml.findNode(node->children, "author", false);
if (author) {
xml.getChildText(node, "name", item->author);
@ -920,7 +920,11 @@ RsFeedReaderErrorState p3FeedReaderThread::process(const RsFeedReaderFeed &feed,
switch (feedFormat) {
case FORMAT_RSS:
case FORMAT_RDF:
xml.getChildText(node, "description", item->description);
/* try content:encoded */
if (!xml.getChildText(node, "encoded", item->description)) {
/* use description */
xml.getChildText(node, "description", item->description);
}
break;
case FORMAT_ATOM:
/* try content */

View File

@ -213,7 +213,6 @@ void NewsFeed::updateFeed()
}
}
}
}
}