2018-11-14 21:14:40 +01:00
/*******************************************************************************
* retroshare - gui / src / gui / gxs / GxsGroupFrameDialog . cpp *
* *
* Copyright 2012 - 2013 by Robert Fernie < retroshare . project @ gmail . com > *
* *
* 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/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-05-04 22:59:06 +00:00
# include <QMenu>
# include <QMessageBox>
# include <QToolButton>
# include "GxsGroupFrameDialog.h"
# include "ui_GxsGroupFrameDialog.h"
# include "GxsMessageFrameWidget.h"
# include "gui/settings/rsharesettings.h"
# include "gui/RetroShareLink.h"
2014-10-13 18:31:47 +00:00
# include "gui/gxs/GxsGroupShareKey.h"
2020-07-04 00:05:29 +02:00
# include "gui/common/GroupTreeWidget.h"
2014-05-04 22:59:06 +00:00
# include "gui/common/RSTreeWidget.h"
# include "gui/notifyqt.h"
2014-05-07 21:04:54 +00:00
# include "gui/common/UIStateHelper.h"
2020-01-27 21:38:57 +01:00
# include "gui/common/UserNotify.h"
2020-03-21 15:25:34 +01:00
# include "util/qtthreadsutils.h"
# include "retroshare/rsgxsifacetypes.h"
2014-05-08 00:00:21 +00:00
# include "GxsCommentDialog.h"
2014-05-04 22:59:06 +00:00
//#define DEBUG_GROUPFRAMEDIALOG
/* Images for TreeWidget */
# define IMAGE_SUBSCRIBE ": / images / edit_add24.png"
# define IMAGE_UNSUBSCRIBE ": / images / cancel.png"
# define IMAGE_INFO ": / images / info16.png"
//#define IMAGE_GROUPAUTHD ":/images/konv_message2.png"
# define IMAGE_COPYLINK ": / images / copyrslink.png"
2020-09-14 20:53:16 +02:00
# define IMAGE_EDIT ": / icons / png / pencil-edit-button.png"
2014-05-08 00:00:21 +00:00
# define IMAGE_SHARE ": / images / share-icon-16.png"
# define IMAGE_TABNEW ": / images / tab-new.png"
2018-06-20 23:26:37 +02:00
# define IMAGE_DELETE ": / images / delete.png"
2018-07-05 11:43:55 +02:00
# define IMAGE_RETRIEVE ": / images / edit_add24.png"
2014-05-08 00:00:21 +00:00
# define IMAGE_COMMENT ""
2014-05-04 22:59:06 +00:00
2014-05-07 21:04:54 +00:00
# define TOKEN_TYPE_GROUP_SUMMARY 1
2014-07-05 18:33:11 +00:00
//#define TOKEN_TYPE_SUBSCRIBE_CHANGE 2
2014-05-04 22:59:06 +00:00
//#define TOKEN_TYPE_CURRENTGROUP 3
2014-07-06 16:39:09 +00:00
# define TOKEN_TYPE_STATISTICS 4
2014-05-04 22:59:06 +00:00
2014-05-08 00:00:21 +00:00
# define MAX_COMMENT_TITLE 32
2020-04-11 20:52:35 +02:00
static const uint32_t DELAY_BETWEEN_GROUP_STATISTICS_UPDATE = 120 ; // do not update group statistics more often than once every 2 mins
2014-05-04 22:59:06 +00:00
/*
* Transformation Notes :
* there are still a couple of things that the new groups differ from Old version .
* these will need to be addressed in the future .
* - > Child TS ( for sorting ) is not handled by GXS , this will probably have to be done in the GUI .
* - > Need to handle IDs properly .
* - > Much more to do .
*/
/** Constructor */
2018-07-05 14:00:04 +02:00
GxsGroupFrameDialog : : GxsGroupFrameDialog ( RsGxsIfaceHelper * ifaceImpl , QWidget * parent , bool allow_dist_sync )
2020-02-06 19:57:23 +01:00
: MainPage ( parent )
2014-05-04 22:59:06 +00:00
{
/* Invoke the Qt Designer generated object setup routine */
ui = new Ui : : GxsGroupFrameDialog ( ) ;
ui - > setupUi ( this ) ;
2020-04-09 22:56:59 +02:00
mShouldUpdateMessageSummaryList = true ;
2020-04-11 20:52:35 +02:00
mShouldUpdateGroupStatistics = false ;
mLastGroupStatisticsUpdateTs = 0 ;
2014-05-04 22:59:06 +00:00
mInitialized = false ;
2018-07-05 14:00:04 +02:00
mDistSyncAllowed = allow_dist_sync ;
2015-08-26 14:51:34 +02:00
mInFill = false ;
2014-09-24 23:57:47 +00:00
mCountChildMsgs = false ;
2014-05-04 22:59:06 +00:00
mYourGroups = NULL ;
mSubscribedGroups = NULL ;
mPopularGroups = NULL ;
mOtherGroups = NULL ;
/* Setup Queue */
mInterface = ifaceImpl ;
/* Setup UI helper */
2014-05-07 21:04:54 +00:00
mStateHelper = new UIStateHelper ( this ) ;
mStateHelper - > addWidget ( TOKEN_TYPE_GROUP_SUMMARY , ui - > loadingLabel , UISTATE_LOADING_VISIBLE ) ;
2014-05-04 22:59:06 +00:00
connect ( ui - > groupTreeWidget , SIGNAL ( treeCustomContextMenuRequested ( QPoint ) ) , this , SLOT ( groupTreeCustomPopupMenu ( QPoint ) ) ) ;
2018-06-21 09:26:03 +02:00
connect ( ui - > groupTreeWidget , SIGNAL ( treeCurrentItemChanged ( QString ) ) , this , SLOT ( changedCurrentGroup ( QString ) ) ) ;
2014-05-04 22:59:06 +00:00
connect ( ui - > groupTreeWidget - > treeWidget ( ) , SIGNAL ( signalMouseMiddleButtonClicked ( QTreeWidgetItem * ) ) , this , SLOT ( groupTreeMiddleButtonClicked ( QTreeWidgetItem * ) ) ) ;
connect ( ui - > messageTabWidget , SIGNAL ( tabCloseRequested ( int ) ) , this , SLOT ( messageTabCloseRequested ( int ) ) ) ;
connect ( ui - > messageTabWidget , SIGNAL ( currentChanged ( int ) ) , this , SLOT ( messageTabChanged ( int ) ) ) ;
connect ( ui - > todoPushButton , SIGNAL ( clicked ( ) ) , this , SLOT ( todo ( ) ) ) ;
2018-07-05 14:00:04 +02:00
ui - > groupTreeWidget - > setDistSearchVisible ( allow_dist_sync ) ;
if ( allow_dist_sync )
connect ( ui - > groupTreeWidget , SIGNAL ( distantSearchRequested ( const QString & ) ) , this , SLOT ( searchNetwork ( const QString & ) ) ) ;
2014-05-04 22:59:06 +00:00
/* Set initial size the splitter */
2014-12-13 23:32:23 +00:00
ui - > splitter - > setStretchFactor ( 0 , 0 ) ;
ui - > splitter - > setStretchFactor ( 1 , 1 ) ;
2014-05-04 22:59:06 +00:00
QList < int > sizes ;
sizes < < 300 < < width ( ) ; // Qt calculates the right sizes
ui - > splitter - > setSizes ( sizes ) ;
2014-09-10 21:38:43 +00:00
# ifndef UNFINISHED
ui - > todoPushButton - > hide ( ) ;
# endif
2014-05-04 22:59:06 +00:00
}
GxsGroupFrameDialog : : ~ GxsGroupFrameDialog ( )
{
// save settings
processSettings ( false ) ;
delete ( ui ) ;
}
2018-07-05 10:11:12 +02:00
void GxsGroupFrameDialog : : getGroupList ( std : : map < RsGxsGroupId , RsGroupMetaData > & group_list )
2017-10-21 21:23:40 +02:00
{
group_list = mCachedGroupMetas ;
if ( group_list . empty ( ) )
2020-03-21 15:25:34 +01:00
updateGroupSummary ( ) ;
2020-03-22 02:33:51 +01:00
else
std : : cerr < < " ************** Using cached GroupMetaData " < < std : : endl ;
2017-10-21 21:23:40 +02:00
}
2014-05-04 22:59:06 +00:00
void GxsGroupFrameDialog : : initUi ( )
{
2017-02-25 23:52:57 +01:00
registerHelpButton ( ui - > helpButton , getHelpString ( ) , pageName ( ) ) ;
2014-09-10 21:38:43 +00:00
2020-08-19 16:19:42 +02:00
ui - > titleBarPixmap - > setPixmap ( FilesDefs : : getPixmapFromQtResourcePath ( icon ( ICON_NAME ) ) ) ;
2014-05-04 22:59:06 +00:00
ui - > titleBarLabel - > setText ( text ( TEXT_NAME ) ) ;
/* Initialize group tree */
QToolButton * newGroupButton = new QToolButton ( this ) ;
2020-08-15 22:17:52 +02:00
newGroupButton - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( icon ( ICON_NEW ) ) ) ;
2014-05-04 22:59:06 +00:00
newGroupButton - > setToolTip ( text ( TEXT_NEW ) ) ;
connect ( newGroupButton , SIGNAL ( clicked ( ) ) , this , SLOT ( newGroup ( ) ) ) ;
ui - > groupTreeWidget - > addToolButton ( newGroupButton ) ;
/* Create group tree */
2020-08-15 22:17:52 +02:00
mYourGroups = ui - > groupTreeWidget - > addCategoryItem ( text ( TEXT_YOUR_GROUP ) , FilesDefs : : getIconFromQtResourcePath ( icon ( ICON_YOUR_GROUP ) ) , true ) ;
mSubscribedGroups = ui - > groupTreeWidget - > addCategoryItem ( text ( TEXT_SUBSCRIBED_GROUP ) , FilesDefs : : getIconFromQtResourcePath ( icon ( ICON_SUBSCRIBED_GROUP ) ) , true ) ;
mPopularGroups = ui - > groupTreeWidget - > addCategoryItem ( text ( TEXT_POPULAR_GROUP ) , FilesDefs : : getIconFromQtResourcePath ( icon ( ICON_POPULAR_GROUP ) ) , false ) ;
mOtherGroups = ui - > groupTreeWidget - > addCategoryItem ( text ( TEXT_OTHER_GROUP ) , FilesDefs : : getIconFromQtResourcePath ( icon ( ICON_OTHER_GROUP ) ) , false ) ;
2014-05-04 22:59:06 +00:00
if ( text ( TEXT_TODO ) . isEmpty ( ) ) {
ui - > todoPushButton - > hide ( ) ;
}
// load settings
mSettingsName = settingsGroupName ( ) ;
processSettings ( true ) ;
2014-07-24 14:54:23 +00:00
if ( groupFrameSettingsType ( ) ! = GroupFrameSettings : : Nothing ) {
connect ( NotifyQt : : getInstance ( ) , SIGNAL ( settingsChanged ( ) ) , this , SLOT ( settingsChanged ( ) ) ) ;
settingsChanged ( ) ;
}
2020-03-26 16:47:37 +01:00
mInitialized = true ;
2014-05-04 22:59:06 +00:00
}
void GxsGroupFrameDialog : : showEvent ( QShowEvent * event )
{
2020-03-26 23:19:34 +01:00
if ( ! mInitialized )
2020-03-26 16:47:37 +01:00
{
2014-05-04 22:59:06 +00:00
/* Problem: virtual methods cannot be used in constructor */
initUi ( ) ;
}
2020-04-06 22:11:32 +02:00
uint32_t children = mYourGroups - > childCount ( ) + mSubscribedGroups - > childCount ( ) + mPopularGroups - > childCount ( ) + mOtherGroups - > childCount ( ) ;
bool empty = mCachedGroupMetas . empty ( ) | | children = = 0 ;
2020-04-06 21:55:07 +02:00
updateDisplay ( empty ) ;
}
void GxsGroupFrameDialog : : paintEvent ( QPaintEvent * pe )
{
if ( mShouldUpdateMessageSummaryList )
{
if ( ! mGroupIdsSummaryToUpdate . empty ( ) )
for ( auto & group_id : mGroupIdsSummaryToUpdate )
updateMessageSummaryListReal ( group_id ) ;
else
updateMessageSummaryListReal ( RsGxsGroupId ( ) ) ;
mShouldUpdateMessageSummaryList = false ;
mGroupIdsSummaryToUpdate . clear ( ) ;
}
2020-04-11 20:52:35 +02:00
rstime_t now = time ( nullptr ) ;
if ( mShouldUpdateGroupStatistics & & now > DELAY_BETWEEN_GROUP_STATISTICS_UPDATE + mLastGroupStatisticsUpdateTs )
{
// This mechanism allows to gather multiple updateGroupStatistics events at once and not send too many of them at the same time.
// it avoids re-loadign all the group everytime a friend sends new statistics.
for ( auto & groupId : mGroupStatisticsToUpdate )
updateGroupStatisticsReal ( groupId ) ;
mShouldUpdateGroupStatistics = false ;
mLastGroupStatisticsUpdateTs = time ( nullptr ) ;
mGroupStatisticsToUpdate . clear ( ) ;
}
2020-04-06 21:55:07 +02:00
MainPage : : paintEvent ( pe ) ;
2014-05-04 22:59:06 +00:00
}
void GxsGroupFrameDialog : : processSettings ( bool load )
{
if ( mSettingsName . isEmpty ( ) ) {
return ;
}
Settings - > beginGroup ( mSettingsName ) ;
if ( load ) {
// load settings
// state of splitter
ui - > splitter - > restoreState ( Settings - > value ( " Splitter " ) . toByteArray ( ) ) ;
} else {
// save settings
// state of splitter
Settings - > setValue ( " Splitter " , ui - > splitter - > saveState ( ) ) ;
}
2018-05-08 12:08:08 +02:00
ui - > groupTreeWidget - > processSettings ( load ) ;
2014-05-04 22:59:06 +00:00
Settings - > endGroup ( ) ;
}
2020-06-23 21:37:36 +02:00
bool GxsGroupFrameDialog : : useTabs ( )
{
GroupFrameSettings groupFrameSettings ;
return Settings - > getGroupFrameSettings ( groupFrameSettingsType ( ) , groupFrameSettings ) & & groupFrameSettings . mOpenAllInNewTab ;
}
2014-07-24 14:54:23 +00:00
void GxsGroupFrameDialog : : settingsChanged ( )
{
GroupFrameSettings groupFrameSettings ;
if ( Settings - > getGroupFrameSettings ( groupFrameSettingsType ( ) , groupFrameSettings ) ) {
setSingleTab ( ! groupFrameSettings . mOpenAllInNewTab ) ;
setHideTabBarWithOneTab ( groupFrameSettings . mHideTabBarWithOneTab ) ;
}
}
2014-05-04 22:59:06 +00:00
void GxsGroupFrameDialog : : setSingleTab ( bool singleTab )
{
2020-06-23 21:37:36 +02:00
if ( singleTab )
{
while ( ui - > messageTabWidget - > count ( ) > 1 )
{
auto w = ui - > messageTabWidget - > widget ( 0 ) ;
ui - > messageTabWidget - > removeTab ( 0 ) ;
delete w ;
}
ui - > messageTabWidget - > hideCloseButton ( 0 ) ;
2014-05-04 22:59:06 +00:00
}
}
2014-07-14 21:29:51 +00:00
void GxsGroupFrameDialog : : setHideTabBarWithOneTab ( bool hideTabBarWithOneTab )
{
ui - > messageTabWidget - > setHideTabBarWithOneTab ( hideTabBarWithOneTab ) ;
}
2014-05-04 22:59:06 +00:00
void GxsGroupFrameDialog : : updateDisplay ( bool complete )
{
2020-02-06 19:57:23 +01:00
if ( complete ) // || !getGrpIds().empty() || !getGrpIdsMeta().empty()) {
2020-03-21 15:25:34 +01:00
updateGroupSummary ( ) ; /* Update group list */
2018-06-23 22:25:36 +02:00
2020-06-16 21:13:55 +02:00
// updateSearchResults() ;
2018-06-23 22:25:36 +02:00
}
void GxsGroupFrameDialog : : updateSearchResults ( )
{
2020-06-16 21:13:55 +02:00
for ( auto & it : mSearchGroupsItems )
updateSearchResults ( it . first ) ;
}
2018-06-24 16:55:38 +02:00
2020-06-16 21:13:55 +02:00
void GxsGroupFrameDialog : : updateSearchResults ( const TurtleRequestId & sid )
{
std : : cerr < < " updating search ID " < < std : : hex < < sid < < std : : dec < < std : : endl ;
2018-06-24 16:55:38 +02:00
2020-06-16 21:13:55 +02:00
std : : map < RsGxsGroupId , RsGxsGroupSearchResults > group_infos ;
2018-06-24 23:15:22 +02:00
2020-06-16 21:13:55 +02:00
getDistantSearchResults ( sid , group_infos ) ;
2018-06-24 23:15:22 +02:00
2020-06-16 21:13:55 +02:00
std : : cerr < < " retrieved " < < std : : endl ;
2018-06-24 23:15:22 +02:00
2020-06-16 21:13:55 +02:00
auto it2 = mSearchGroupsItems . find ( sid ) ;
2018-06-24 23:15:22 +02:00
2020-08-30 18:01:58 +02:00
if ( it2 = = mSearchGroupsItems . end ( ) )
{
std : : cerr < < " (EE) received a channel group turtle search result with ID " < < sid < < " but no item is known for this search " < < std : : endl ;
return ;
}
2020-06-16 21:13:55 +02:00
QList < GroupItemInfo > group_items ;
2018-06-24 23:15:22 +02:00
2020-06-16 21:13:55 +02:00
for ( auto it3 ( group_infos . begin ( ) ) ; it3 ! = group_infos . end ( ) ; + + it3 )
{
std : : cerr < < " adding group " < < it3 - > first < < " " < < it3 - > second . mGroupId < < " \" " < < it3 - > second . mGroupName < < " \" " < < std : : endl ;
2020-06-25 21:15:37 +02:00
for ( auto s : it3 - > second . mSearchContexts )
std : : cerr < < " Context string \" " < < s < < " \" " < < std : : endl ;
2020-06-16 21:13:55 +02:00
GroupItemInfo i ;
i . id = QString ( it3 - > second . mGroupId . toStdString ( ) . c_str ( ) ) ;
i . name = QString : : fromUtf8 ( it3 - > second . mGroupName . c_str ( ) ) ;
i . popularity = 0 ; // could be set to the number of hits
i . lastpost = QDateTime : : fromTime_t ( it3 - > second . mLastMessageTs ) ;
i . subscribeFlags = 0 ; // irrelevant here
i . publishKey = false ; // IS_GROUP_PUBLISHER(groupInfo.mSubscribeFlags);
i . adminKey = false ; // IS_GROUP_ADMIN(groupInfo.mSubscribeFlags);
i . max_visible_posts = it3 - > second . mNumberOfMessages ;
i . context_strings = it3 - > second . mSearchContexts ;
group_items . push_back ( i ) ;
}
2018-06-24 23:15:22 +02:00
2020-06-16 21:13:55 +02:00
ui - > groupTreeWidget - > fillGroupItems ( it2 - > second , group_items ) ;
2014-05-04 22:59:06 +00:00
}
void GxsGroupFrameDialog : : todo ( )
{
QMessageBox : : information ( this , " Todo " , text ( TEXT_TODO ) ) ;
}
2018-06-20 23:26:37 +02:00
void GxsGroupFrameDialog : : removeCurrentSearch ( )
{
QAction * action = dynamic_cast < QAction * > ( sender ( ) ) ;
if ( ! action )
return ;
TurtleRequestId search_request_id = action - > data ( ) . toUInt ( ) ;
2018-06-24 23:15:22 +02:00
auto it = mSearchGroupsItems . find ( search_request_id ) ;
2018-06-20 23:26:37 +02:00
2018-06-24 23:15:22 +02:00
if ( it = = mSearchGroupsItems . end ( ) )
2018-06-20 23:26:37 +02:00
return ;
ui - > groupTreeWidget - > removeSearchItem ( it - > second ) ;
2018-06-24 23:15:22 +02:00
mSearchGroupsItems . erase ( it ) ;
mKnownGroups . erase ( search_request_id ) ;
2020-07-03 22:48:33 +02:00
clearDistantSearchResults ( search_request_id ) ;
2018-06-20 23:26:37 +02:00
}
void GxsGroupFrameDialog : : removeAllSearches ( )
{
2018-06-24 23:15:22 +02:00
for ( auto it ( mSearchGroupsItems . begin ( ) ) ; it ! = mSearchGroupsItems . end ( ) ; + + it )
2020-07-03 22:48:33 +02:00
{
2020-07-04 00:05:29 +02:00
QString group_id ;
TurtleRequestId search_request_id ;
2018-06-20 23:26:37 +02:00
2020-07-04 00:05:29 +02:00
if ( ui - > groupTreeWidget - > isSearchRequestResultItem ( it - > second , group_id , search_request_id ) )
2020-07-03 22:48:33 +02:00
clearDistantSearchResults ( search_request_id ) ;
ui - > groupTreeWidget - > removeSearchItem ( it - > second ) ;
}
2018-06-24 23:15:22 +02:00
mSearchGroupsItems . clear ( ) ;
mKnownGroups . clear ( ) ;
2018-06-20 23:26:37 +02:00
}
2019-01-12 14:59:58 +01:00
// Same function than the one in rsgxsnetservice.cc, so that all times are automatically consistent
static uint32_t checkDelay ( uint32_t time_in_secs )
{
if ( time_in_secs < 1 * 86400 )
return 0 ;
if ( time_in_secs < = 10 * 86400 )
return 5 * 86400 ;
if ( time_in_secs < = 20 * 86400 )
return 15 * 86400 ;
if ( time_in_secs < = 60 * 86400 )
return 30 * 86400 ;
if ( time_in_secs < = 120 * 86400 )
return 90 * 86400 ;
if ( time_in_secs < = 250 * 86400 )
return 180 * 86400 ;
return 365 * 86400 ;
}
2020-06-23 20:24:14 +02:00
2014-05-25 21:43:05 +00:00
void GxsGroupFrameDialog : : groupTreeCustomPopupMenu ( QPoint point )
2014-05-04 22:59:06 +00:00
{
2018-06-22 23:38:31 +02:00
// First separately handle the case of search top level items
2018-06-20 23:26:37 +02:00
2018-06-22 23:38:31 +02:00
TurtleRequestId search_request_id = 0 ;
2018-06-20 23:26:37 +02:00
2018-06-22 23:38:31 +02:00
if ( ui - > groupTreeWidget - > isSearchRequestItem ( point , search_request_id ) )
2018-05-08 12:08:08 +02:00
{
2018-06-20 23:26:37 +02:00
QMenu contextMnu ( this ) ;
2020-08-15 22:17:52 +02:00
contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_DELETE ) , tr ( " Remove this search " ) , this , SLOT ( removeCurrentSearch ( ) ) ) - > setData ( search_request_id ) ;
contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_DELETE ) , tr ( " Remove all searches " ) , this , SLOT ( removeAllSearches ( ) ) ) ;
2018-06-20 23:26:37 +02:00
contextMnu . exec ( QCursor : : pos ( ) ) ;
2018-06-22 23:38:31 +02:00
return ;
}
2018-06-20 23:26:37 +02:00
2018-07-05 11:43:55 +02:00
// Then check whether we have a searched item, or a normal group
QString group_id_s ;
if ( ui - > groupTreeWidget - > isSearchRequestResult ( point , group_id_s , search_request_id ) )
{
QMenu contextMnu ( this ) ;
2020-08-15 22:17:52 +02:00
contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_RETRIEVE ) , tr ( " Request data " ) , this , SLOT ( distantRequestGroupData ( ) ) ) - > setData ( group_id_s ) ;
2018-07-05 11:43:55 +02:00
contextMnu . exec ( QCursor : : pos ( ) ) ;
return ;
}
2014-05-29 13:34:08 +00:00
QString id = ui - > groupTreeWidget - > itemIdAt ( point ) ;
2014-05-25 21:43:05 +00:00
if ( id . isEmpty ( ) ) return ;
mGroupId = RsGxsGroupId ( id . toStdString ( ) ) ;
2014-05-04 22:59:06 +00:00
int subscribeFlags = ui - > groupTreeWidget - > subscribeFlags ( QString : : fromStdString ( mGroupId . toStdString ( ) ) ) ;
2018-06-20 23:26:37 +02:00
bool isAdmin = IS_GROUP_ADMIN ( subscribeFlags ) ;
bool isPublisher = IS_GROUP_PUBLISHER ( subscribeFlags ) ;
2014-05-04 22:59:06 +00:00
bool isSubscribed = IS_GROUP_SUBSCRIBED ( subscribeFlags ) ;
QMenu contextMnu ( this ) ;
QAction * action ;
2016-12-05 23:42:44 +01:00
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_TABNEW ) , tr ( " Open in new tab " ) , this , SLOT ( openInNewTab ( ) ) ) ;
2020-06-23 20:24:14 +02:00
2020-06-23 21:37:36 +02:00
if ( mGroupId . isNull ( ) ) // dont enable the open in tab if a tab is already here
action - > setEnabled ( false ) ;
2014-05-04 22:59:06 +00:00
if ( isSubscribed ) {
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_UNSUBSCRIBE ) , tr ( " Unsubscribe " ) , this , SLOT ( unsubscribeGroup ( ) ) ) ;
2014-05-04 22:59:06 +00:00
action - > setEnabled ( ! mGroupId . isNull ( ) & & IS_GROUP_SUBSCRIBED ( subscribeFlags ) ) ;
} else {
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_SUBSCRIBE ) , tr ( " Subscribe " ) , this , SLOT ( subscribeGroup ( ) ) ) ;
2014-05-04 22:59:06 +00:00
action - > setDisabled ( mGroupId . isNull ( ) | | IS_GROUP_SUBSCRIBED ( subscribeFlags ) ) ;
}
contextMnu . addSeparator ( ) ;
2020-08-15 22:17:52 +02:00
contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( icon ( ICON_NEW ) ) , text ( TEXT_NEW ) , this , SLOT ( newGroup ( ) ) ) ;
2014-05-04 22:59:06 +00:00
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_INFO ) , tr ( " Show Details " ) , this , SLOT ( showGroupDetails ( ) ) ) ;
2014-05-04 22:59:06 +00:00
action - > setEnabled ( ! mGroupId . isNull ( ) ) ;
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_EDIT ) , tr ( " Edit Details " ) , this , SLOT ( editGroupDetails ( ) ) ) ;
2014-05-04 22:59:06 +00:00
action - > setEnabled ( ! mGroupId . isNull ( ) & & isAdmin ) ;
2019-01-12 14:59:58 +01:00
uint32_t current_store_time = checkDelay ( mInterface - > getStoragePeriod ( mGroupId ) ) / 86400 ;
uint32_t current_sync_time = checkDelay ( mInterface - > getSyncPeriod ( mGroupId ) ) / 86400 ;
2016-12-05 23:42:44 +01:00
2018-06-22 23:38:31 +02:00
std : : cerr < < " Got sync= " < < current_sync_time < < " . store= " < < current_store_time < < std : : endl ;
QAction * actnn = NULL ;
2016-12-05 23:42:44 +01:00
QMenu * ctxMenu2 = contextMnu . addMenu ( tr ( " Synchronise posts of last... " ) ) ;
2020-08-15 22:17:52 +02:00
actnn = ctxMenu2 - > addAction ( tr ( " 5 days " ) , this , SLOT ( setSyncPostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 5 ) ) ; if ( current_sync_time = = 5 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 2 weeks " ) , this , SLOT ( setSyncPostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 15 ) ) ; if ( current_sync_time = = 15 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 1 month " ) , this , SLOT ( setSyncPostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 30 ) ) ; if ( current_sync_time = = 30 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 3 months " ) , this , SLOT ( setSyncPostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 90 ) ) ; if ( current_sync_time = = 90 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 6 months " ) , this , SLOT ( setSyncPostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 180 ) ) ; if ( current_sync_time = = 180 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 1 year " ) , this , SLOT ( setSyncPostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 365 ) ) ; if ( current_sync_time = = 365 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " Indefinitly " ) , this , SLOT ( setSyncPostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 0 ) ) ; if ( current_sync_time = = 0 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
2016-12-05 23:42:44 +01:00
2018-06-22 23:38:31 +02:00
ctxMenu2 = contextMnu . addMenu ( tr ( " Store posts for at most... " ) ) ;
2020-08-15 22:17:52 +02:00
actnn = ctxMenu2 - > addAction ( tr ( " 5 days " ) , this , SLOT ( setStorePostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 5 ) ) ; if ( current_store_time = = 5 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 2 weeks " ) , this , SLOT ( setStorePostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 15 ) ) ; if ( current_store_time = = 15 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 1 month " ) , this , SLOT ( setStorePostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 30 ) ) ; if ( current_store_time = = 30 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 3 months " ) , this , SLOT ( setStorePostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 90 ) ) ; if ( current_store_time = = 90 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 6 months " ) , this , SLOT ( setStorePostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 180 ) ) ; if ( current_store_time = = 180 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " 1 year " ) , this , SLOT ( setStorePostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 365 ) ) ; if ( current_store_time = = 365 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
actnn = ctxMenu2 - > addAction ( tr ( " Indefinitly " ) , this , SLOT ( setStorePostsDelay ( ) ) ) ; actnn - > setData ( QVariant ( 0 ) ) ; if ( current_store_time = = 0 ) { actnn - > setEnabled ( false ) ; actnn - > setIcon ( FilesDefs : : getIconFromQtResourcePath ( " :/images/start.png " ) ) ; }
2016-12-05 22:14:48 +01:00
2014-07-22 15:04:36 +00:00
if ( shareKeyType ( ) ) {
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_SHARE ) , tr ( " Share publish permissions... " ) , this , SLOT ( sharePublishKey ( ) ) ) ;
2018-06-22 23:38:31 +02:00
action - > setEnabled ( ! mGroupId . isNull ( ) & & isPublisher ) ;
2014-07-22 15:04:36 +00:00
}
2014-05-04 22:59:06 +00:00
2014-07-22 15:04:36 +00:00
if ( getLinkType ( ) ! = RetroShareLink : : TYPE_UNKNOWN ) {
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( IMAGE_COPYLINK ) , tr ( " Copy RetroShare Link " ) , this , SLOT ( copyGroupLink ( ) ) ) ;
2014-07-22 15:04:36 +00:00
action - > setEnabled ( ! mGroupId . isNull ( ) ) ;
}
2014-05-04 22:59:06 +00:00
contextMnu . addSeparator ( ) ;
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( " :/images/message-mail-read.png " ) , tr ( " Mark all as read " ) , this , SLOT ( markMsgAsRead ( ) ) ) ;
2014-05-04 22:59:06 +00:00
action - > setEnabled ( ! mGroupId . isNull ( ) & & isSubscribed ) ;
2020-08-15 22:17:52 +02:00
action = contextMnu . addAction ( FilesDefs : : getIconFromQtResourcePath ( " :/images/message-mail.png " ) , tr ( " Mark all as unread " ) , this , SLOT ( markMsgAsUnread ( ) ) ) ;
2014-05-04 22:59:06 +00:00
action - > setEnabled ( ! mGroupId . isNull ( ) & & isSubscribed ) ;
/* Add special actions */
QList < QAction * > actions ;
groupTreeCustomActions ( mGroupId , subscribeFlags , actions ) ;
if ( ! actions . isEmpty ( ) ) {
contextMnu . addSeparator ( ) ;
contextMnu . addActions ( actions ) ;
}
2018-05-08 12:08:08 +02:00
//Add Standard Menu
ui - > groupTreeWidget - > treeWidget ( ) - > createStandardContextMenu ( & contextMnu ) ;
2014-05-04 22:59:06 +00:00
contextMnu . exec ( QCursor : : pos ( ) ) ;
}
2016-12-05 22:14:48 +01:00
void GxsGroupFrameDialog : : setStorePostsDelay ( )
{
QAction * action = dynamic_cast < QAction * > ( sender ( ) ) ;
if ( ! action | | mGroupId . isNull ( ) )
{
std : : cerr < < " (EE) Cannot find action/group that called me! Group is " < < mGroupId < < " , action is " < < ( void * ) action < < " " < < __PRETTY_FUNCTION__ < < std : : endl ;
return ;
}
uint32_t duration = action - > data ( ) . toUInt ( ) ;
std : : cerr < < " Data is " < < duration < < std : : endl ;
2016-12-05 23:42:44 +01:00
mInterface - > setStoragePeriod ( mGroupId , duration * 86400 ) ;
2016-12-13 21:12:34 +01:00
// If the sync is larger, we reduce it. No need to sync more than we store. The machinery below also takes care of this.
//
uint32_t sync_period = mInterface - > getSyncPeriod ( mGroupId ) ;
if ( duration > 0 ) // the >0 test is to discard the indefinitly test. Basically, if we store for less than indefinitly, the sync is reduced accordingly.
{
if ( sync_period = = 0 | | sync_period > duration * 86400 )
{
mInterface - > setSyncPeriod ( mGroupId , duration * 86400 ) ;
std : : cerr < < " (II) auto adjusting sync period to " < < duration < < " days as well. " < < std : : endl ;
}
}
2016-12-05 22:14:48 +01:00
}
void GxsGroupFrameDialog : : setSyncPostsDelay ( )
{
QAction * action = dynamic_cast < QAction * > ( sender ( ) ) ;
if ( ! action | | mGroupId . isNull ( ) )
{
std : : cerr < < " (EE) Cannot find action/group that called me! Group is " < < mGroupId < < " , action is " < < ( void * ) action < < " " < < __PRETTY_FUNCTION__ < < std : : endl ;
return ;
}
uint32_t duration = action - > data ( ) . toUInt ( ) ;
std : : cerr < < " Data is " < < duration < < std : : endl ;
2016-12-05 23:42:44 +01:00
mInterface - > setSyncPeriod ( mGroupId , duration * 86400 ) ;
2016-12-13 21:12:34 +01:00
// If the store is smaller, we increase it accordingly. No need to sync more than we store. The machinery below also takes care of this.
//
uint32_t store_period = mInterface - > getStoragePeriod ( mGroupId ) ;
if ( duration = = 0 )
mInterface - > setStoragePeriod ( mGroupId , duration * 86400 ) ; // indefinite sync => indefinite storage
else
{
if ( store_period ! = 0 & & store_period < duration * 86400 )
{
mInterface - > setStoragePeriod ( mGroupId , duration * 86400 ) ; // indefinite sync => indefinite storage
std : : cerr < < " (II) auto adjusting storage period to " < < duration < < " days as well. " < < std : : endl ;
}
}
2016-12-05 22:14:48 +01:00
}
2014-05-04 22:59:06 +00:00
void GxsGroupFrameDialog : : restoreGroupKeys ( void )
{
QMessageBox : : warning ( this , " RetroShare " , " ToDo " ) ;
# ifdef TOGXS
mInterface - > groupRestoreKeys ( mGroupId ) ;
# endif
}
void GxsGroupFrameDialog : : newGroup ( )
{
2020-03-22 21:47:14 +01:00
GxsGroupDialog * dialog = createNewGroupDialog ( ) ;
2014-05-04 22:59:06 +00:00
if ( ! dialog ) {
return ;
}
dialog - > exec ( ) ;
delete ( dialog ) ;
}
void GxsGroupFrameDialog : : subscribeGroup ( )
{
groupSubscribe ( true ) ;
}
void GxsGroupFrameDialog : : unsubscribeGroup ( )
{
groupSubscribe ( false ) ;
}
void GxsGroupFrameDialog : : groupSubscribe ( bool subscribe )
{
if ( mGroupId . isNull ( ) ) {
return ;
}
uint32_t token ;
mInterface - > subscribeToGroup ( token , mGroupId , subscribe ) ;
}
void GxsGroupFrameDialog : : showGroupDetails ( )
{
if ( mGroupId . isNull ( ) ) {
return ;
}
2020-03-22 21:47:14 +01:00
GxsGroupDialog * dialog = createGroupDialog ( GxsGroupDialog : : MODE_SHOW , mGroupId ) ;
2014-05-04 22:59:06 +00:00
if ( ! dialog ) {
return ;
}
dialog - > exec ( ) ;
delete ( dialog ) ;
}
void GxsGroupFrameDialog : : editGroupDetails ( )
{
if ( mGroupId . isNull ( ) ) {
return ;
}
2020-03-22 21:47:14 +01:00
GxsGroupDialog * dialog = createGroupDialog ( GxsGroupDialog : : MODE_EDIT , mGroupId ) ;
2014-05-04 22:59:06 +00:00
if ( ! dialog ) {
return ;
}
dialog - > exec ( ) ;
delete ( dialog ) ;
}
void GxsGroupFrameDialog : : copyGroupLink ( )
{
if ( mGroupId . isNull ( ) ) {
return ;
}
2014-07-26 23:52:45 +00:00
QString name ;
if ( ! getCurrentGroupName ( name ) ) return ;
2014-05-27 21:14:05 +00:00
2017-07-16 13:11:47 +02:00
RetroShareLink link = RetroShareLink : : createGxsGroupLink ( getLinkType ( ) , mGroupId , name ) ;
if ( link . valid ( ) ) {
2014-07-26 23:52:45 +00:00
QList < RetroShareLink > urls ;
urls . push_back ( link ) ;
RSLinkClipboard : : copyLinks ( urls ) ;
}
2014-05-27 21:14:05 +00:00
}
bool GxsGroupFrameDialog : : getCurrentGroupName ( QString & name )
{
2014-07-26 23:52:45 +00:00
return ui - > groupTreeWidget - > getGroupName ( QString : : fromStdString ( mGroupId . toStdString ( ) ) , name ) ;
2014-05-04 22:59:06 +00:00
}
void GxsGroupFrameDialog : : markMsgAsRead ( )
{
2020-06-23 21:37:36 +02:00
GxsMessageFrameWidget * msgWidget = messageWidget ( mGroupId ) ;
2014-05-04 22:59:06 +00:00
if ( msgWidget ) {
msgWidget - > setAllMessagesRead ( true ) ;
}
}
void GxsGroupFrameDialog : : markMsgAsUnread ( )
{
2020-06-23 21:37:36 +02:00
GxsMessageFrameWidget * msgWidget = messageWidget ( mGroupId ) ;
2014-05-04 22:59:06 +00:00
if ( msgWidget ) {
msgWidget - > setAllMessagesRead ( false ) ;
}
}
2016-06-16 22:23:27 -04:00
void GxsGroupFrameDialog : : sharePublishKey ( )
2014-05-04 22:59:06 +00:00
{
if ( mGroupId . isNull ( ) ) {
return ;
}
2014-10-05 19:14:05 +00:00
// QMessageBox::warning(this, "", "ToDo");
2014-07-26 21:18:03 +00:00
2014-10-13 18:31:47 +00:00
GroupShareKey shareUi ( this , mGroupId , shareKeyType ( ) ) ;
2014-10-05 19:14:05 +00:00
shareUi . exec ( ) ;
2014-05-04 22:59:06 +00:00
}
2017-05-18 22:31:52 +02:00
void GxsGroupFrameDialog : : loadComment ( const RsGxsGroupId & grpId , const QVector < RsGxsMessageId > & msg_versions , const RsGxsMessageId & most_recent_msgId , const QString & title )
2014-05-08 00:00:21 +00:00
{
RsGxsCommentService * commentService = getCommentService ( ) ;
if ( ! commentService ) {
/* No comment service available */
return ;
}
2017-05-18 22:31:52 +02:00
GxsCommentDialog * commentDialog = commentWidget ( most_recent_msgId ) ;
2014-05-08 00:00:21 +00:00
if ( ! commentDialog ) {
QString comments = title ;
if ( title . length ( ) > MAX_COMMENT_TITLE )
{
comments . truncate ( MAX_COMMENT_TITLE - 3 ) ;
comments + = " ... " ;
}
2020-10-01 21:25:32 +02:00
commentDialog = new GxsCommentDialog ( this , RsGxsId ( ) , mInterface - > getTokenService ( ) , commentService ) ;
2014-05-08 00:00:21 +00:00
2017-05-18 22:31:52 +02:00
QWidget * commentHeader = createCommentHeaderWidget ( grpId , most_recent_msgId ) ;
2014-05-08 00:00:21 +00:00
if ( commentHeader ) {
commentDialog - > setCommentHeader ( commentHeader ) ;
}
2017-05-18 22:31:52 +02:00
std : : set < RsGxsMessageId > msgv ;
for ( int i = 0 ; i < msg_versions . size ( ) ; + + i )
msgv . insert ( msg_versions [ i ] ) ;
commentDialog - > commentLoad ( grpId , msgv , most_recent_msgId ) ;
2014-05-08 00:00:21 +00:00
int index = ui - > messageTabWidget - > addTab ( commentDialog , comments ) ;
2020-08-15 22:17:52 +02:00
ui - > messageTabWidget - > setTabIcon ( index , FilesDefs : : getIconFromQtResourcePath ( IMAGE_COMMENT ) ) ;
2014-05-08 00:00:21 +00:00
}
ui - > messageTabWidget - > setCurrentWidget ( commentDialog ) ;
}
2014-10-25 15:50:00 +00:00
bool GxsGroupFrameDialog : : navigate ( const RsGxsGroupId & groupId , const RsGxsMessageId & msgId )
2014-05-04 22:59:06 +00:00
{
if ( groupId . isNull ( ) ) {
return false ;
}
2014-10-25 15:50:00 +00:00
if ( mStateHelper - > isLoading ( TOKEN_TYPE_GROUP_SUMMARY ) ) {
mNavigatePendingGroupId = groupId ;
mNavigatePendingMsgId = msgId ;
/* No information if group is available */
return true ;
}
QString groupIdString = QString : : fromStdString ( groupId . toStdString ( ) ) ;
if ( ui - > groupTreeWidget - > activateId ( groupIdString , msgId . isNull ( ) ) = = NULL ) {
2014-05-04 22:59:06 +00:00
return false ;
2014-10-25 15:50:00 +00:00
}
2018-06-21 09:26:03 +02:00
changedCurrentGroup ( groupIdString ) ;
2014-10-25 15:50:00 +00:00
/* search exisiting tab */
2020-06-23 21:37:36 +02:00
GxsMessageFrameWidget * msgWidget = messageWidget ( mGroupId ) ;
2014-10-25 15:50:00 +00:00
if ( ! msgWidget ) {
return false ;
}
2014-05-04 22:59:06 +00:00
2014-10-25 15:50:00 +00:00
if ( msgId . isNull ( ) ) {
return true ;
}
2014-05-04 22:59:06 +00:00
2014-10-25 23:52:33 +00:00
return msgWidget - > navigate ( msgId ) ;
2014-05-04 22:59:06 +00:00
}
2020-06-23 21:37:36 +02:00
GxsMessageFrameWidget * GxsGroupFrameDialog : : messageWidget ( const RsGxsGroupId & groupId )
2014-05-04 22:59:06 +00:00
{
int tabCount = ui - > messageTabWidget - > count ( ) ;
2020-06-23 21:37:36 +02:00
for ( int index = 0 ; index < tabCount ; + + index )
{
2014-05-04 22:59:06 +00:00
GxsMessageFrameWidget * childWidget = dynamic_cast < GxsMessageFrameWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
2020-06-23 21:37:36 +02:00
if ( childWidget & & childWidget - > groupId ( ) = = groupId )
2014-05-04 22:59:06 +00:00
return childWidget ;
}
return NULL ;
}
GxsMessageFrameWidget * GxsGroupFrameDialog : : createMessageWidget ( const RsGxsGroupId & groupId )
{
GxsMessageFrameWidget * msgWidget = createMessageFrameWidget ( groupId ) ;
2020-06-23 21:37:36 +02:00
if ( ! msgWidget )
2014-05-04 22:59:06 +00:00
return NULL ;
int index = ui - > messageTabWidget - > addTab ( msgWidget , msgWidget - > groupName ( true ) ) ;
ui - > messageTabWidget - > setTabIcon ( index , msgWidget - > groupIcon ( ) ) ;
2014-05-08 00:00:21 +00:00
2014-05-04 22:59:06 +00:00
connect ( msgWidget , SIGNAL ( groupChanged ( QWidget * ) ) , this , SLOT ( messageTabInfoChanged ( QWidget * ) ) ) ;
2015-03-14 21:13:28 +00:00
connect ( msgWidget , SIGNAL ( waitingChanged ( QWidget * ) ) , this , SLOT ( messageTabWaitingChanged ( QWidget * ) ) ) ;
2017-05-18 22:31:52 +02:00
connect ( msgWidget , SIGNAL ( loadComment ( RsGxsGroupId , QVector < RsGxsMessageId > , RsGxsMessageId , QString ) ) , this , SLOT ( loadComment ( RsGxsGroupId , QVector < RsGxsMessageId > , RsGxsMessageId , QString ) ) ) ;
2014-05-04 22:59:06 +00:00
return msgWidget ;
}
2017-05-18 22:31:52 +02:00
GxsCommentDialog * GxsGroupFrameDialog : : commentWidget ( const RsGxsMessageId & msgId )
2014-05-08 00:00:21 +00:00
{
int tabCount = ui - > messageTabWidget - > count ( ) ;
for ( int index = 0 ; index < tabCount ; + + index ) {
GxsCommentDialog * childWidget = dynamic_cast < GxsCommentDialog * > ( ui - > messageTabWidget - > widget ( index ) ) ;
if ( childWidget & & childWidget - > messageId ( ) = = msgId ) {
return childWidget ;
}
}
return NULL ;
}
2020-06-22 23:52:59 +02:00
void GxsGroupFrameDialog : : changedCurrentGroup ( const QString & groupId )
2014-05-04 22:59:06 +00:00
{
2015-08-26 14:51:34 +02:00
if ( mInFill ) {
return ;
}
2020-06-23 21:37:36 +02:00
if ( groupId . isEmpty ( ) )
{
auto w = currentWidget ( ) ;
if ( w )
w - > setGroupId ( RsGxsGroupId ( ) ) ;
2018-02-18 23:12:59 +01:00
return ;
}
2014-05-04 22:59:06 +00:00
mGroupId = RsGxsGroupId ( groupId . toStdString ( ) ) ;
2020-06-23 21:37:36 +02:00
if ( mGroupId . isNull ( ) )
2014-05-04 22:59:06 +00:00
return ;
/* search exisiting tab */
2020-06-23 21:37:36 +02:00
GxsMessageFrameWidget * msgWidget = messageWidget ( mGroupId ) ;
2014-05-04 22:59:06 +00:00
2020-06-23 20:24:14 +02:00
// check that we have at least one tab
2020-06-23 21:37:36 +02:00
if ( msgWidget )
2020-06-23 20:24:14 +02:00
ui - > messageTabWidget - > setCurrentWidget ( msgWidget ) ;
else
2020-06-22 23:52:59 +02:00
{
2020-06-23 21:37:36 +02:00
if ( useTabs ( ) | | ui - > messageTabWidget - > count ( ) = = 0 )
{
msgWidget = createMessageWidget ( RsGxsGroupId ( groupId . toStdString ( ) ) ) ;
ui - > messageTabWidget - > setCurrentWidget ( msgWidget ) ;
2014-05-04 22:59:06 +00:00
}
2020-06-23 21:37:36 +02:00
else
currentWidget ( ) - > setGroupId ( mGroupId ) ;
2014-05-04 22:59:06 +00:00
}
}
void GxsGroupFrameDialog : : groupTreeMiddleButtonClicked ( QTreeWidgetItem * item )
{
openGroupInNewTab ( RsGxsGroupId ( ui - > groupTreeWidget - > itemId ( item ) . toStdString ( ) ) ) ;
}
void GxsGroupFrameDialog : : openInNewTab ( )
{
openGroupInNewTab ( mGroupId ) ;
}
void GxsGroupFrameDialog : : openGroupInNewTab ( const RsGxsGroupId & groupId )
{
if ( groupId . isNull ( ) ) {
return ;
}
/* search exisiting tab */
2020-06-23 22:00:14 +02:00
GxsMessageFrameWidget * msgWidget = createMessageWidget ( groupId ) ;
2014-05-04 22:59:06 +00:00
ui - > messageTabWidget - > setCurrentWidget ( msgWidget ) ;
}
void GxsGroupFrameDialog : : messageTabCloseRequested ( int index )
{
2020-06-23 20:24:14 +02:00
if ( ui - > messageTabWidget - > count ( ) = = 1 ) /* Don't close single tab */
2014-05-04 22:59:06 +00:00
return ;
2020-06-23 20:24:14 +02:00
GxsMessageFrameWidget * msgWidget = dynamic_cast < GxsMessageFrameWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
delete msgWidget ;
}
2014-05-04 22:59:06 +00:00
2020-06-23 20:24:14 +02:00
GxsMessageFrameWidget * GxsGroupFrameDialog : : currentWidget ( ) const
{
return dynamic_cast < GxsMessageFrameWidget * > ( ui - > messageTabWidget - > widget ( ui - > messageTabWidget - > currentIndex ( ) ) ) ;
2014-05-04 22:59:06 +00:00
}
void GxsGroupFrameDialog : : messageTabChanged ( int index )
{
GxsMessageFrameWidget * msgWidget = dynamic_cast < GxsMessageFrameWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
2020-06-23 21:37:36 +02:00
if ( ! msgWidget )
2014-05-04 22:59:06 +00:00
return ;
ui - > groupTreeWidget - > activateId ( QString : : fromStdString ( msgWidget - > groupId ( ) . toStdString ( ) ) , false ) ;
}
void GxsGroupFrameDialog : : messageTabInfoChanged ( QWidget * widget )
{
int index = ui - > messageTabWidget - > indexOf ( widget ) ;
if ( index < 0 ) {
return ;
}
GxsMessageFrameWidget * msgWidget = dynamic_cast < GxsMessageFrameWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
if ( ! msgWidget ) {
return ;
}
ui - > messageTabWidget - > setTabText ( index , msgWidget - > groupName ( true ) ) ;
ui - > messageTabWidget - > setTabIcon ( index , msgWidget - > groupIcon ( ) ) ;
}
2015-03-14 21:13:28 +00:00
void GxsGroupFrameDialog : : messageTabWaitingChanged ( QWidget * widget )
{
int index = ui - > messageTabWidget - > indexOf ( widget ) ;
if ( index < 0 ) {
return ;
}
GxsMessageFrameWidget * msgWidget = dynamic_cast < GxsMessageFrameWidget * > ( ui - > messageTabWidget - > widget ( index ) ) ;
if ( ! msgWidget ) {
return ;
}
ui - > groupTreeWidget - > setWaiting ( QString : : fromStdString ( msgWidget - > groupId ( ) . toStdString ( ) ) , msgWidget - > isWaiting ( ) ) ;
}
2014-05-04 22:59:06 +00:00
///***** INSERT GROUP LISTS *****/
2020-03-21 15:25:34 +01:00
void GxsGroupFrameDialog : : groupInfoToGroupItemInfo ( const RsGxsGenericGroupData * groupInfo , GroupItemInfo & groupItemInfo )
2014-05-04 22:59:06 +00:00
{
2020-03-21 15:25:34 +01:00
groupItemInfo . id = QString : : fromStdString ( groupInfo - > mMeta . mGroupId . toStdString ( ) ) ;
groupItemInfo . name = QString : : fromUtf8 ( groupInfo - > mMeta . mGroupName . c_str ( ) ) ;
groupItemInfo . popularity = groupInfo - > mMeta . mPop ;
groupItemInfo . lastpost = QDateTime : : fromTime_t ( groupInfo - > mMeta . mLastPost ) ;
groupItemInfo . subscribeFlags = groupInfo - > mMeta . mSubscribeFlags ;
groupItemInfo . publishKey = IS_GROUP_PUBLISHER ( groupInfo - > mMeta . mSubscribeFlags ) ;
groupItemInfo . adminKey = IS_GROUP_ADMIN ( groupInfo - > mMeta . mSubscribeFlags ) ;
groupItemInfo . max_visible_posts = groupInfo - > mMeta . mVisibleMsgCount ;
2014-05-04 22:59:06 +00:00
# if TOGXS
if ( groupInfo . mGroupFlags & RS_DISTRIB_AUTHEN_REQ ) {
groupItemInfo . name + = " ( " + tr ( " AUTHD " ) + " ) " ;
2020-08-15 22:17:52 +02:00
groupItemInfo . icon = FilesDefs : : getIconFromQtResourcePath ( IMAGE_GROUPAUTHD ) ;
2014-05-04 22:59:06 +00:00
}
else
# endif
{
2020-08-15 22:17:52 +02:00
groupItemInfo . icon = FilesDefs : : getIconFromQtResourcePath ( icon ( ICON_DEFAULT ) ) ;
2014-05-04 22:59:06 +00:00
}
}
2020-03-21 15:25:34 +01:00
void GxsGroupFrameDialog : : insertGroupsData ( const std : : list < RsGxsGenericGroupData * > & groupList )
2014-05-04 22:59:06 +00:00
{
if ( ! mInitialized ) {
return ;
}
2015-08-26 14:51:34 +02:00
mInFill = true ;
2014-05-04 22:59:06 +00:00
QList < GroupItemInfo > adminList ;
QList < GroupItemInfo > subList ;
QList < GroupItemInfo > popList ;
QList < GroupItemInfo > otherList ;
std : : multimap < uint32_t , GroupItemInfo > popMap ;
2020-03-21 15:25:34 +01:00
for ( auto & g : groupList )
{
2014-05-04 22:59:06 +00:00
/* sort it into Publish (Own), Subscribed, Popular and Other */
2020-03-21 15:25:34 +01:00
uint32_t flags = g - > mMeta . mSubscribeFlags ;
2014-05-04 22:59:06 +00:00
GroupItemInfo groupItemInfo ;
2020-03-21 15:25:34 +01:00
groupInfoToGroupItemInfo ( g , groupItemInfo ) ;
2014-05-04 22:59:06 +00:00
if ( IS_GROUP_SUBSCRIBED ( flags ) )
{
if ( IS_GROUP_ADMIN ( flags ) )
adminList . push_back ( groupItemInfo ) ;
else
2020-03-21 15:25:34 +01:00
subList . push_back ( groupItemInfo ) ; /* subscribed group */
2014-05-04 22:59:06 +00:00
}
else
2020-03-21 17:44:58 +01:00
{
2020-03-21 15:25:34 +01:00
popMap . insert ( std : : make_pair ( g - > mMeta . mLastPost , groupItemInfo ) ) ; /* rate the others by time of last post */
2020-03-21 17:44:58 +01:00
}
2014-05-04 22:59:06 +00:00
}
/* iterate backwards through popMap - take the top 5 or 10% of list */
uint32_t popCount = 5 ;
if ( popCount < popMap . size ( ) / 10 )
popCount = popMap . size ( ) / 10 ;
uint32_t i = 0 ;
std : : multimap < uint32_t , GroupItemInfo > : : reverse_iterator rit ;
2020-03-21 15:25:34 +01:00
for ( rit = popMap . rbegin ( ) ; rit ! = popMap . rend ( ) ; + + rit , + + i )
2017-06-29 22:11:44 +02:00
if ( i < popCount )
2014-05-04 22:59:06 +00:00
popList . append ( rit - > second ) ;
2017-06-29 22:11:44 +02:00
else
otherList . append ( rit - > second ) ;
2014-05-04 22:59:06 +00:00
/* now we can add them in as a tree! */
ui - > groupTreeWidget - > fillGroupItems ( mYourGroups , adminList ) ;
2020-03-09 23:22:52 +01:00
mYourGroups - > setText ( 2 , QString : : number ( mYourGroups - > childCount ( ) ) ) ;
2014-05-04 22:59:06 +00:00
ui - > groupTreeWidget - > fillGroupItems ( mSubscribedGroups , subList ) ;
2017-03-21 16:52:40 +03:00
mSubscribedGroups - > setText ( 2 , QString : : number ( mSubscribedGroups - > childCount ( ) ) ) ; // 1 COLUMN_UNREAD 2 COLUMN_POPULARITY
2014-05-04 22:59:06 +00:00
ui - > groupTreeWidget - > fillGroupItems ( mPopularGroups , popList ) ;
2017-03-21 16:52:40 +03:00
mPopularGroups - > setText ( 2 , QString : : number ( mPopularGroups - > childCount ( ) ) ) ;
2014-05-04 22:59:06 +00:00
ui - > groupTreeWidget - > fillGroupItems ( mOtherGroups , otherList ) ;
2017-03-21 16:52:40 +03:00
mOtherGroups - > setText ( 2 , QString : : number ( mOtherGroups - > childCount ( ) ) ) ;
2014-05-04 22:59:06 +00:00
2015-08-26 14:51:34 +02:00
mInFill = false ;
2014-07-05 18:33:11 +00:00
/* Re-fill group */
2020-03-21 15:25:34 +01:00
if ( ! ui - > groupTreeWidget - > activateId ( QString : : fromStdString ( mGroupId . toStdString ( ) ) , true ) )
2014-07-05 18:33:11 +00:00
mGroupId . clear ( ) ;
2014-05-04 22:59:06 +00:00
updateMessageSummaryList ( RsGxsGroupId ( ) ) ;
}
void GxsGroupFrameDialog : : updateMessageSummaryList ( RsGxsGroupId groupId )
2020-04-06 21:55:07 +02:00
{
// groupId.isNull() means that we need to update all groups so we clear up the list of groups to update.
if ( ! groupId . isNull ( ) )
mGroupIdsSummaryToUpdate . insert ( groupId ) ;
else
mGroupIdsSummaryToUpdate . clear ( ) ;
mShouldUpdateMessageSummaryList = true ;
}
void GxsGroupFrameDialog : : updateMessageSummaryListReal ( RsGxsGroupId groupId )
2014-05-04 22:59:06 +00:00
{
if ( ! mInitialized ) {
return ;
}
2020-03-22 21:47:14 +01:00
if ( groupId . isNull ( ) )
{
2014-07-06 16:39:09 +00:00
QTreeWidgetItem * items [ 2 ] = { mYourGroups , mSubscribedGroups } ;
2014-10-21 22:33:02 +00:00
for ( int item = 0 ; item < 2 ; + + item ) {
2014-07-06 16:39:09 +00:00
int child ;
int childCount = items [ item ] - > childCount ( ) ;
2014-10-21 22:33:02 +00:00
for ( child = 0 ; child < childCount ; + + child ) {
2014-07-06 16:39:09 +00:00
QTreeWidgetItem * childItem = items [ item ] - > child ( child ) ;
QString childId = ui - > groupTreeWidget - > itemId ( childItem ) ;
2020-03-22 21:47:14 +01:00
if ( childId . isEmpty ( ) )
2014-07-06 16:39:09 +00:00
continue ;
2020-03-22 21:47:14 +01:00
updateGroupStatistics ( RsGxsGroupId ( childId . toLatin1 ( ) . constData ( ) ) ) ;
2014-05-04 22:59:06 +00:00
}
}
}
2020-03-22 21:47:14 +01:00
else
updateGroupStatistics ( groupId ) ;
2014-05-04 22:59:06 +00:00
}
/*********************** **** **** **** ***********************/
/** Request / Response of Data ********************************/
/*********************** **** **** **** ***********************/
2020-03-21 15:25:34 +01:00
void GxsGroupFrameDialog : : updateGroupSummary ( )
{
RsThread : : async ( [ this ] ( )
{
2020-06-25 21:15:37 +02:00
auto groupInfo = new std : : list < RsGxsGenericGroupData * > ( ) ;
2020-03-21 15:25:34 +01:00
2020-06-25 21:15:37 +02:00
if ( ! getGroupData ( * groupInfo ) )
2020-03-21 15:25:34 +01:00
{
2020-06-25 21:15:37 +02:00
std : : cerr < < __PRETTY_FUNCTION__ < < " failed to collect group info. " < < std : : endl ;
delete groupInfo ;
2020-03-21 15:25:34 +01:00
return ;
}
2020-06-25 21:15:37 +02:00
if ( groupInfo - > empty ( ) )
{
std : : cerr < < __PRETTY_FUNCTION__ < < " no group info collected. " < < std : : endl ;
delete groupInfo ;
2020-03-26 23:19:34 +01:00
return ;
2020-06-25 21:15:37 +02:00
}
2020-03-21 15:25:34 +01:00
RsQThreadUtils : : postToObject ( [ this , groupInfo ] ( )
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread , for example to update the data model with new information
* after a blocking call to RetroShare API complete , note that
* Qt : : QueuedConnection is important !
*/
2020-06-25 21:15:37 +02:00
insertGroupsData ( * groupInfo ) ;
2020-03-21 15:25:34 +01:00
updateSearchResults ( ) ;
mStateHelper - > setLoading ( TOKEN_TYPE_GROUP_SUMMARY , false ) ;
if ( ! mNavigatePendingGroupId . isNull ( ) ) {
/* Navigate pending */
navigate ( mNavigatePendingGroupId , mNavigatePendingMsgId ) ;
mNavigatePendingGroupId . clear ( ) ;
mNavigatePendingMsgId . clear ( ) ;
}
2020-03-22 02:33:51 +01:00
2020-03-26 23:19:34 +01:00
// update the local cache in order to avoid re-asking the data when the UI wants it (this happens on ::show() for instance)
mCachedGroupMetas . clear ( ) ;
2020-03-22 02:33:51 +01:00
2020-03-21 15:25:34 +01:00
// now delete the data that is not used anymore
2020-06-25 21:15:37 +02:00
for ( auto & g : * groupInfo )
2020-03-26 23:19:34 +01:00
{
mCachedGroupMetas [ g - > mMeta . mGroupId ] = g - > mMeta ;
delete g ;
}
2020-03-21 15:25:34 +01:00
2020-06-25 21:15:37 +02:00
delete groupInfo ;
2020-03-21 15:25:34 +01:00
} , this ) ;
} ) ;
}
2014-05-04 22:59:06 +00:00
/*********************** **** **** **** ***********************/
/*********************** **** **** **** ***********************/
2020-03-22 21:47:14 +01:00
void GxsGroupFrameDialog : : updateGroupStatistics ( const RsGxsGroupId & groupId )
2020-04-11 20:52:35 +02:00
{
mGroupStatisticsToUpdate . insert ( groupId ) ;
mShouldUpdateGroupStatistics = true ;
}
void GxsGroupFrameDialog : : updateGroupStatisticsReal ( const RsGxsGroupId & groupId )
2014-07-06 16:39:09 +00:00
{
2020-03-22 21:47:14 +01:00
RsThread : : async ( [ this , groupId ] ( )
{
GxsGroupStatistic stats ;
if ( ! getGroupStatistics ( groupId , stats ) )
{
std : : cerr < < __PRETTY_FUNCTION__ < < " failed to collect group statistics for group " < < groupId < < std : : endl ;
return ;
}
2020-04-08 21:11:53 +02:00
RsQThreadUtils : : postToObject ( [ this , stats , groupId ] ( )
2020-03-22 21:47:14 +01:00
{
/* Here it goes any code you want to be executed on the Qt Gui
* thread , for example to update the data model with new information
* after a blocking call to RetroShare API complete , note that
* Qt : : QueuedConnection is important !
*/
QTreeWidgetItem * item = ui - > groupTreeWidget - > getItemFromId ( QString : : fromStdString ( stats . mGrpId . toStdString ( ) ) ) ;
if ( ! item )
return ;
ui - > groupTreeWidget - > setUnreadCount ( item , mCountChildMsgs ? ( stats . mNumThreadMsgsUnread + stats . mNumChildMsgsUnread ) : stats . mNumThreadMsgsUnread ) ;
2020-04-08 21:11:53 +02:00
mCachedGroupStats [ groupId ] = stats ;
2020-03-22 21:47:14 +01:00
getUserNotify ( ) - > updateIcon ( ) ;
} , this ) ;
} ) ;
2014-07-06 16:39:09 +00:00
}
2020-04-08 21:11:53 +02:00
void GxsGroupFrameDialog : : getServiceStatistics ( GxsServiceStatistic & stats ) const
{
stats = GxsServiceStatistic ( ) ; // clears everything
for ( auto it : mCachedGroupStats )
{
const GxsGroupStatistic & s ( it . second ) ;
stats . mNumMsgs + = s . mNumMsgs ;
stats . mNumGrps + = 1 ;
stats . mSizeOfMsgs + = s . mTotalSizeOfMsgs ;
stats . mNumThreadMsgsNew + = s . mNumThreadMsgsNew ;
stats . mNumThreadMsgsUnread + = s . mNumThreadMsgsUnread ;
stats . mNumChildMsgsNew + = s . mNumChildMsgsNew ;
stats . mNumChildMsgsUnread + = s . mNumChildMsgsUnread ;
}
}
2018-06-20 22:30:44 +02:00
TurtleRequestId GxsGroupFrameDialog : : distantSearch ( const QString & search_string ) // this should be overloaded in the child class
{
2018-06-21 13:48:57 +02:00
std : : cerr < < " Searching for \" " < < search_string . toStdString ( ) < < " \" . Function is not overloaded, so nothing will happen. " < < std : : endl ;
2018-06-20 22:30:44 +02:00
return 0 ;
}
void GxsGroupFrameDialog : : searchNetwork ( const QString & search_string )
{
2018-06-20 23:26:37 +02:00
if ( search_string . isNull ( ) )
return ;
2018-06-20 22:30:44 +02:00
uint32_t request_id = distantSearch ( search_string ) ;
if ( request_id = = 0 )
return ;
2020-08-15 22:17:52 +02:00
mSearchGroupsItems [ request_id ] = ui - > groupTreeWidget - > addSearchItem ( tr ( " Search for " ) + " \" " + search_string + " \" " , ( uint32_t ) request_id , FilesDefs : : getIconFromQtResourcePath ( icon ( ICON_SEARCH ) ) ) ;
2018-06-20 22:30:44 +02:00
}
2018-07-05 11:43:55 +02:00
void GxsGroupFrameDialog : : distantRequestGroupData ( )
{
QAction * action = dynamic_cast < QAction * > ( sender ( ) ) ;
if ( ! action )
return ;
RsGxsGroupId group_id ( action - > data ( ) . toString ( ) . toStdString ( ) ) ;
if ( group_id . isNull ( ) )
{
std : : cerr < < " Cannot retrieve group! Group id is null! " < < std : : endl ;
}
std : : cerr < < " Explicit request for group " < < group_id < < std : : endl ;
checkRequestGroup ( group_id ) ;
}