2018-11-04 09:48:33 -05:00
/*******************************************************************************
* plugins / FeedReader / gui / FeedReaderDialog . cpp *
* *
* Copyright ( C ) 2012 by Thunder *
* *
* This program is free software : you can redistribute it and / or modify *
* it under the terms of the GNU Affero General Public License as *
* published by the Free Software Foundation , either version 3 of the *
* License , or ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU Affero General Public License for more details . *
* *
* You should have received a copy of the GNU Affero General Public License *
* along with this program . If not , see < https : //www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-08-02 09:17:53 -04:00
2012-08-03 21:15:40 -04:00
# include <QKeyEvent>
2012-08-02 09:17:53 -04:00
# include <QMenu>
# include <QInputDialog>
# include <QPainter>
# include <QMessageBox>
# include "FeedReaderDialog.h"
2012-12-25 18:53:55 -05:00
# include "FeedReaderMessageWidget.h"
2012-08-02 09:17:53 -04:00
# include "ui_FeedReaderDialog.h"
# include "FeedReaderNotify.h"
2013-01-05 21:30:10 -05:00
# include "FeedReaderConfig.h"
2012-08-02 09:17:53 -04:00
# include "AddFeedDialog.h"
2012-08-13 17:35:11 -04:00
# include "FeedReaderStringDefs.h"
2012-08-02 09:17:53 -04:00
# include "gui/common/RSTreeWidgetItem.h"
# include "gui/settings/rsharesettings.h"
2013-01-05 21:30:10 -05:00
# include "gui/notifyqt.h"
2012-12-20 08:30:16 -05:00
# include "FeedReaderUserNotify.h"
2012-08-13 17:35:11 -04:00
2012-08-02 09:17:53 -04:00
# include "interface/rsFeedReader.h"
# include "retroshare/rsiface.h"
# define COLUMN_FEED_COUNT 1
# define COLUMN_FEED_NAME 0
# define COLUMN_FEED_DATA 0
# define ROLE_FEED_ID Qt::UserRole
# define ROLE_FEED_SORT Qt::UserRole + 1
# define ROLE_FEED_FOLDER Qt::UserRole + 2
# define ROLE_FEED_UNREAD Qt::UserRole + 3
2013-01-10 17:51:04 -05:00
# 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
2012-08-02 09:17:53 -04:00
2013-01-08 17:07:52 -05:00
FeedReaderDialog : : FeedReaderDialog ( RsFeedReader * feedReader , FeedReaderNotify * notify , QWidget * parent )
: MainPage ( parent ) , mFeedReader ( feedReader ) , mNotify ( notify ) , ui ( new Ui : : FeedReaderDialog )
2012-08-02 09:17:53 -04:00
{
/* Invoke the Qt Designer generated object setup routine */
ui - > setupUi ( this ) ;
2012-12-25 18:53:55 -05:00
mProcessSettings = false ;
mOpenFeedIds = NULL ;
2013-01-05 21:30:10 -05:00
mMessageWidget = NULL ;
2012-12-25 18:53:55 -05:00
2020-11-08 07:22:59 -05:00
connect ( mNotify , & FeedReaderNotify : : feedChanged , this , & FeedReaderDialog : : feedChanged , Qt : : QueuedConnection ) ;
2013-01-05 21:30:10 -05:00
connect ( NotifyQt : : getInstance ( ) , SIGNAL ( settingsChanged ( ) ) , this , SLOT ( settingsChanged ( ) ) ) ;
2012-08-02 09:17:53 -04:00
/* connect signals */
2012-12-29 21:41:53 -05:00
connect ( ui - > feedTreeWidget , SIGNAL ( itemActivated ( QTreeWidgetItem * , int ) ) , this , SLOT ( feedTreeItemActivated ( QTreeWidgetItem * ) ) ) ;
if ( ! style ( ) - > styleHint ( QStyle : : SH_ItemView_ActivateItemOnSingleClick , NULL , this ) ) {
// need signal itemClicked too
connect ( ui - > feedTreeWidget , SIGNAL ( itemClicked ( QTreeWidgetItem * , int ) ) , this , SLOT ( feedTreeItemActivated ( QTreeWidgetItem * ) ) ) ;
}
2012-08-02 09:17:53 -04:00
connect ( ui - > feedTreeWidget , SIGNAL ( customContextMenuRequested ( QPoint ) ) , this , SLOT ( feedTreeCustomPopupMenu ( QPoint ) ) ) ;
2013-01-05 21:30:10 -05:00
connect ( ui - > feedTreeWidget , SIGNAL ( signalMouseMiddleButtonClicked ( QTreeWidgetItem * ) ) , this , SLOT ( feedTreeMiddleButtonClicked ( QTreeWidgetItem * ) ) ) ;
2012-08-02 09:17:53 -04:00
2012-12-29 21:41:53 -05:00
connect ( ui - > messageTabWidget , SIGNAL ( tabCloseRequested ( int ) ) , this , SLOT ( messageTabCloseRequested ( int ) ) ) ;
connect ( ui - > messageTabWidget , SIGNAL ( currentChanged ( int ) ) , this , SLOT ( messageTabChanged ( int ) ) ) ;
2012-12-27 19:42:27 -05:00
connect ( ui - > feedAddButton , SIGNAL ( clicked ( ) ) , this , SLOT ( newFeed ( ) ) ) ;
connect ( ui - > feedProcessButton , SIGNAL ( clicked ( ) ) , this , SLOT ( processFeed ( ) ) ) ;
2023-04-13 09:53:14 -04:00
connect ( ui - > feedTreeWidget , SIGNAL ( feedReparent ( QTreeWidgetItem * , QTreeWidgetItem * ) ) , this , SLOT ( feedTreeReparent ( QTreeWidgetItem * , QTreeWidgetItem * ) ) ) ;
2012-08-02 09:17:53 -04:00
mFeedCompareRole = new RSTreeWidgetItemCompareRole ;
mFeedCompareRole - > setRole ( COLUMN_FEED_NAME , ROLE_FEED_SORT ) ;
2023-04-13 09:53:14 -04:00
/* enable drag and drop */
ui - > feedTreeWidget - > setAcceptDrops ( true ) ;
ui - > feedTreeWidget - > setDragEnabled ( true ) ;
ui - > feedTreeWidget - > setDragDropMode ( QAbstractItemView : : InternalMove ) ;
2012-08-02 09:17:53 -04:00
/* initialize root item */
mRootItem = new QTreeWidgetItem ( ui - > feedTreeWidget ) ;
QString name = tr ( " Message Folders " ) ;
mRootItem - > setText ( COLUMN_FEED_NAME , name ) ;
mRootItem - > setIcon ( COLUMN_FEED_NAME , QIcon ( " :/images/Root.png " ) ) ;
mRootItem - > setData ( COLUMN_FEED_DATA , ROLE_FEED_NAME , name ) ;
mRootItem - > setData ( COLUMN_FEED_DATA , ROLE_FEED_FOLDER , true ) ;
mRootItem - > setData ( COLUMN_FEED_DATA , ROLE_FEED_ICON , QIcon ( " :/images/Root.png " ) ) ;
mRootItem - > setExpanded ( true ) ;
2013-01-05 21:30:10 -05:00
/* set initial size the splitter */
2014-12-13 18:32:23 -05:00
ui - > splitter - > setStretchFactor ( 0 , 0 ) ;
ui - > splitter - > setStretchFactor ( 1 , 1 ) ;
2013-01-05 21:30:10 -05:00
QList < int > sizes ;
sizes < < 300 < < width ( ) ; // Qt calculates the right sizes
ui - > splitter - > setSizes ( sizes ) ;
2012-08-02 09:17:53 -04:00
/* load settings */
processSettings ( true ) ;
/* initialize feed list */
ui - > feedTreeWidget - > sortItems ( COLUMN_FEED_NAME , Qt : : AscendingOrder ) ;
2012-12-25 18:53:55 -05:00
ui - > feedTreeWidget - > installEventFilter ( this ) ;
2012-12-27 19:42:27 -05:00
2013-01-05 21:30:10 -05:00
settingsChanged ( ) ;
2012-12-29 21:41:53 -05:00
feedTreeItemActivated ( NULL ) ;
2012-08-02 09:17:53 -04:00
}
FeedReaderDialog : : ~ FeedReaderDialog ( )
{
/* save settings */
processSettings ( false ) ;
delete ( mFeedCompareRole ) ;
delete ( ui ) ;
2012-12-25 18:53:55 -05:00
if ( mOpenFeedIds ) {
delete mOpenFeedIds ;
mOpenFeedIds = NULL ;
}
2012-08-02 09:17:53 -04:00
}
2020-01-26 17:19:20 -05:00
UserNotify * FeedReaderDialog : : createUserNotify ( QObject * parent )
2012-12-20 08:30:16 -05:00
{
return new FeedReaderUserNotify ( this , mFeedReader , mNotify , parent ) ;
}
2012-08-02 09:17:53 -04:00
void FeedReaderDialog : : processSettings ( bool load )
{
mProcessSettings = true ;
Settings - > beginGroup ( QString ( " FeedReaderDialog " ) ) ;
if ( load ) {
// load settings
// state of splitter
ui - > splitter - > restoreState ( Settings - > value ( " Splitter " ) . toByteArray ( ) ) ;
2012-12-25 18:53:55 -05:00
// open feeds
int arrayIndex = Settings - > beginReadArray ( " Feeds " ) ;
for ( int index = 0 ; index < arrayIndex ; index + + ) {
Settings - > setArrayIndex ( index ) ;
2020-11-08 07:22:59 -05:00
addFeedToExpand ( Settings - > value ( " open " ) . toUInt ( ) ) ;
2012-12-25 18:53:55 -05:00
}
Settings - > endArray ( ) ;
2012-08-02 09:17:53 -04:00
} else {
// save settings
// state of splitter
Settings - > setValue ( " Splitter " , ui - > splitter - > saveState ( ) ) ;
2012-12-25 18:53:55 -05:00
// open groups
Settings - > beginWriteArray ( " Feeds " ) ;
int arrayIndex = 0 ;
2020-11-08 07:22:59 -05:00
QList < uint32_t > expandedFeedIds ;
2012-12-25 18:53:55 -05:00
getExpandedFeedIds ( expandedFeedIds ) ;
2020-11-08 07:22:59 -05:00
foreach ( uint32_t feedId , expandedFeedIds ) {
2012-12-25 18:53:55 -05:00
Settings - > setArrayIndex ( arrayIndex + + ) ;
2020-11-08 07:22:59 -05:00
Settings - > setValue ( " open " , feedId ) ;
2012-12-25 18:53:55 -05:00
}
Settings - > endArray ( ) ;
2012-08-02 09:17:53 -04:00
}
Settings - > endGroup ( ) ;
mProcessSettings = false ;
}
2013-01-05 21:30:10 -05:00
void FeedReaderDialog : : settingsChanged ( )
{
if ( FeedReaderSetting_OpenAllInNewTab ( ) ) {
if ( mMessageWidget ) {
delete ( mMessageWidget ) ;
mMessageWidget = NULL ;
}
} else {
if ( ! mMessageWidget ) {
2020-11-08 07:22:59 -05:00
mMessageWidget = createMessageWidget ( 0 ) ;
2013-01-05 21:30:10 -05:00
// remove close button of the the first tab
ui - > messageTabWidget - > hideCloseButton ( ui - > messageTabWidget - > indexOf ( mMessageWidget ) ) ;
}
}
}
2020-11-08 07:22:59 -05:00
void FeedReaderDialog : : addFeedToExpand ( uint32_t feedId )
2012-12-25 18:53:55 -05:00
{
if ( mOpenFeedIds = = NULL ) {
2020-11-08 07:22:59 -05:00
mOpenFeedIds = new QList < uint32_t > ;
2012-12-25 18:53:55 -05:00
}
if ( mOpenFeedIds - > contains ( feedId ) ) {
return ;
}
mOpenFeedIds - > push_back ( feedId ) ;
}
2020-11-08 07:22:59 -05:00
void FeedReaderDialog : : getExpandedFeedIds ( QList < uint32_t > & feedIds )
2012-12-25 18:53:55 -05:00
{
QTreeWidgetItemIterator it ( ui - > feedTreeWidget ) ;
QTreeWidgetItem * item ;
while ( ( item = * it ) ! = NULL ) {
+ + it ;
if ( ! item - > isExpanded ( ) ) {
continue ;
}
if ( ! item - > data ( COLUMN_FEED_DATA , ROLE_FEED_FOLDER ) . toBool ( ) ) {
continue ;
}
2020-11-08 07:22:59 -05:00
uint32_t feedId = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) ;
if ( feedId = = 0 ) {
2012-12-25 18:53:55 -05:00
continue ;
}
feedIds . push_back ( feedId ) ;
}
}
2012-08-02 09:17:53 -04:00
void FeedReaderDialog : : showEvent ( QShowEvent */ * event */ )
{
2020-11-08 07:22:59 -05:00
updateFeeds ( 0 , mRootItem ) ;
2012-08-02 09:17:53 -04:00
}
bool FeedReaderDialog : : eventFilter ( QObject * obj , QEvent * event )
{
if ( obj = = ui - > feedTreeWidget ) {
if ( event - > type ( ) = = QEvent : : KeyPress ) {
QKeyEvent * keyEvent = static_cast < QKeyEvent * > ( event ) ;
if ( keyEvent ) {
if ( keyEvent - > key ( ) = = Qt : : Key_Delete ) {
/* Delete pressed */
removeFeed ( ) ;
return true ; // eat event
}
}
}
}
/* pass the event on to the parent class */
return MainPage : : eventFilter ( obj , event ) ;
}
2020-11-08 07:22:59 -05:00
uint32_t FeedReaderDialog : : currentFeedId ( )
2012-08-02 09:17:53 -04:00
{
QTreeWidgetItem * item = ui - > feedTreeWidget - > currentItem ( ) ;
if ( ! item ) {
2020-11-08 07:22:59 -05:00
return 0 ;
2012-08-02 09:17:53 -04:00
}
2020-11-08 07:22:59 -05:00
return item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) ;
2012-08-02 09:17:53 -04:00
}
2020-11-08 07:22:59 -05:00
void FeedReaderDialog : : setCurrentFeedId ( uint32_t feedId )
2012-12-29 21:41:53 -05:00
{
2020-11-08 07:22:59 -05:00
if ( feedId = = 0 ) {
2012-12-29 21:41:53 -05:00
return ;
}
QTreeWidgetItemIterator it ( ui - > feedTreeWidget ) ;
QTreeWidgetItem * item ;
while ( ( item = * it ) ! = NULL ) {
2020-11-08 07:22:59 -05:00
if ( item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) = = feedId ) {
2012-12-29 21:41:53 -05:00
ui - > feedTreeWidget - > setCurrentItem ( item ) ;
break ;
}
+ + it ;
}
}
2012-08-02 09:17:53 -04:00
void FeedReaderDialog : : feedTreeCustomPopupMenu ( QPoint /*point*/ )
{
QMenu contextMnu ( this ) ;
bool folder = false ;
2020-11-08 07:22:59 -05:00
uint32_t feedId ;
2012-08-02 09:17:53 -04:00
QTreeWidgetItem * item = ui - > feedTreeWidget - > currentItem ( ) ;
if ( item ) {
folder = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_FOLDER ) . toBool ( ) ;
2020-11-08 07:22:59 -05:00
feedId = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) ;
2012-08-02 09:17:53 -04:00
}
QMenu * menu = contextMnu . addMenu ( QIcon ( " " ) , tr ( " New " ) ) ;
QAction * action = menu - > addAction ( QIcon ( " :/images/FeedAdd.png " ) , tr ( " Feed " ) , this , SLOT ( newFeed ( ) ) ) ;
if ( ! item | | ! folder ) {
action - > setEnabled ( false ) ;
}
action = menu - > addAction ( QIcon ( " :/images/FolderAdd.png " ) , tr ( " Folder " ) , this , SLOT ( newFolder ( ) ) ) ;
if ( ! item | | ! folder ) {
action - > setEnabled ( false ) ;
}
2013-01-05 21:30:10 -05:00
if ( ! FeedReaderSetting_OpenAllInNewTab ( ) ) {
contextMnu . addSeparator ( ) ;
2012-08-02 09:17:53 -04:00
2013-01-05 21:30:10 -05:00
action = contextMnu . addAction ( QIcon ( " " ) , tr ( " Open in new tab " ) , this , SLOT ( openInNewTab ( ) ) ) ;
if ( ! item | | folder | | feedMessageWidget ( feedId ) ) {
action - > setEnabled ( false ) ;
}
2012-12-29 21:41:53 -05:00
}
contextMnu . addSeparator ( ) ;
2012-08-02 09:17:53 -04:00
action = contextMnu . addAction ( QIcon ( " :/images/edit_16.png " ) , tr ( " Edit " ) , this , SLOT ( editFeed ( ) ) ) ;
if ( ! item | | item = = mRootItem ) {
action - > setEnabled ( false ) ;
}
action = contextMnu . addAction ( QIcon ( " :/images/delete.png " ) , tr ( " Delete " ) , this , SLOT ( removeFeed ( ) ) ) ;
if ( ! item | | item = = mRootItem ) {
action - > setEnabled ( false ) ;
}
contextMnu . addSeparator ( ) ;
bool deactivated = false ;
if ( ! folder & & item ) {
deactivated = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_DEACTIVATED ) . toBool ( ) ;
}
action = contextMnu . addAction ( QIcon ( " :/images/Update.png " ) , tr ( " Update " ) , this , SLOT ( processFeed ( ) ) ) ;
action - > setEnabled ( ! deactivated ) ;
action = contextMnu . addAction ( QIcon ( " " ) , deactivated ? tr ( " Activate " ) : tr ( " Deactivate " ) , this , SLOT ( activateFeed ( ) ) ) ;
if ( ! item | | item = = mRootItem | | folder ) {
action - > setEnabled ( false ) ;
}
contextMnu . exec ( QCursor : : pos ( ) ) ;
}
2020-11-08 07:22:59 -05:00
void FeedReaderDialog : : updateFeeds ( uint32_t parentId , QTreeWidgetItem * parentItem )
2012-08-02 09:17:53 -04:00
{
if ( ! parentItem ) {
return ;
}
/* get feed infos */
std : : list < FeedInfo > feedInfos ;
mFeedReader - > getFeedList ( parentId , feedInfos ) ;
int index = 0 ;
QTreeWidgetItem * item ;
std : : list < FeedInfo > : : iterator feedIt ;
/* update existing and delete not existing feeds */
while ( index < parentItem - > childCount ( ) ) {
item = parentItem - > child ( index ) ;
2020-11-08 07:22:59 -05:00
uint32_t feedId = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) ;
2012-08-02 09:17:53 -04:00
/* search existing feed */
int found = - 1 ;
for ( feedIt = feedInfos . begin ( ) ; feedIt ! = feedInfos . end ( ) ; + + feedIt ) {
if ( feedIt - > feedId = = feedId ) {
/* found it, update it */
updateFeedItem ( item , * feedIt ) ;
if ( feedIt - > flag . folder ) {
/* process child feeds */
updateFeeds ( feedIt - > feedId , item ) ;
}
feedInfos . erase ( feedIt ) ;
found = index ;
break ;
}
}
if ( found > = 0 ) {
+ + index ;
} else {
delete ( parentItem - > takeChild ( index ) ) ;
}
}
/* add new feeds */
for ( feedIt = feedInfos . begin ( ) ; feedIt ! = feedInfos . end ( ) ; + + feedIt ) {
item = new RSTreeWidgetItem ( mFeedCompareRole ) ;
parentItem - > addChild ( item ) ;
updateFeedItem ( item , * feedIt ) ;
if ( feedIt - > flag . folder ) {
/* process child feeds */
updateFeeds ( feedIt - > feedId , item ) ;
2012-12-25 18:53:55 -05:00
if ( mOpenFeedIds ) {
int index = mOpenFeedIds - > indexOf ( feedIt - > feedId ) ;
if ( index > = 0 ) {
item - > setExpanded ( true ) ;
mOpenFeedIds - > removeAt ( index ) ;
}
}
2023-04-13 09:53:14 -04:00
} else {
/* disable drop */
item - > setFlags ( item - > flags ( ) & ~ Qt : : ItemIsDropEnabled ) ;
2012-08-02 09:17:53 -04:00
}
}
2012-12-25 18:53:55 -05:00
if ( mOpenFeedIds & & mOpenFeedIds - > empty ( ) ) {
delete mOpenFeedIds ;
mOpenFeedIds = NULL ;
}
2012-08-02 09:17:53 -04:00
calculateFeedItems ( ) ;
}
2013-01-10 17:51:04 -05:00
void FeedReaderDialog : : calculateFeedItem ( QTreeWidgetItem * item , uint32_t & unreadCount , uint32_t & newCount , bool & loading )
2012-08-02 09:17:53 -04:00
{
uint32_t unreadCountItem = 0 ;
2013-01-10 17:51:04 -05:00
uint32_t newCountItem = 0 ;
2012-08-02 09:17:53 -04:00
bool loadingItem = false ;
if ( item - > data ( COLUMN_FEED_DATA , ROLE_FEED_FOLDER ) . toBool ( ) ) {
int childCount = item - > childCount ( ) ;
for ( int index = 0 ; index < childCount ; + + index ) {
2013-01-10 17:51:04 -05:00
calculateFeedItem ( item - > child ( index ) , unreadCountItem , newCountItem , loadingItem ) ;
2012-08-02 09:17:53 -04:00
}
} else {
unreadCountItem = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_UNREAD ) . toUInt ( ) ;
2013-01-10 17:51:04 -05:00
newCountItem = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_NEW ) . toUInt ( ) ;
2012-08-02 09:17:53 -04:00
loadingItem = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_LOADING ) . toBool ( ) ;
}
unreadCount + = unreadCountItem ;
2013-01-10 17:51:04 -05:00
newCount + = newCountItem ;
2012-08-02 09:17:53 -04:00
loading = loading | | loadingItem ;
QString name = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_NAME ) . toString ( ) ;
QString workState = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_WORKSTATE ) . toString ( ) ;
if ( unreadCountItem ) {
name + = QString ( " (%1) " ) . arg ( unreadCountItem ) ;
}
if ( ! workState . isEmpty ( ) ) {
name + = QString ( " (%1) " ) . arg ( workState ) ;
}
item - > setText ( COLUMN_FEED_NAME , name ) ;
bool deactivated = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_DEACTIVATED ) . toBool ( ) ;
2013-07-04 16:09:46 -04:00
QColor colorActivated = ui - > feedTreeWidget - > palette ( ) . color ( QPalette : : Active , QPalette : : Text ) ;
QColor color = ui - > feedTreeWidget - > palette ( ) . color ( QPalette : : Active , QPalette : : Base ) ;
QColor colorDeactivated ;
colorDeactivated . setRgbF ( ( color . redF ( ) + colorActivated . redF ( ) ) / 2 , ( color . greenF ( ) + colorActivated . greenF ( ) ) / 2 , ( color . blueF ( ) + colorActivated . blueF ( ) ) / 2 ) ;
2012-08-02 09:17:53 -04:00
for ( int i = 0 ; i < COLUMN_FEED_COUNT ; i + + ) {
QFont font = item - > font ( i ) ;
font . setBold ( unreadCountItem ! = 0 ) ;
item - > setFont ( i , font ) ;
2020-05-16 13:43:27 -04:00
item - > setData ( COLUMN_FEED_NAME , Qt : : ForegroundRole , deactivated ? colorDeactivated : colorActivated ) ;
2012-08-02 09:17:53 -04:00
}
QIcon icon = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ICON ) . value < QIcon > ( ) ;
if ( deactivated ) {
/* create disabled icon */
icon = icon . pixmap ( QSize ( 16 , 16 ) , QIcon : : Disabled ) ;
}
QImage overlayIcon ;
if ( loadingItem ) {
/* overlaying icon */
overlayIcon = QImage ( " :/images/FeedProcessOverlay.png " ) ;
} else if ( item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ERROR ) . toBool ( ) ) {
overlayIcon = QImage ( " :/images/FeedErrorOverlay.png " ) ;
2013-01-10 17:51:04 -05:00
} else if ( newCountItem ) {
overlayIcon = QImage ( " :/images/FeedNewOverlay.png " ) ;
2012-08-02 09:17:53 -04:00
}
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 ;
}
}
item - > setIcon ( COLUMN_FEED_NAME , icon ) ;
}
void FeedReaderDialog : : calculateFeedItems ( )
{
uint32_t unreadCount = 0 ;
2013-01-10 17:51:04 -05:00
uint32_t newCount = 0 ;
2012-08-02 09:17:53 -04:00
bool loading = false ;
2013-01-10 17:51:04 -05:00
calculateFeedItem ( mRootItem , unreadCount , newCount , loading ) ;
2012-08-02 09:17:53 -04:00
ui - > feedTreeWidget - > sortItems ( COLUMN_FEED_NAME , Qt : : AscendingOrder ) ;
}
2013-01-10 17:51:04 -05:00
QIcon FeedReaderDialog : : iconFromFeed ( const FeedInfo & feedInfo )
2012-08-02 09:17:53 -04:00
{
QIcon icon ;
2013-01-10 17:51:04 -05:00
if ( feedInfo . flag . folder ) {
2012-08-02 09:17:53 -04:00
/* use folder icon */
icon = QIcon ( " :/images/Folder.png " ) ;
} else {
2013-01-10 17:51:04 -05:00
if ( feedInfo . icon . empty ( ) ) {
2012-08-02 09:17:53 -04:00
/* use standard icon */
icon = QIcon ( " :/images/Feed.png " ) ;
2013-01-10 17:51:04 -05:00
} 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 ) ;
}
}
2012-08-02 09:17:53 -04:00
}
2013-01-10 17:51:04 -05:00
return icon ;
}
void FeedReaderDialog : : updateFeedItem ( QTreeWidgetItem * item , const FeedInfo & feedInfo )
{
item - > setData ( COLUMN_FEED_DATA , ROLE_FEED_ICON , iconFromFeed ( feedInfo ) ) ;
2012-08-02 09:17:53 -04:00
2013-01-10 17:51:04 -05:00
QString name = QString : : fromUtf8 ( feedInfo . name . c_str ( ) ) ;
2012-08-02 09:17:53 -04:00
item - > setData ( COLUMN_FEED_DATA , ROLE_FEED_NAME , name . isEmpty ( ) ? tr ( " No name " ) : name ) ;
2013-01-10 17:51:04 -05:00
item - > setData ( COLUMN_FEED_DATA , ROLE_FEED_WORKSTATE , FeedReaderStringDefs : : workState ( feedInfo . workstate ) ) ;
2012-08-02 09:17:53 -04:00
uint32_t unreadCount ;
2013-01-10 17:51:04 -05:00
uint32_t newCount ;
mFeedReader - > getMessageCount ( feedInfo . feedId , NULL , & newCount , & unreadCount ) ;
2012-08-02 09:17:53 -04:00
2013-01-10 17:51:04 -05:00
item - > setData ( COLUMN_FEED_NAME , ROLE_FEED_SORT , QString ( " %1_%2 " ) . arg ( QString ( feedInfo . flag . folder ? " 0 " : " 1 " ) , name ) ) ;
2012-08-02 09:17:53 -04:00
item - > setData ( COLUMN_FEED_DATA , ROLE_FEED_UNREAD , unreadCount ) ;
2013-01-10 17:51:04 -05:00
item - > setData ( COLUMN_FEED_DATA , ROLE_FEED_NEW , newCount ) ;
item - > setData ( COLUMN_FEED_DATA , ROLE_FEED_LOADING , feedInfo . workstate ! = FeedInfo : : WAITING ) ;
2020-11-08 07:22:59 -05:00
item - > setData ( COLUMN_FEED_DATA , ROLE_FEED_ID , feedInfo . feedId ) ;
2013-01-10 17:51:04 -05:00
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 ) : " " ) ;
2012-08-02 09:17:53 -04:00
}
2020-11-08 07:22:59 -05:00
void FeedReaderDialog : : feedChanged ( uint32_t feedId , int type )
2012-08-02 09:17:53 -04:00
{
if ( ! isVisible ( ) ) {
/* complete update in showEvent */
return ;
}
2020-11-08 07:22:59 -05:00
if ( feedId = = 0 ) {
2012-08-02 09:17:53 -04:00
return ;
}
FeedInfo feedInfo ;
if ( type ! = NOTIFY_TYPE_DEL ) {
2020-11-08 07:22:59 -05:00
if ( ! mFeedReader - > getFeedInfo ( feedId , feedInfo ) ) {
2012-08-02 09:17:53 -04:00
return ;
}
2012-08-13 17:35:11 -04:00
if ( feedInfo . flag . preview ) {
return ;
}
2012-08-02 09:17:53 -04:00
}
if ( type = = NOTIFY_TYPE_MOD | | type = = NOTIFY_TYPE_DEL ) {
QTreeWidgetItemIterator it ( ui - > feedTreeWidget ) ;
QTreeWidgetItem * item ;
while ( ( item = * it ) ! = NULL ) {
2020-11-08 07:22:59 -05:00
if ( item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) = = feedId ) {
2012-08-02 09:17:53 -04:00
if ( type = = NOTIFY_TYPE_MOD ) {
updateFeedItem ( item , feedInfo ) ;
} else {
delete ( item ) ;
}
break ;
}
+ + it ;
}
}
if ( type = = NOTIFY_TYPE_ADD ) {
QTreeWidgetItemIterator it ( ui - > feedTreeWidget ) ;
QTreeWidgetItem * itemParent ;
while ( ( itemParent = * it ) ! = NULL ) {
2020-11-08 07:22:59 -05:00
if ( itemParent - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) = = feedInfo . parentId ) {
2012-08-02 09:17:53 -04:00
QTreeWidgetItem * item = new RSTreeWidgetItem ( mFeedCompareRole ) ;
itemParent - > addChild ( item ) ;
updateFeedItem ( item , feedInfo ) ;
break ;
}
+ + it ;
}
}
calculateFeedItems ( ) ;
}
2020-11-08 07:22:59 -05:00
FeedReaderMessageWidget * FeedReaderDialog : : feedMessageWidget ( uint32_t id )
2012-08-02 09:17:53 -04:00
{
2012-12-25 18:53:55 -05:00
int tabCount = ui - > messageTabWidget - > count ( ) ;
for ( int index = 0 ; index < tabCount ; + + index ) {
FeedReaderMessageWidget * childWidget = dynamic_cast < FeedReaderMessageWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
2013-01-05 21:30:10 -05:00
if ( mMessageWidget & & childWidget = = mMessageWidget ) {
2012-12-29 21:41:53 -05:00
continue ;
}
2012-12-25 18:53:55 -05:00
if ( childWidget & & childWidget - > feedId ( ) = = id ) {
return childWidget ;
2012-08-02 09:17:53 -04:00
}
}
2012-12-25 18:53:55 -05:00
return NULL ;
2012-08-02 09:17:53 -04:00
}
2020-11-08 07:22:59 -05:00
FeedReaderMessageWidget * FeedReaderDialog : : createMessageWidget ( uint32_t feedId )
2012-12-29 21:41:53 -05:00
{
FeedReaderMessageWidget * messageWidget = new FeedReaderMessageWidget ( feedId , mFeedReader , mNotify ) ;
int index = ui - > messageTabWidget - > addTab ( messageWidget , messageWidget - > feedName ( true ) ) ;
ui - > messageTabWidget - > setTabIcon ( index , messageWidget - > feedIcon ( ) ) ;
connect ( messageWidget , SIGNAL ( feedMessageChanged ( QWidget * ) ) , this , SLOT ( messageTabInfoChanged ( QWidget * ) ) ) ;
return messageWidget ;
}
void FeedReaderDialog : : feedTreeItemActivated ( QTreeWidgetItem * item )
2012-08-02 09:17:53 -04:00
{
if ( ! item ) {
2012-12-27 19:42:27 -05:00
ui - > feedAddButton - > setEnabled ( false ) ;
ui - > feedProcessButton - > setEnabled ( false ) ;
2012-08-02 09:17:53 -04:00
return ;
}
2012-12-27 19:42:27 -05:00
ui - > feedProcessButton - > setEnabled ( true ) ;
2012-12-25 18:53:55 -05:00
if ( item - > data ( COLUMN_FEED_DATA , ROLE_FEED_FOLDER ) . toBool ( ) ) {
2012-12-27 19:42:27 -05:00
ui - > feedAddButton - > setEnabled ( true ) ;
2012-08-02 09:17:53 -04:00
return ;
}
2012-12-27 19:42:27 -05:00
ui - > feedAddButton - > setEnabled ( false ) ;
2020-11-08 07:22:59 -05:00
uint32_t feedId = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) ;
2012-12-25 18:53:55 -05:00
/* search exisiting tab */
FeedReaderMessageWidget * messageWidget = feedMessageWidget ( feedId ) ;
2012-12-29 21:41:53 -05:00
if ( ! messageWidget ) {
2013-01-05 21:30:10 -05:00
if ( mMessageWidget ) {
/* not found, use standard tab */
messageWidget = mMessageWidget ;
messageWidget - > setFeedId ( feedId ) ;
} else {
/* create new tab */
messageWidget = createMessageWidget ( feedId ) ;
}
2012-12-29 21:41:53 -05:00
}
ui - > messageTabWidget - > setCurrentWidget ( messageWidget ) ;
}
2012-08-02 09:17:53 -04:00
2013-01-05 21:30:10 -05:00
void FeedReaderDialog : : feedTreeMiddleButtonClicked ( QTreeWidgetItem * item )
{
if ( ! item ) {
return ;
}
2020-11-08 07:22:59 -05:00
openFeedInNewTab ( item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) ) ;
2013-01-05 21:30:10 -05:00
}
2012-12-29 21:41:53 -05:00
void FeedReaderDialog : : openInNewTab ( )
{
2013-01-05 21:30:10 -05:00
openFeedInNewTab ( currentFeedId ( ) ) ;
}
2020-11-08 07:22:59 -05:00
void FeedReaderDialog : : openFeedInNewTab ( uint32_t feedId )
2013-01-05 21:30:10 -05:00
{
2020-11-08 07:22:59 -05:00
if ( feedId = = 0 ) {
2012-12-29 21:41:53 -05:00
return ;
}
/* search exisiting tab */
FeedReaderMessageWidget * messageWidget = feedMessageWidget ( feedId ) ;
2012-12-25 18:53:55 -05:00
if ( ! messageWidget ) {
2012-12-29 21:41:53 -05:00
/* not found, create new tab */
messageWidget = createMessageWidget ( feedId ) ;
2012-08-02 09:17:53 -04:00
}
2012-12-25 18:53:55 -05:00
ui - > messageTabWidget - > setCurrentWidget ( messageWidget ) ;
2012-08-02 09:17:53 -04:00
}
2012-12-25 18:53:55 -05:00
void FeedReaderDialog : : messageTabCloseRequested ( int index )
2012-08-02 09:17:53 -04:00
{
2012-12-25 18:53:55 -05:00
FeedReaderMessageWidget * messageWidget = dynamic_cast < FeedReaderMessageWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
2012-12-29 21:41:53 -05:00
if ( ! messageWidget ) {
return ;
}
if ( messageWidget = = mMessageWidget ) {
return ;
2012-08-02 09:17:53 -04:00
}
2012-12-29 21:41:53 -05:00
delete ( messageWidget ) ;
}
void FeedReaderDialog : : messageTabChanged ( int index )
{
FeedReaderMessageWidget * messageWidget = dynamic_cast < FeedReaderMessageWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
if ( ! messageWidget ) {
return ;
}
setCurrentFeedId ( messageWidget - > feedId ( ) ) ;
2012-08-02 09:17:53 -04:00
}
2012-12-29 21:41:53 -05:00
void FeedReaderDialog : : messageTabInfoChanged ( QWidget * widget )
2012-08-02 09:17:53 -04:00
{
2012-12-25 18:53:55 -05:00
int index = ui - > messageTabWidget - > indexOf ( widget ) ;
if ( index < 0 ) {
2012-08-02 09:17:53 -04:00
return ;
}
2012-12-25 18:53:55 -05:00
FeedReaderMessageWidget * messageWidget = dynamic_cast < FeedReaderMessageWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
if ( ! messageWidget ) {
return ;
2012-08-02 09:17:53 -04:00
}
2020-11-08 07:22:59 -05:00
if ( messageWidget ! = mMessageWidget & & messageWidget - > feedId ( ) = = 0 ) {
2013-01-02 16:02:39 -05:00
messageWidget - > deleteLater ( ) ;
return ;
}
2012-12-25 18:53:55 -05:00
ui - > messageTabWidget - > setTabText ( index , messageWidget - > feedName ( true ) ) ;
ui - > messageTabWidget - > setTabIcon ( index , messageWidget - > feedIcon ( ) ) ;
2012-08-02 09:17:53 -04:00
}
void FeedReaderDialog : : newFolder ( )
{
QInputDialog dialog ;
dialog . setWindowTitle ( tr ( " Add new folder " ) ) ;
dialog . setLabelText ( tr ( " Please enter a name for the folder " ) ) ;
dialog . setWindowIcon ( QIcon ( " :/images/FeedReader.png " ) ) ;
if ( dialog . exec ( ) = = QDialog : : Accepted & & ! dialog . textValue ( ) . isEmpty ( ) ) {
2020-11-08 07:22:59 -05:00
uint32_t feedId ;
2023-04-13 14:16:10 -04:00
RsFeedResult result = mFeedReader - > addFolder ( currentFeedId ( ) , dialog . textValue ( ) . toUtf8 ( ) . constData ( ) , feedId ) ;
2012-08-13 17:35:11 -04:00
FeedReaderStringDefs : : showError ( this , result , tr ( " Create folder " ) , tr ( " Cannot create folder. " ) ) ;
2012-08-02 09:17:53 -04:00
}
}
void FeedReaderDialog : : newFeed ( )
{
2012-08-13 17:35:11 -04:00
AddFeedDialog dialog ( mFeedReader , mNotify , this ) ;
2012-08-02 09:17:53 -04:00
dialog . setParent ( currentFeedId ( ) ) ;
dialog . exec ( ) ;
}
void FeedReaderDialog : : removeFeed ( )
{
2020-11-08 07:22:59 -05:00
uint32_t feedId = currentFeedId ( ) ;
if ( feedId = = 0 ) {
2012-08-02 09:17:53 -04:00
return ;
}
QTreeWidgetItem * item = ui - > feedTreeWidget - > currentItem ( ) ;
if ( ! item ) {
return ;
}
bool folder = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_FOLDER ) . toBool ( ) ;
QString name = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_NAME ) . toString ( ) ;
if ( QMessageBox : : question ( this , folder ? tr ( " Remove folder " ) : tr ( " Remove feed " ) , folder ? tr ( " Do you want to remove the folder %1? " ) . arg ( name ) : tr ( " Do you want to remove the feed %1? " ) . arg ( name ) , QMessageBox : : Yes | QMessageBox : : No , QMessageBox : : No ) = = QMessageBox : : Yes ) {
mFeedReader - > removeFeed ( feedId ) ;
}
}
void FeedReaderDialog : : editFeed ( )
{
2020-11-08 07:22:59 -05:00
uint32_t feedId = currentFeedId ( ) ;
if ( feedId = = 0 ) {
2012-08-02 09:17:53 -04:00
return ;
}
QTreeWidgetItem * item = ui - > feedTreeWidget - > currentItem ( ) ;
if ( ! item ) {
return ;
}
bool folder = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_FOLDER ) . toBool ( ) ;
if ( folder ) {
QInputDialog dialog ;
dialog . setWindowTitle ( tr ( " Edit folder " ) ) ;
dialog . setLabelText ( tr ( " Please enter a new name for the folder " ) ) ;
dialog . setWindowIcon ( QIcon ( " :/images/FeedReader.png " ) ) ;
dialog . setTextValue ( item - > data ( COLUMN_FEED_DATA , ROLE_FEED_NAME ) . toString ( ) ) ;
if ( dialog . exec ( ) = = QDialog : : Accepted & & ! dialog . textValue ( ) . isEmpty ( ) ) {
2023-04-13 14:16:10 -04:00
RsFeedResult result = mFeedReader - > setFolder ( feedId , dialog . textValue ( ) . toUtf8 ( ) . constData ( ) ) ;
2012-08-13 17:35:11 -04:00
FeedReaderStringDefs : : showError ( this , result , tr ( " Create folder " ) , tr ( " Cannot create folder. " ) ) ;
2012-08-02 09:17:53 -04:00
}
} else {
2012-08-13 17:35:11 -04:00
AddFeedDialog dialog ( mFeedReader , mNotify , this ) ;
2012-08-02 09:17:53 -04:00
if ( ! dialog . fillFeed ( feedId ) ) {
return ;
}
dialog . exec ( ) ;
}
}
void FeedReaderDialog : : activateFeed ( )
{
2020-11-08 07:22:59 -05:00
uint32_t feedId = currentFeedId ( ) ;
if ( feedId = = 0 ) {
2012-08-02 09:17:53 -04:00
return ;
}
FeedInfo feedInfo ;
if ( ! mFeedReader - > getFeedInfo ( feedId , feedInfo ) ) {
return ;
}
if ( feedInfo . flag . folder ) {
return ;
}
feedInfo . flag . deactivated = ! feedInfo . flag . deactivated ;
mFeedReader - > setFeed ( feedId , feedInfo ) ;
}
void FeedReaderDialog : : processFeed ( )
{
2020-11-08 07:22:59 -05:00
uint32_t feedId = currentFeedId ( ) ;
2012-08-02 09:17:53 -04:00
/* empty feed id process all feeds */
mFeedReader - > processFeed ( feedId ) ;
}
2023-04-13 09:53:14 -04:00
void FeedReaderDialog : : feedTreeReparent ( QTreeWidgetItem * item , QTreeWidgetItem * newParent )
{
if ( ! item | | ! newParent ) {
return ;
}
uint32_t feedId = item - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) ;
uint32_t parentId = newParent - > data ( COLUMN_FEED_DATA , ROLE_FEED_ID ) . toUInt ( ) ;
if ( feedId = = 0 ) {
return ;
}
2023-04-13 14:16:10 -04:00
RsFeedResult result = mFeedReader - > setParent ( feedId , parentId ) ;
2023-04-13 09:53:14 -04:00
if ( FeedReaderStringDefs : : showError ( this , result , tr ( " Move feed " ) , tr ( " Cannot move feed. " ) ) ) {
return ;
}
bool expanded = item - > isExpanded ( ) ;
item - > parent ( ) - > removeChild ( item ) ;
newParent - > addChild ( item ) ;
item - > setExpanded ( expanded ) ;
newParent - > setExpanded ( true ) ;
calculateFeedItems ( ) ;
}