Merge branch 'master' into TheWire-rework-ui

This commit is contained in:
drbob 2020-06-02 22:33:33 +10:00
commit bcaef29d49
145 changed files with 4041 additions and 3647 deletions

View file

@ -27,6 +27,7 @@
#include "chat/ChatTabWidget.h"
#include "chat/CreateLobbyDialog.h"
#include "common/RSTreeWidgetItem.h"
#include "common/RSElidedItemDelegate.h"
#include "gui/RetroShareLink.h"
#include "gui/gxs/GxsIdDetails.h"
#include "gui/Identity/IdEditDialog.h"
@ -157,6 +158,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
ui.lobbyTreeWidget->setColumnHidden(COLUMN_USER_COUNT,true) ;
ui.lobbyTreeWidget->setColumnHidden(COLUMN_TOPIC,true) ;
ui.lobbyTreeWidget->setSortingEnabled(true) ;
ui.lobbyTreeWidget->setItemDelegateForColumn(COLUMN_NAME, new RSElidedItemDelegate());
float fact = QFontMetricsF(font()).height()/14.0f;
@ -386,6 +388,8 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
item->setData(COLUMN_DATA, ROLE_FLAGS, lobby_flags.toUInt32());
item->setData(COLUMN_DATA, ROLE_AUTOSUBSCRIBE, autoSubscribe);
//TODO (Phenom): Add qproperty for these text colors in stylesheets
// As palette is not updated by stylesheet
QColor color = treeWidget->palette().color(QPalette::Active, QPalette::Text);
if (!subscribed) {
@ -395,7 +399,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
}
for (int column = 0; column < COLUMN_COUNT; ++column) {
item->setTextColor(column, color);
item->setData(column, Qt::ForegroundRole, color);
}
QString tooltipstr = QObject::tr("Subject:")+" "+item->text(COLUMN_TOPIC)+"\n"
+QObject::tr("Participants:")+" "+QString::number(count)+"\n"
@ -407,7 +411,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ;
QColor foreground = QColor(0, 128, 0); // green
for (int column = 0; column < COLUMN_COUNT; ++column)
item->setTextColor(column, foreground);
item->setData(column, Qt::ForegroundRole, foreground);
}
item->setToolTip(0,tooltipstr) ;
}

View file

@ -415,9 +415,8 @@ void SearchDialog::download()
std::cout << *it << "-" << std::endl;
QColor foreground = textColorDownloading();
QBrush brush(foreground);
for (int i = 0; i < item->columnCount(); ++i)
item->setForeground(i, brush);
item->setData(i, Qt::ForegroundRole, foreground );
}
}
}
@ -1269,10 +1268,9 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
foreground = textColorHighSources();
}
QBrush brush(foreground);
for (int i = 0; i < item->columnCount(); ++i)
{
item->setForeground(i, brush);
item->setData(i, Qt::ForegroundRole, foreground);
}
}
@ -1355,10 +1353,9 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
}
if (setForeground) {
QBrush brush(foreground);
for (int i = 0; i < item->columnCount(); ++i)
{
item->setForeground(i, brush);
item->setData(i, Qt::ForegroundRole, foreground);
}
}

View file

@ -31,6 +31,7 @@ public:
TransferUserNotify(QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group);
virtual QString textInfo() const override { return tr("completed transfer(s)"); }
private:
virtual QIcon getIcon();

View file

@ -181,8 +181,9 @@ IdDialog::IdDialog(QWidget *parent) : MainPage(parent), ui(new Ui::IdDialog)
ui->treeWidget_membership->clear();
ui->treeWidget_membership->setItemDelegateForColumn(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,new GxsIdTreeItemDelegate());
mExternalOtherCircleItem = NULL ;
mExternalBelongingCircleItem = NULL ;
mExternalOtherCircleItem = NULL ;
mExternalBelongingCircleItem = NULL ;
mMyCircleItem = NULL ;
/* Setup UI helper */
mStateHelper = new UIStateHelper(this);
@ -437,12 +438,11 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
switch(e->mCircleEventType)
{
case RsGxsCircleEventCode::NEW_CIRCLE:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED:
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST:
case RsGxsCircleEventCode::NEW_CIRCLE:
case RsGxsCircleEventCode::CACHE_DATA_UPDATED:
updateCircles();
@ -598,6 +598,10 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true);
std::vector<bool> expanded_top_level_items;
std::set<RsGxsCircleId> expanded_circle_items;
saveExpandedCircleItems(expanded_top_level_items,expanded_circle_items);
#ifdef QT_BUG_CRASH_IN_TAKECHILD_WORKAROUND
// These 3 lines are normally not needed. But apparently a bug (in Qt ??) causes Qt to crash when takeChild() is called. If we remove everything from the
// tree widget before updating it, takeChild() is never called, but the all tree is filled again from scratch. This is less efficient obviously, and
@ -858,6 +862,7 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
else
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,FilesDefs::getIconFromQtResourcePath(IMAGE_UNKNOWN)) ;
}
restoreExpandedCircleItems(expanded_top_level_items,expanded_circle_items);
}
//static void mark_matching_tree(QTreeWidget *w, const std::set<RsGxsId>& members, int col)
@ -936,14 +941,26 @@ void IdDialog::revokeCircleMembership()
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
return;
if(circle_id.isNull())
{
RsErr() << __PRETTY_FUNCTION__ << " : got a null circle ID. Cannot revoke an identity from that circle!" << std::endl;
return ;
}
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
RsThread::async([circle_id,gxs_id_to_revoke]()
{
// 1 - get message data from p3GxsForums
if(gxs_id_to_revoke.isNull())
RsErr() << __PRETTY_FUNCTION__ << " : got a null ID. Cannot revoke it from circle " << circle_id << "!" << std::endl;
else
RsThread::async([circle_id,gxs_id_to_revoke]()
{
// 1 - get message data from p3GxsForums
rsGxsCircles->revokeIdsFromCircle(std::set<RsGxsId>( { gxs_id_to_revoke } ),circle_id);
});
std::set<RsGxsId> ids;
ids.insert(gxs_id_to_revoke);
rsGxsCircles->revokeIdsFromCircle(ids,circle_id);
});
}
void IdDialog::acceptCircleSubscription()
@ -1369,23 +1386,24 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
item->setData(RSID_COL_NICKNAME, Qt::UserRole, QString::fromStdString(data.mMeta.mGroupId.toStdString()));
item->setText(RSID_COL_KEYID, QString::fromStdString(data.mMeta.mGroupId.toStdString()));
if(isBanned)
{
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::red));
item->setForeground(RSID_COL_KEYID,QBrush(Qt::red));
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::red));
item->setForeground(RSID_COL_VOTES,QBrush(Qt::red));
}
else
{
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::black));
item->setForeground(RSID_COL_KEYID,QBrush(Qt::black));
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::black));
item->setForeground(RSID_COL_VOTES,QBrush(Qt::black));
}
if(isBanned)
{
//TODO (Phenom): Add qproperty for these text colors in stylesheets
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QColor(Qt::red));
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QColor(Qt::red));
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QColor(Qt::red));
item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QColor(Qt::red));
}
else
{
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QVariant());
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QVariant());
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QVariant());
item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QVariant());
}
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter);
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
item->setTextAlignment(RSID_COL_VOTES, Qt::AlignRight | Qt::AlignVCenter);
item->setData(
RSID_COL_VOTES,Qt::DecorationRole,
static_cast<uint32_t>(idd.mReputation.mOverallReputationLevel));
@ -1404,14 +1422,15 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
QString tooltip = tr("This identity is owned by you");
if(idd.mFlags & RS_IDENTITY_FLAGS_IS_DEPRECATED)
{
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::red));
item->setForeground(RSID_COL_KEYID,QBrush(Qt::red));
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::red));
if(idd.mFlags & RS_IDENTITY_FLAGS_IS_DEPRECATED)
{
//TODO (Phenom): Add qproperty for these text colors in stylesheets
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QColor(Qt::red));
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QColor(Qt::red));
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QColor(Qt::red));
tooltip += tr("\nThis identity has a unsecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities will soon be not supported anymore.") ;
}
tooltip += tr("\nThis identity has a unsecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities will soon be not supported anymore.") ;
}
item->setToolTip(RSID_COL_NICKNAME, tooltip) ;
item->setToolTip(RSID_COL_KEYID, tooltip) ;
@ -2450,3 +2469,53 @@ void IdDialog::on_closeInfoFrameButton_clicked()
{
ui->inviteFrame->setVisible(false);
}
// We need to use indexes here because saving items is not possible since they can be re-created.
void IdDialog::saveExpandedCircleItems(std::vector<bool>& expanded_root_items, std::set<RsGxsCircleId>& expanded_circle_items) const
{
expanded_root_items.clear();
expanded_root_items.resize(3,false);
expanded_circle_items.clear();
auto saveTopLevel = [&](const QTreeWidgetItem* top_level_item,uint32_t index){
if(!top_level_item)
return;
if(top_level_item->isExpanded())
{
expanded_root_items[index] = true;
for(int row=0;row<top_level_item->childCount();++row)
if(top_level_item->child(row)->isExpanded())
expanded_circle_items.insert(RsGxsCircleId(top_level_item->child(row)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString()));
}
};
saveTopLevel(mExternalBelongingCircleItem,0);
saveTopLevel(mExternalOtherCircleItem,1);
saveTopLevel(mMyCircleItem,2);
}
void IdDialog::restoreExpandedCircleItems(const std::vector<bool>& expanded_root_items,const std::set<RsGxsCircleId>& expanded_circle_items)
{
auto restoreTopLevel = [=](QTreeWidgetItem* top_level_item,uint32_t index){
if(!top_level_item)
return;
top_level_item->setExpanded(expanded_root_items[index]);
for(int row=0;row<top_level_item->childCount();++row)
{
RsGxsCircleId circle_id(RsGxsCircleId(top_level_item->child(row)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString()));
bool expanded = expanded_circle_items.find(circle_id) != expanded_circle_items.end();
top_level_item->child(row)->setExpanded(expanded_circle_items.find(circle_id) != expanded_circle_items.end());
}
};
restoreTopLevel(mExternalBelongingCircleItem,0);
restoreTopLevel(mExternalOtherCircleItem,1);
restoreTopLevel(mMyCircleItem,2);
}

View file

@ -145,6 +145,9 @@ private:
QTreeWidgetItem *mMyCircleItem;
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
void saveExpandedCircleItems(std::vector<bool> &expanded_root_items, std::set<RsGxsCircleId>& expanded_circle_items) const;
void restoreExpandedCircleItems(const std::vector<bool>& expanded_root_items,const std::set<RsGxsCircleId>& expanded_circle_items);
std::map<uint32_t, CircleUpdateOrder> mCircleUpdates ;
RsGxsGroupId mId;

View file

@ -120,7 +120,7 @@
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<iconset resource="../icons.qrc">
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
</property>
<property name="checkable">
@ -268,7 +268,7 @@
</widget>
<widget class="QTabWidget" name="rightTabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="personTab">
<attribute name="icon">
@ -289,8 +289,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>634</width>
<height>523</height>
<width>1372</width>
<height>719</height>
</rect>
</property>
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
@ -1052,7 +1052,7 @@ border-image: url(:/images/closepressed.png)
</action>
<action name="chatIdentity">
<property name="icon">
<iconset resource="../images.qrc">
<iconset>
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
</property>
<property name="text">
@ -1094,8 +1094,8 @@ border-image: url(:/images/closepressed.png)
<tabstop>idTreeWidget</tabstop>
</tabstops>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -486,7 +486,7 @@ void MainWindow::initStackedPage()
for (notifyIt = notify.begin(); notifyIt != notify.end(); ++notifyIt) {
UserNotify *userNotify = notifyIt->first->getUserNotify();
if (userNotify) {
userNotify->initialize(ui->toolBarPage, notifyIt->second.first, notifyIt->second.second);
userNotify->initialize(ui->toolBarPage, notifyIt->second.first, notifyIt->second.second,userNotify->textInfo());
connect(userNotify, SIGNAL(countChanged()), this, SLOT(updateTrayCombine()));
userNotifyList.push_back(userNotify);
}

View file

@ -251,14 +251,20 @@ void NewsFeed::handleForumEvent(std::shared_ptr<const RsEvent> event)
switch(pe->mForumEventCode)
{
case RsForumEventCode::MODERATOR_LIST_CHANGED:
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_UPDATED_FORUM, pe->mForumGroupId,pe->mModeratorsAdded,pe->mModeratorsRemoved, false, true));
break;
case RsForumEventCode::UPDATED_FORUM:
case RsForumEventCode::NEW_FORUM:
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_FORUMNEWLIST, pe->mForumGroupId, false, true));
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, false, true));
break;
case RsForumEventCode::UPDATED_MESSAGE:
case RsForumEventCode::NEW_MESSAGE:
addFeedItem(new GxsForumMsgItem(this, NEWSFEED_FORUMNEWLIST, pe->mForumGroupId, pe->mForumMsgId, false, true));
addFeedItem(new GxsForumMsgItem(this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, pe->mForumMsgId, false, true));
break;
default: break;
}
}
@ -288,47 +294,120 @@ void NewsFeed::handleChannelEvent(std::shared_ptr<const RsEvent> event)
void NewsFeed::handleCircleEvent(std::shared_ptr<const RsEvent> event)
{
const RsGxsCircleEvent *pe = dynamic_cast<const RsGxsCircleEvent*>(event.get());
if(!pe)
return;
// Gives the backend a few secs to load the cache data while not blocking the UI. This is not so nice, but there's no proper
// other way to do that.
RsGxsCircleDetails details;
if(pe->mCircleId.isNull()) // probably an item for cache update
return ;
if(!rsGxsCircles->getCircleDetails(pe->mCircleId,details))
RsThread::async( [event,this]()
{
std::cerr << "(EE) Cannot get information about circle " << pe->mCircleId << ". Not in cache?" << std::endl;
return;
}
const RsGxsCircleEvent *pe = dynamic_cast<const RsGxsCircleEvent*>(event.get());
if(!pe)
return;
// Check if the circle is one of which we belong to. If so, then notify in the GUI about other members leaving/subscribing
if(pe->mCircleId.isNull()) // probably an item for cache update
return ;
if(details.mAmIAllowed || details.mAmIAdmin)
RsGxsCircleDetails details;
bool loaded = false;
for(int i=0;i<5 && !loaded;++i)
if(rsGxsCircles->getCircleDetails(pe->mCircleId,details))
{
std::cerr << "Cache item loaded for circle " << pe->mCircleId << std::endl;
loaded = true;
}
else
{
std::cerr << "Cache item for circle " << pe->mCircleId << " not loaded. Waiting " << i << "s" << std::endl;
rstime::rs_usleep(1000*1000);
}
if(!loaded)
{
std::cerr << "(EE) Cannot get information about circle " << pe->mCircleId << ". Not in cache?" << std::endl;
return;
}
if(!details.isGxsIdBased()) // not handled yet.
return;
// Check if the circle is one of which we belong to or we are an admin of.
// If so, then notify in the GUI about other members leaving/subscribing, according
// to the following rules. The names correspond to the RS_FEED_CIRCLE_* variables:
//
// Message-based notifications:
//
// +---------------------------+----------------------------+
// | Membership request | Membership cancellation |
// +-------------+-------------+-------------+--------------+
// | Admin | Not admin | Admin | Not admin |
// +--------------------+-------------+-------------+----------------------------+
// | in invitee list | MEMB_JOIN | MEMB_JOIN | MEMB_LEAVE | MEMB_LEAVE |
// +--------------------+-------------+-------------+-------------+--------------+
// |not in invitee list | MEMB_REQ | X | X | X |
// +--------------------+-------------+-------------+-------------+--------------+
//
// Note: in this case, the GxsId never belongs to you, since you dont need to handle
// notifications for actions you took yourself (leave/join a circle)
//
// GroupData-based notifications, the GxsId belongs to you:
//
// +---------------------------+----------------------------+
// | GxsId joins invitee list | GxsId leaves invitee list |
// +-------------+-------------+-------------+--------------+
// | Id is yours| Id is not | Id is yours | Id is not |
// +--------------------+-------------+-------------+-------------+--------------+
// | Has Member request | MEMB_ACCEPT | (MEMB_JOIN) | MEMB_REVOKED| (MEMB_LEAVE) |
// +--------------------+-------------+-------------+-------------+--------------+
// | No Member request | INVITE_REC | X | INVITE_REM | X |
// +--------------------+-------------+-------------+-------------+--------------+
//
// Note: In this case you're never an admin of the circle, since these notification
// would be a direct consequence of your own actions.
RsQThreadUtils::postToObject( [event,details,this]()
{
const RsGxsCircleEvent *pe = static_cast<const RsGxsCircleEvent*>(event.get());
switch(pe->mCircleEventType)
{
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST:
// only show membership requests if we're an admin of that circle
if(details.mAmIAdmin)
if(details.isIdInInviteeList(pe->mGxsId))
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true);
else if(details.mAmIAdmin)
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ),true);
break;
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN:
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true);
break;
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_LEAVE),true);
if(details.isIdInInviteeList(pe->mGxsId))
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_LEAVE),true);
break;
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE:
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVIT_REC),true);
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST:
if(rsIdentity->isOwnId(pe->mGxsId))
{
if(details.isIdRequestingMembership(pe->mGxsId))
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED),true);
else
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVITE_REC),true);
}
break;
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED:
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED),true);
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST:
if(rsIdentity->isOwnId(pe->mGxsId))
{
if(details.isIdRequestingMembership(pe->mGxsId))
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REVOKED),true);
else
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVITE_CANCELLED),true);
}
break;
default: break;
}
}
}, this ); }); // damn!
}
void NewsFeed::handleConnectionEvent(std::shared_ptr<const RsEvent> event)

View file

@ -31,8 +31,10 @@
const uint32_t NEWSFEED_PEERLIST = 0x0001;
const uint32_t NEWSFEED_FORUMNEWLIST = 0x0002;
const uint32_t NEWSFEED_FORUMMSGLIST = 0x0003;
const uint32_t NEWSFEED_NEW_FORUM = 0x0002;
const uint32_t NEWSFEED_NEW_FORUM_MSG = 0x0003;
const uint32_t NEWSFEED_UPDATED_FORUM = 0x000f;
const uint32_t NEWSFEED_CHANNELNEWLIST = 0x0004;
//const uint32_t NEWSFEED_CHANNELMSGLIST = 0x0005;
#if 0

View file

@ -271,25 +271,29 @@ void PeopleDialog::insertCircles(uint32_t token)
std::list<RsGroupMetaData> gSummaryList;
std::list<RsGroupMetaData>::iterator gsIt;
if (!rsGxsCircles->getGroupSummary(token,gSummaryList)) {
if (!rsGxsCircles->getGroupSummary(token,gSummaryList))
{
std::cerr << "PeopleDialog::insertExtCircles() Error getting GroupSummary";
std::cerr << std::endl;
return;
}//if (!rsGxsCircles->getGroupSummary(token,gSummaryList))
}
for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); ++gsIt) {
RsGroupMetaData gsItem = (*gsIt);
RsGxsCircleDetails details ;
if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(gsItem.mGroupId), details)){
if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(gsItem.mGroupId), details))
{
std::cerr << "(EE) Cannot get details for circle id " << gsItem.mGroupId << ". Circle item is not created!" << std::endl;
continue ;
}//if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(git->mGroupId), details))
}
if (details.mCircleType != GXS_CIRCLE_TYPE_EXTERNAL){
if (details.mCircleType != RsGxsCircleType::EXTERNAL)
{
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end()) {
if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
{
std::cerr << "PeopleDialog::insertExtCircles() add new Internal GroupId: " << gsItem.mGroupId;
std::cerr << " GroupName: " << gsItem.mGroupName;
std::cerr << std::endl;
@ -307,7 +311,9 @@ void PeopleDialog::insertCircles(uint32_t token)
QPixmap pixmap = gitem->getImage();
pictureFlowWidgetInternal->addSlide( pixmap );
_intListCir << gitem;
} else {//if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
}
else
{
std::cerr << "PeopleDialog::insertExtCircles() Update GroupId: " << gsItem.mGroupId;
std::cerr << " GroupName: " << gsItem.mGroupName;
std::cerr << std::endl;
@ -318,8 +324,10 @@ void PeopleDialog::insertCircles(uint32_t token)
//int index = _intListCir.indexOf(cirWidget);
//QPixmap pixmap = cirWidget->getImage();
//pictureFlowWidgetInternal->setSlide(index, pixmap);
}//if((item=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
} else {//if (!details.mIsExternal)
}
}
else
{
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
if((itFound=_ext_circles_widgets.find(gsItem.mGroupId)) == _ext_circles_widgets.end()) {
std::cerr << "PeopleDialog::insertExtCircles() add new GroupId: " << gsItem.mGroupId;
@ -339,7 +347,9 @@ void PeopleDialog::insertCircles(uint32_t token)
QPixmap pixmap = gitem->getImage();
pictureFlowWidgetExternal->addSlide( pixmap );
_extListCir << gitem;
} else {//if((itFound=_circles_widgets.find(gsItem.mGroupId)) == _circles_widgets.end())
}
else
{
std::cerr << "PeopleDialog::insertExtCircles() Update GroupId: " << gsItem.mGroupId;
std::cerr << " GroupName: " << gsItem.mGroupName;
std::cerr << std::endl;
@ -350,9 +360,9 @@ void PeopleDialog::insertCircles(uint32_t token)
//int index = _extListCir.indexOf(cirWidget);
//QPixmap pixmap = cirWidget->getImage();
//pictureFlowWidgetExternal->setSlide(index, pixmap);
}//if((item=_circles_items.find(gsItem.mGroupId)) == _circles_items.end())
}//else (!details.mIsExternal)
}//for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); ++gsIt)
}
}
}
}
void PeopleDialog::requestIdList()

View file

@ -167,8 +167,9 @@ void BasePostedItem::loadMessage()
std::vector<RsPostedPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
if(! rsPosted->getBoardContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments))
if(! rsPosted->getBoardContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments,votes))
{
RsErr() << "BasePostedItem::loadMessage() ERROR getting data" << std::endl;
mIsLoadingMessage = false;
@ -227,8 +228,9 @@ void BasePostedItem::loadComment()
std::vector<RsPostedPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
if(! rsPosted->getBoardContent( groupId(),msgIds,posts,comments))
if(! rsPosted->getBoardContent( groupId(),msgIds,posts,comments,votes))
{
RsErr() << "BasePostedItem::loadGroup() ERROR getting data" << std::endl;
mIsLoadingComment = false;

View file

@ -1033,8 +1033,9 @@ void PostedListWidget::getMsgData(const std::set<RsGxsMessageId>& msgIds,std::ve
{
std::vector<RsPostedPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
rsPosted->getBoardContent( groupId(),msgIds,posts,comments );
rsPosted->getBoardContent( groupId(),msgIds,posts,comments,votes );
psts.clear();
@ -1046,8 +1047,9 @@ void PostedListWidget::getAllMsgData(std::vector<RsGxsGenericMsgData*>& psts)
{
std::vector<RsPostedPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
rsPosted->getBoardAllContent( groupId(),posts,comments );
rsPosted->getBoardAllContent( groupId(),posts,comments,votes );
psts.clear();

View file

@ -21,6 +21,7 @@
#include "retroshare/rsposted.h"
#include "PostedUserNotify.h"
#include "gui/MainWindow.h"
#include "gui/common/FilesDefs.h"
PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
@ -37,12 +38,12 @@ bool PostedUserNotify::hasSetting(QString *name, QString *group)
QIcon PostedUserNotify::getIcon()
{
return QIcon(":/icons/png/posted.png");
return FilesDefs::getIconFromQtResourcePath(":/icons/png/posted.png");
}
QIcon PostedUserNotify::getMainIcon(bool hasNew)
{
return hasNew ? QIcon(":/icons/png/posted-notify.png") : QIcon(":/icons/png/posted.png");
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/posted-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/posted.png");
}
void PostedUserNotify::iconClicked()

View file

@ -31,6 +31,7 @@ public:
PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group);
virtual QString textInfo() const override { return tr("new board post(s)"); }
private:
virtual QIcon getIcon();

View file

@ -335,12 +335,13 @@ QString RetroshareDirModel::getAgeIndicatorString(const DirDetails &details) con
const QIcon& RetroshareDirModel::getFlagsIcon(FileStorageFlags flags)
{
static QIcon *static_icons[8] = {NULL};
if(static_icons[0] == NULL)
static_icons[0] = new QIcon();
int n=0;
if(flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) n += 1 ;
if(flags & DIR_FLAGS_ANONYMOUS_SEARCH ) n += 2 ;
if(flags & DIR_FLAGS_BROWSABLE ) n += 4 ;
n-= 1;
if(static_icons[n] == NULL)
{

View file

@ -250,21 +250,23 @@ void ShareManager::load()
listWidget->item(row,COLUMN_GROUPS)->setText(getGroupString(mDirInfos[row].parent_groups));
QFont font = listWidget->item(row,COLUMN_GROUPS)->font();
font.setBold(mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ;
listWidget->item(row,COLUMN_GROUPS)->setTextColor( (mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE)? (Qt::black):(Qt::lightGray)) ;
listWidget->item(row,COLUMN_GROUPS)->setFont(font);
//TODO (Phenom): Add qproperty for these text colors in stylesheets
// As palette is not updated by stylesheet
QFont font = listWidget->item(row,COLUMN_GROUPS)->font();
font.setBold(mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ;
listWidget->item(row,COLUMN_GROUPS)->setData(Qt::ForegroundRole, QColor((mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ? (Qt::black):(Qt::lightGray)) );
listWidget->item(row,COLUMN_GROUPS)->setFont(font);
if(QDir(QString::fromUtf8(mDirInfos[row].filename.c_str())).exists())
{
listWidget->item(row,COLUMN_PATH)->setTextColor(Qt::black);
if(QDir(QString::fromUtf8(mDirInfos[row].filename.c_str())).exists())
{
listWidget->item(row,COLUMN_PATH)->setData(Qt::ForegroundRole, QColor(Qt::black));
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Double click to change shared directory path")) ;
}
else
{
listWidget->item(row,COLUMN_PATH)->setTextColor(Qt::lightGray);
}
else
{
listWidget->item(row,COLUMN_PATH)->setData(Qt::ForegroundRole, QColor(Qt::lightGray));
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Directory does not exist! Double click to change shared directory path")) ;
}
}
}
listWidget->setColumnWidth(COLUMN_SHARE_FLAGS,132 * QFontMetricsF(font()).height()/14.0) ;

View file

@ -59,12 +59,14 @@
#define ROLE_SORT Qt::UserRole + 1
const static uint32_t timeToInactivity = 60 * 10; // in seconds
const static uint32_t timeToInactivity2 = 60 * 5; // in seconds
/** Default constructor */
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
: ChatDialog(parent, flags), lobbyId(lid), mWindowedSetted(false), mPCWindow(nullptr),
bullet_red_128(":/icons/bullet_red_128.png"), bullet_grey_128(":/icons/bullet_grey_128.png"),
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png")
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png"),
bullet_blue_128(":/icons/bullet_blue_128.png")
{
/* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this);
@ -614,10 +616,12 @@ void ChatLobbyDialog::updateParticipantsList()
else
widgetitem = dynamic_cast<GxsIdRSTreeWidgetItem*>(qlFoundParticipants.at(0));
//TODO (Phenom): Add qproperty for these text colors in stylesheets
// As palette is not updated by stylesheet
if (isParticipantMuted(it2->first)) {
widgetitem->setTextColor(COLUMN_NAME,QColor(255,0,0));
widgetitem->setData(COLUMN_NAME, Qt::ForegroundRole, QColor(255,0,0));
} else {
widgetitem->setTextColor(COLUMN_NAME,ui.participantsList->palette().color(QPalette::Active, QPalette::Text));
widgetitem->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
}
time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt();
@ -630,13 +634,15 @@ void ChatLobbyDialog::updateParticipantsList()
widgetitem->setIcon(COLUMN_ICON, bullet_red_128);
else if (tLastAct + timeToInactivity < now)
widgetitem->setIcon(COLUMN_ICON, bullet_grey_128);
else if (tLastAct + timeToInactivity2 < now)
widgetitem->setIcon(COLUMN_ICON, bullet_yellow_128);
else
widgetitem->setIcon(COLUMN_ICON, bullet_green_128);
RsGxsId gxs_id;
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, bullet_yellow_128);
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, bullet_blue_128);
widgetitem->updateBannedState();

View file

@ -134,7 +134,7 @@ private:
GxsIdChooser *ownIdChooser ;
//icons cache
QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128;
QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128, bullet_blue_128;
};
#endif

View file

@ -63,6 +63,7 @@ public:
QString textToNotify() { return _textToNotify.join("\n");}
void setTextCaseSensitive(bool value);
bool isTextCaseSensitive() {return _bTextCaseSensitive;}
virtual QString textInfo() const override { return tr("mention(s)"); }
signals:
void countChanged(ChatLobbyId id, unsigned int count);

View file

@ -41,6 +41,7 @@ public:
~ChatUserNotify();
virtual bool hasSetting(QString *name, QString *group);
virtual QString textInfo() const override { return tr("mention(s)"); }
private slots:
void chatMessageReceived(ChatMessage msg);

View file

@ -115,6 +115,7 @@ ChatWidget::ChatWidget(QWidget *parent)
//ui->sendButton->setFixedHeight(iconHeight);
ui->sendButton->setIconSize(iconSize);
ui->typingLabel->setMaximumHeight(QFontMetricsF(font()).height()*1.2);
ui->fontcolorButton->setIconSize(iconSize);
//Initialize search
iCharToStartSearch=Settings->getChatSearchCharToStartSearch();
@ -189,7 +190,7 @@ ChatWidget::ChatWidget(QWidget *parent)
ui->hashBox->setDropWidget(this);
ui->hashBox->setAutoHide(true);
QMenu *fontmenu = new QMenu(tr("Set text font & color"));
QMenu *fontmenu = new QMenu();
fontmenu->addAction(ui->actionChooseFont);
fontmenu->addAction(ui->actionChooseColor);
fontmenu->addAction(ui->actionResetFont);
@ -198,10 +199,10 @@ ChatWidget::ChatWidget(QWidget *parent)
#ifdef USE_CMARK
fontmenu->addAction(ui->actionSend_as_CommonMark);
#endif
ui->fontcolorButton->setMenu(fontmenu);
QMenu *menu = new QMenu();
menu->addAction(ui->actionMessageHistory);
menu->addMenu(fontmenu);
menu->addSeparator();
menu->addAction(ui->actionSaveChatHistory);
menu->addAction(ui->actionClearChatHistory);

View file

@ -455,13 +455,13 @@ border-image: url(:/images/closepressed.png)
</widget>
</item>
<item>
<widget class="QToolButton" name="notifyButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
<widget class="QToolButton" name="fontcolorButton">
<property name="toolTip">
<string>Set font &amp; color</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/chat-bubble-notify.png</normaloff>:/icons/png/chat-bubble-notify.png</iconset>
<normaloff>:/icons/png/font.png</normaloff>:/icons/png/font.png</iconset>
</property>
<property name="iconSize">
<size>
@ -469,6 +469,9 @@ border-image: url(:/images/closepressed.png)
<height>28</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
@ -769,6 +772,26 @@ border-image: url(:/images/closepressed.png)
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="notifyButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/chat-bubble-notify.png</normaloff>:/icons/png/chat-bubble-notify.png</iconset>
</property>
<property name="iconSize">
<size>
<width>28</width>
<height>28</height>
</size>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="pushtoolsButton">
<property name="focusPolicy">

View file

@ -239,7 +239,10 @@ bool ElidedLabel::paintElidedLine( QPainter* painter, QString plainText
*rectElision = mRectElision;
if(drawRoundedRect)
if (painter) painter->drawRoundedRect(mRectElision, 2 , 2);
if (painter) {
painter->setBrush(QBrush(Qt::transparent));
painter->drawRoundedRect(mRectElision, 2 , 2);
}
}
if (painter) painter->restore();

View file

@ -717,7 +717,7 @@ void FriendList::insertPeers()
groupItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
groupItem->setTextAlignment(COLUMN_NAME, Qt::AlignLeft | Qt::AlignVCenter);
groupItem->setIcon(COLUMN_NAME, QIcon(IMAGE_GROUP24));
groupItem->setForeground(COLUMN_NAME, QBrush(textColorGroup()));
groupItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorGroup());
/* used to find back the item */
QString strID = QString::fromStdString(groupInfo->id.toStdString());
@ -1110,8 +1110,8 @@ void FriendList::insertPeers()
for (int i = 0; i < columnCount; ++i) {
sslItem->setData(i, ROLE_SORT_STATE, peerState);
sslItem->setTextColor(i, sslColor);
sslItem->setFont(i, sslFont);
sslItem->setData(i, Qt::ForegroundRole, sslColor);
sslItem->setData(i, Qt::FontRole, sslFont);
}
}
@ -1222,8 +1222,8 @@ void FriendList::insertPeers()
for (int i = 0; i < columnCount; ++i) {
gpgItem->setData(i, ROLE_SORT_STATE, bestPeerState);
gpgItem->setTextColor(i, gpgColor);
gpgItem->setFont(i, gpgFont);
gpgItem->setData(i, Qt::ForegroundRole, gpgColor);
gpgItem->setData(i, Qt::FontRole, gpgFont);
}
if (openPeers.find(gpgId) != openPeers.end()) {

View file

@ -100,7 +100,7 @@ FriendSelectionDialog::FriendSelectionDialog(QWidget *parent,const QString& head
friends_widget->setModus(modus) ;
friends_widget->setShowType(show_type) ;
friends_widget->start() ;
friends_widget->setSelectedIds(pre_selected_id_type, pre_selected_ids, false);
friends_widget->setSelectedIdsFromString(pre_selected_id_type, pre_selected_ids, false);
QLayout *l = new QVBoxLayout ;
setLayout(l) ;

View file

@ -215,7 +215,7 @@ static void initSslItem(QTreeWidgetItem *item, const RsPeerDetails &detail, cons
}
if (state != (int) RS_STATUS_OFFLINE) {
item->setTextColor(COLUMN_NAME, textColorOnline);
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline);
}
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(state)));
@ -278,18 +278,35 @@ void FriendSelectionWidget::secured_fillList()
// get selected items
std::set<RsPeerId> sslIdsSelected;
if (mShowTypes & SHOW_SSL) {
if (mShowTypes & SHOW_SSL)
{
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
for(auto& s:mPreSelectedIds)
sslIdsSelected.insert(RsPeerId(s));
selectedIds<RsPeerId,IDTYPE_SSL>(sslIdsSelected,true);
}
std::set<RsNodeGroupId> groupIdsSelected;
if (mShowTypes & SHOW_GROUP) {
if (mShowTypes & SHOW_GROUP)
{
selectedIds<RsNodeGroupId,IDTYPE_GROUP>(groupIdsSelected,true);
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
for(auto& s:mPreSelectedIds)
groupIdsSelected.insert(RsNodeGroupId(s));
}
std::set<RsPgpId> gpgIdsSelected;
if (mShowTypes & (SHOW_GPG | SHOW_NON_FRIEND_GPG)) {
if (mShowTypes & (SHOW_GPG | SHOW_NON_FRIEND_GPG))
{
selectedIds<RsPgpId,IDTYPE_GPG>(gpgIdsSelected,true);
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
for(auto& s:mPreSelectedIds)
gpgIdsSelected.insert(RsPgpId(s));
}
std::set<RsGxsId> gxsIdsSelected;
@ -299,7 +316,8 @@ void FriendSelectionWidget::secured_fillList()
selectedIds<RsGxsId,IDTYPE_GXS>(gxsIdsSelected,true);
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
gxsIdsSelected = mPreSelectedGxsIds;
for(auto& s:mPreSelectedIds)
gxsIdsSelected.insert(RsGxsId(s));
}
std::set<RsGxsId> gxsIdsSelected2;
@ -434,7 +452,7 @@ void FriendSelectionWidget::secured_fillList()
}
if (state != (int) RS_STATUS_OFFLINE) {
gpgItem->setTextColor(COLUMN_NAME, textColorOnline());
gpgItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
}
gpgItem->setFlags(Qt::ItemIsUserCheckable | gpgItem->flags());
@ -571,7 +589,7 @@ void FriendSelectionWidget::secured_fillList()
QString name = QString::fromUtf8(detail.mNickname.c_str());
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
//gxsItem->setTextColor(COLUMN_NAME, textColorOnline());
//gxsItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
gxsItem->setIcon(COLUMN_NAME, identicon);
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
@ -625,7 +643,7 @@ void FriendSelectionWidget::secured_fillList()
QString name = QString::fromUtf8(detail.mNickname.c_str());
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
//gxsItem->setTextColor(COLUMN_NAME, textColorOnline());
//gxsItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
gxsItem->setIcon(COLUMN_NAME, identicon);
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
@ -678,7 +696,12 @@ void FriendSelectionWidget::updateDisplay(bool)
// This call is inlined so that there's no linking conflict with MinGW on Windows
template<> inline void FriendSelectionWidget::setSelectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(const std::set<RsGxsId>& ids, bool add)
{
mPreSelectedGxsIds = ids ;
if(!add)
mPreSelectedIds.clear();
for(auto& gxsId:ids)
mPreSelectedIds.insert(gxsId.toStdString());
loadIdentities();
}
@ -746,14 +769,12 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status)
case IDTYPE_GPG:
{
if (item->data(COLUMN_DATA, ROLE_ID).toString() == gpgId) {
QColor color;
if (status != (int) RS_STATUS_OFFLINE) {
color = textColorOnline();
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
} else {
color = ui->friendList->palette().color(QPalette::Text);
item->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
}
item->setTextColor(COLUMN_NAME, color);
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(gpgStatus)));
item->setData(COLUMN_NAME, ROLE_SORT_STATE, gpgStatus);
@ -765,14 +786,12 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status)
case IDTYPE_SSL:
{
if (item->data(COLUMN_DATA, ROLE_ID).toString() == peerId) {
QColor color;
if (status != (int) RS_STATUS_OFFLINE) {
color = textColorOnline();
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
} else {
color = ui->friendList->palette().color(QPalette::Text);
item->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
}
item->setTextColor(COLUMN_NAME, color);
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(status)));
item->setData(COLUMN_NAME, ROLE_SORT_STATE, status);
@ -981,7 +1000,7 @@ std::string FriendSelectionWidget::selectedId(IdType &idType)
return idFromItem(item);
}
void FriendSelectionWidget::selectedIds(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected)
void FriendSelectionWidget::selectedIds_internal(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected)
{
QTreeWidgetItemIterator itemIterator(ui->friendList);
QTreeWidgetItem *item;
@ -1055,11 +1074,21 @@ void FriendSelectionWidget::selectAll()
setSelected(mListModus, *itemIterator, true);
}
void FriendSelectionWidget::setSelectedIds(IdType idType, const std::set<std::string> &ids, bool add)
void FriendSelectionWidget::setSelectedIdsFromString(IdType type, const std::set<std::string>& ids, bool add)
{
setSelectedIds_internal(type,ids,add);
}
void FriendSelectionWidget::setSelectedIds_internal(IdType idType, const std::set<std::string> &ids, bool add)
{
mPreSelectedIds = ids;
// if items are already loaded, check them
QTreeWidgetItemIterator itemIterator(ui->friendList);
QTreeWidgetItem *item;
while ((item = *itemIterator) != NULL) {
while ((item = *itemIterator) != NULL)
{
++itemIterator;
std::string id = idFromItem(item);

View file

@ -85,10 +85,12 @@ public:
int selectedItemCount();
std::string selectedId(IdType &idType);
void setSelectedIdsFromString(IdType type,const std::set<std::string>& ids,bool add);
template<class ID_CLASS,FriendSelectionWidget::IdType TYPE> void selectedIds(std::set<ID_CLASS>& ids, bool onlyDirectSelected)
{
std::set<std::string> tmpids ;
selectedIds(TYPE, tmpids, onlyDirectSelected);
selectedIds_internal(TYPE, tmpids, onlyDirectSelected);
ids.clear() ;
for(std::set<std::string>::const_iterator it(tmpids.begin());it!=tmpids.end();++it)
ids.insert(ID_CLASS(*it)) ;
@ -98,7 +100,7 @@ public:
std::set<std::string> tmpids ;
for(typename std::set<ID_CLASS>::const_iterator it(ids.begin());it!=ids.end();++it)
tmpids.insert((*it).toStdString()) ;
setSelectedIds(TYPE, tmpids, add);
setSelectedIds_internal(TYPE, tmpids, add);
}
void itemsFromId(IdType idType, const std::string &id, QList<QTreeWidgetItem*> &items);
@ -145,8 +147,8 @@ private:
void fillList();
void secured_fillList();
void selectedIds(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected);
void setSelectedIds(IdType idType, const std::set<std::string> &ids, bool add);
void selectedIds_internal(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected);
void setSelectedIds_internal(IdType idType, const std::set<std::string> &ids, bool add);
private:
bool mStarted;
@ -170,7 +172,7 @@ private:
std::vector<RsGxsGroupId> gxsIds ;
QList<QAction*> mContextMenuActions;
std::set<RsGxsId> mPreSelectedGxsIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
std::set<std::string> mPreSelectedIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
};
Q_DECLARE_OPERATORS_FOR_FLAGS(FriendSelectionWidget::ShowTypes)

View file

@ -287,9 +287,6 @@ void GroupTreeWidget::initDisplayMenu(QToolButton *toolButton)
void GroupTreeWidget::updateColors()
{
QBrush brush;
QBrush standardBrush = ui->treeWidget->palette().color(QPalette::Text);
QTreeWidgetItemIterator itemIterator(ui->treeWidget);
QTreeWidgetItem *item;
while ((item = *itemIterator) != NULL) {
@ -297,12 +294,11 @@ void GroupTreeWidget::updateColors()
int color = item->data(COLUMN_DATA, ROLE_COLOR).toInt();
if (color >= 0) {
brush = QBrush(mTextColor[color]);
item->setData(COLUMN_NAME, Qt::TextColorRole, mTextColor[color]);
} else {
brush = standardBrush;
item->setData(COLUMN_NAME, Qt::TextColorRole, QVariant());
}
item->setForeground(COLUMN_NAME, brush);
}
}
@ -356,7 +352,7 @@ QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIc
int S = QFontMetricsF(font).height();
item->setSizeHint(COLUMN_NAME, QSize(S*1.9, S*1.9));
item->setForeground(COLUMN_NAME, QBrush(textColorCategory()));
item->setData(COLUMN_NAME, Qt::TextColorRole, textColorCategory());
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_CATEGORY);
item->setExpanded(expand);
@ -513,15 +509,14 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
item->setData(COLUMN_DATA, ROLE_SUBSCRIBE_FLAGS, itemInfo.subscribeFlags);
/* Set color */
QBrush brush;
if (itemInfo.publishKey) {
brush = QBrush(textColorPrivateKey());
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_PRIVATEKEY);
item->setData(COLUMN_NAME, Qt::ForegroundRole, QBrush(textColorPrivateKey()));
} else {
brush = ui->treeWidget->palette().color(QPalette::Text);
// Let StyleSheet color
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_STANDARD);
item->setData(COLUMN_NAME, Qt::BackgroundRole, QVariant());
}
item->setForeground(COLUMN_NAME, brush);
/* Calculate score */
calculateScore(item, filterText);

View file

@ -36,6 +36,36 @@
#include <cmath>
#include <chrono>
//#define DEBUG_EID_PAINT 1
/* To test it you can make an empty.qss file with:
QTreeView::item, QTreeWidget::item, QListWidget::item{
color: #AB0000;
background-color: #00DC00;
}
QTreeView::item:selected, QTreeWidget::item:selected, QListWidget::item:selected{
color: #00CD00;
background-color: #0000BA;
}
QTreeView::item:hover, QTreeWidget::item:hover, QListWidget::item:hover{
color: #0000EF;
background-color: #FEDCBA;
}
QQTreeView::item:selected:hover, TreeWidget::item:selected:hover, QListWidget::item:selected:hover{
color: #ABCDEF;
background-color: #FE0000;
}
ForumsDialog, GxsForumThreadWidget
{
qproperty-textColorRead: darkgray;
qproperty-textColorUnread: white;
qproperty-textColorUnreadChildren: red;
qproperty-textColorNotSubscribed: white;
qproperty-textColorMissing: darkred;
}
*/
RSElidedItemDelegate::RSElidedItemDelegate(QObject *parent)
: RSStyledItemDelegate(parent)
, mOnlyPlainText(false), mPaintRoundedRect(true)
@ -63,6 +93,18 @@ QSize RSElidedItemDelegate::sizeHint(const QStyleOptionViewItem &option, const Q
return contSize;
}
inline QColor getImagePixelColor(QImage img, int x, int y)
{
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
#ifdef DEBUG_EID_PAINT
// RsDbg() << " RSEID: Found Color " << img.pixelColor(x,y).name(QColor::HexArgb).toStdString() << " at " << x << "," << y << std::endl;
#endif
return img.pixelColor(x,y);
#else
return img.pixel(x,y);
#endif
}
void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(!index.isValid())
@ -71,15 +113,16 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
return ;
}
painter->save();
// To draw with default for debug purpose
//QStyledItemDelegate::paint(painter, option, index);
QStyleOptionViewItem ownOption (option);
initStyleOption(&ownOption, index);
//Prefer use icon from option
if (!option.icon.isNull())
ownOption.icon = option.icon;
#ifdef DEBUG_EID_PAINT
RsDbg() << __PRETTY_FUNCTION__ << std::endl << " RSEID: Enter for item with text:" << ownOption.text.toStdString() << std::endl;
#endif
const QWidget* widget = option.widget;
QStyle* ownStyle = widget ? widget->style() : QApplication::style();
@ -89,28 +132,180 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
td.setHtml(ownOption.text);
ownOption.text = td.toPlainText();
}
//Get Font as option.font is not accurate
// Get Font as option.font is not accurate
if (index.data(Qt::FontRole).type() == QVariant::Font) {
QFont font = index.data(Qt::FontRole).value<QFont>();
ownOption.font = font;
ownOption.fontMetrics = QFontMetrics(font);
#ifdef DEBUG_EID_PAINT
QFontInfo info(font);
RsDbg() << " RSEID: Found font in model:" << info.family().toStdString() << std::endl;
#endif
}
// Get Text color from model if one exists
QColor textColor;
if (index.data(Qt::TextColorRole).canConvert(QMetaType::QColor)) {
textColor = QColor(index.data(Qt::TextColorRole).toString());//Needs to pass from string else loose RBG format.
if (index.data(Qt::TextColorRole).isValid()) {
//textColor = QColor(index.data(Qt::TextColorRole).toString());//Needs to pass from string else loose RBG format.
textColor = index.data(Qt::TextColorRole).value<QColor>();
#ifdef DEBUG_EID_PAINT
RsDbg() << " RSEID: Found text color in model:" << textColor.name().toStdString() << std::endl;
#endif
}
if (index.data(Qt::BackgroundRole).canConvert(QMetaType::QBrush)) {
QBrush brush(index.data(Qt::BackgroundRole).convert(QMetaType::QBrush));
ownOption.backgroundBrush = brush;
// Get Brush from model if one exists
QBrush bgBrush;
bgBrush.setColor(QColor());// To get color().spec()==QColor::Invalid)
if (index.data(Qt::BackgroundRole).isValid()) {
bgBrush = index.data(Qt::BackgroundRole).value<QBrush>();
#ifdef DEBUG_EID_PAINT
RsDbg() << " RSEID: Found bg brush in model:" << bgBrush.color().name().toStdString() << std::endl;
#endif
}
//Code from: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html#2271
// If we get text and bg color from model, no need to retrieve it from base
if ( (bgBrush.color().spec()==QColor::Invalid) || (textColor.spec()!=QColor::Invalid) )
{
#ifdef DEBUG_EID_PAINT
RsDbg() << " RSEID:"
<< ((bgBrush.color().spec()==QColor::Invalid) ? " Brush not defined" : "")
<< ((textColor.spec()==QColor::Invalid) ? " Text Color not defined" : "")
<< " so get it from base image." << std::endl;
#endif
// QPalette is not updated by StyleSheet all occurs in internal class. (QRenderRule)
// https://code.woboq.org/qt5/qtbase/src/widgets/styles/qstylesheetstyle.cpp.html#4138
// void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p, const QWidget *w) const
// case CE_ItemViewItem:
// So we have to print it in Image to get colors by pixel
QSize moSize=sizeHint(option,index);
if (moSize.width() <= 20)
moSize.setWidth(20);
#ifdef DEBUG_EID_PAINT
RsDbg() << " RSEID: for item size = " << moSize.width() << "x" << moSize.height() << std::endl;
#endif
QImage moImg(moSize,QImage::Format_ARGB32);
QPainter moPnt;
moPnt.begin(&moImg);
moPnt.setCompositionMode (QPainter::CompositionMode_Source);
moPnt.fillRect(moImg.rect(), Qt::transparent);
moPnt.setCompositionMode (QPainter::CompositionMode_SourceOver);
QStyleOptionViewItem moOption (option);
// Define option to get only what we want
{
moOption.rect = QRect(QPoint(0,0),moSize);
moOption.state = ownOption.state;
moOption.text = " ████████████████";//Add a blank char to get BackGround Color at top left
// Remove unwanted info. Yes it can draw without that all public data ...
moOption.backgroundBrush = QBrush();
moOption.checkState = Qt::Unchecked;
moOption.decorationAlignment = Qt::AlignLeft;
moOption.decorationPosition = QStyleOptionViewItem::Left;
moOption.decorationSize = QSize();
moOption.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
moOption.features=0;
moOption.font = QFont();
moOption.icon = QIcon();
moOption.index = QModelIndex();
moOption.locale = QLocale();
moOption.showDecorationSelected = false;
moOption.textElideMode = Qt::ElideNone;
moOption.viewItemPosition = QStyleOptionViewItem::Middle;
//moOption.widget = nullptr; //Needed.
moOption.direction = Qt::LayoutDirectionAuto;
moOption.fontMetrics = QFontMetrics(QFont());
moOption.palette = QPalette();
moOption.styleObject = nullptr;
}
QStyledItemDelegate::paint(&moPnt, moOption, QModelIndex());
//// But these lines doesn't works.
{
//QStyleOptionViewItem moOptionsState;
//moOptionsState.initFrom(moOption.widget);
//moOptionsState.rect = QRect(QPoint(0,0),moSize);
//moOptionsState.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
//moOptionsState.text = "████████";
//moOptionsState.widget = option.widget;
//QStyledItemDelegate::paint(&moPnt, moOptionsState, QModelIndex());
}
moPnt.end();
#ifdef DEBUG_EID_PAINT
// To save what it paint in application path
moImg.save("image.png");
#endif
// Get Color in this rect.
{
QColor moColor;
QColor moBGColor=getImagePixelColor(moImg,1,1); // BackGround may be paint.
QColor moColorBorder;// To avoid Border pixel
int moWidth = moImg.size().width(), moHeight = moImg.size().height();
for (int x = 0; (x<moWidth) && (moColor.spec() == QColor::Invalid); x++)
for (int y = 0; (y<moHeight) && (moColor.spec() == QColor::Invalid); y++)
if (getImagePixelColor(moImg,x,y) != moBGColor)
{
if (getImagePixelColor(moImg,x,y) == moColorBorder)
moColor = getImagePixelColor(moImg,x,y);
else
{
if (moColorBorder.spec() == QColor::Invalid)
{
// First pixel border move inside
x+=5;
y+=5;
}
moColorBorder = getImagePixelColor(moImg,x,y);
}
}
// If not found color is same as BackGround.
if (moColor.spec() == QColor::Invalid)
moColor = moBGColor;
if (bgBrush.color().spec()==QColor::Invalid)
{
bgBrush = QBrush(moBGColor);
#ifdef DEBUG_EID_PAINT
RsDbg() << " RSEID: bg brush setted to " << moBGColor.name(QColor::HexArgb).toStdString() << std::endl;
#endif
}
if (textColor.spec()==QColor::Invalid)
{
textColor = moColor;
#ifdef DEBUG_EID_PAINT
RsDbg() << " RSEID: text color setted to " << moColor.name(QColor::HexArgb).toStdString() << std::endl;
#endif
}
}
}
painter->setPen(textColor);
painter->setBrush(bgBrush);
ownOption.backgroundBrush = bgBrush;
// Code from: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html#2271
QRect checkRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &ownOption, widget);
QRect iconRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemDecoration, &ownOption, widget);
QRect textRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemText, &ownOption, widget);
// draw the background
ownStyle->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);
// Draw the background
if (bgBrush.color().alpha() == 0)
// No BackGround Color found, use default delegate to draw it.
ownStyle->proxy()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);// This prefer draw StyleSheet bg than item one.
else
painter->fillRect(ownOption.rect,bgBrush);
#ifdef DEBUG_EID_PAINT
{
QStyleOptionViewItem tstOption = option;
// Reduce rect to get this item bg color external and base internal
tstOption.rect.adjust(3,3,-6,-6);
// To draw with base for debug purpose
QStyledItemDelegate::paint(painter, tstOption, index);
}
#endif
// draw the check mark
if (ownOption.features & QStyleOptionViewItem::HasCheckIndicator) {
QStyleOptionViewItem option(*&ownOption);
@ -165,130 +360,31 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
qreal add = 120*(time/(duration*1000.0))*std::abs(sin(qDegreesToRadians(angle/2)));
painter->setPen(QPen(QBrush(ownOption.palette.color(QPalette::Normal, QPalette::WindowText)),diag/10,Qt::DotLine,Qt::RoundCap));
painter->drawEllipse( iconRect.x()+iconRect.width() /2 + (diag/4)*cos(qDegreesToRadians(angle ))
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle )), 1, 1);
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle )), 1, 1);
painter->setPen(QPen(QBrush(ownOption.palette.color(QPalette::Normal, QPalette::Midlight)),diag/10,Qt::DotLine,Qt::RoundCap));
painter->drawEllipse( iconRect.x()+iconRect.width() /2 + (diag/4)*cos(qDegreesToRadians(angle- add))
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle- add)), 1, 1);
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle- add)), 1, 1);
painter->setPen(QPen(QBrush(ownOption.palette.color(QPalette::Normal, QPalette::Window)),diag/10,Qt::DotLine,Qt::RoundCap));
painter->drawEllipse( iconRect.x()+iconRect.width() /2 + (diag/4)*cos(qDegreesToRadians(angle-2*add))
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle-2*add)), 1, 1);
, iconRect.y()+iconRect.height()/2 + (diag/4)*sin(qDegreesToRadians(angle-2*add)), 1, 1);
}
}
}
// draw the text
if (!ownOption.text.isEmpty()) {
QPalette::ColorGroup cg = ownOption.state & QStyle::State_Enabled
? QPalette::Normal : QPalette::Disabled;
if (cg == QPalette::Normal && !(ownOption.state & QStyle::State_Active))
cg = QPalette::Inactive;
if (ownOption.state & QStyle::State_Selected) {
painter->setPen(ownOption.palette.color(cg, QPalette::HighlightedText));
} else {
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
if (ownOption.state & QStyle::State_MouseOver) {
//TODO: Manage to get palette with HOVER css pseudoclass
// For now this is hidden by Qt: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qstylesheetstyle.cpp.html#6103
// So we print default in image and get it's color...
QSize moSize=sizeHint(option,index);
QImage moImg(moSize,QImage::Format_ARGB32);
QPainter moPnt;
moPnt.begin(&moImg);
moPnt.setPen(Qt::black);//Fill Image with Black
moPnt.setBrush(Qt::black);
moPnt.drawRect(moImg.rect());
QStyleOptionViewItem moOption (option);
// Define option to get only what we want
{
moOption.rect = QRect(QPoint(0,0),moSize);
moOption.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
moOption.text = " ████████████████";//Add a blank char to get BackGround Color at top left
// Remove unwanted info. Yes it can draw without that all public data ...
moOption.backgroundBrush = QBrush();
moOption.checkState = Qt::Unchecked;
moOption.decorationAlignment = Qt::AlignLeft;
moOption.decorationPosition = QStyleOptionViewItem::Left;
moOption.decorationSize = QSize();
moOption.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
moOption.features=0;
moOption.font = QFont();
moOption.icon = QIcon();
moOption.index = QModelIndex();
moOption.locale = QLocale();
moOption.showDecorationSelected = false;
moOption.textElideMode = Qt::ElideNone;
moOption.viewItemPosition = QStyleOptionViewItem::Middle;
//moOption.widget = nullptr; //Needed.
moOption.direction = Qt::LayoutDirectionAuto;
moOption.fontMetrics = QFontMetrics(QFont());
moOption.palette = QPalette();
moOption.styleObject = nullptr;
}
QStyledItemDelegate::paint(&moPnt, moOption, QModelIndex());
//// But these lines doesn't works.
{
//QStyleOptionViewItem moOptionsState;
//moOptionsState.initFrom(moOption.widget);
//moOptionsState.rect = QRect(QPoint(0,0),moSize);
//moOptionsState.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
//moOptionsState.text = "████████";
//moOptionsState.widget = option.widget;
//QStyledItemDelegate::paint(&moPnt, moOptionsState, QModelIndex());
}
moPnt.end();
// To save what it paint
//moImg.save("image.bmp");
// Get Color in this black rect.
QColor moColor;
QColor moBGColor=moImg.pixelColor(1,1); //BackGround may be paint.
QColor moColorBorder;// To avoid Border pixel
int moWidth = moImg.size().width(), moHeight = moImg.size().height();
for (int x = 0; (x<moWidth) && (moColor.spec() == QColor::Invalid); x++)
for (int y = 0; (y<moHeight) && (moColor.spec() == QColor::Invalid); y++)
if (moImg.pixelColor(x,y) != moBGColor)
{
if (moImg.pixelColor(x,y) == moColorBorder)
moColor = QColor(moImg.pixelColor(x,y).name());
else
{
if (moColorBorder.spec() == QColor::Invalid)
{
// First pixel border move inside
x+=5;
y+=5;
}
moColorBorder = QColor(moImg.pixelColor(x,y).name());
}
}
// If not found color is same as BackGround.
if (moColor.spec() == QColor::Invalid)
moColor = moBGColor;
painter->setPen(moColor);
}
else
#ifdef DEBUG_EID_PAINT
// To draw text near base one.
ownOption.text = ownOption.text.prepend("__");
#endif
if (textColor.spec()==QColor::Invalid) {
painter->setPen(ownOption.palette.color(cg, QPalette::Text));
} else { //Only get color from index for unselected(as Qt does)
painter->setPen(textColor);
}
}
if (ownOption.state & QStyle::State_Editing) {
painter->setPen(ownOption.palette.color(cg, QPalette::Text));
painter->drawRect(textRect.adjusted(0, 0, -1, -1));
}
//d->viewItemDrawText(p, &ownOption, textRect);
QTextLayout textLayout(ownOption.text, painter->font());
QTextOption to = textLayout.textOption();
StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode()&QTextOption::WordWrap,mPaintRoundedRect);
}
painter->restore();
#ifdef DEBUG_EID_PAINT
RsDbg() << " RSEID: Finished" << std::endl;
#endif
}
bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)

View file

@ -537,8 +537,9 @@ bool RsCollectionDialog::addChild(QTreeWidgetItem* parent, const std::vector<Col
if (colFileInfo.filename_has_wrong_characters)
{
//TODO (Phenom): Add qproperty for these text colors in stylesheets
wrong_chars = true ;
item->setTextColor(COLUMN_FILE, QColor(255,80,120)) ;
item->setData(COLUMN_FILE, Qt::ForegroundRole, QColor(255,80,120)) ;
}
if (parentsFounds.empty()) {

View file

@ -88,11 +88,12 @@ void UserNotify::setNotifyEnabled(bool enabled, bool combined, bool blink)
Settings->endGroup();
}
void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem)
void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem,const QString& subtext)
{
mMainAction = mainAction;
if (mMainAction) {
mButtonText = mMainAction->text();
mButtonText2 = subtext;
if (mainToolBar) {
mMainToolButton = dynamic_cast<QToolButton*>(mainToolBar->widgetForAction(mMainAction));
}
@ -165,7 +166,18 @@ void UserNotify::update()
if (mMainAction) {
mMainAction->setIcon(getMainIcon(count > 0));
mMainAction->setText((count > 0) ? QString("%1 (%2)").arg(mButtonText).arg(count) : mButtonText);
if(count > 0)
{
if(!mButtonText2.isNull())
mMainAction->setToolTip(QString("%1 (%2 %3)").arg(mButtonText).arg(count).arg(mButtonText2));
else
mMainAction->setToolTip(QString("%1 (%2)").arg(mButtonText).arg(count));
mMainAction->setText(QString("%1 (%2)").arg(mButtonText).arg(count));
}
else
mMainAction->setText(mButtonText);
QFont font = mMainAction->font();
font.setBold(count > 0);

View file

@ -37,12 +37,17 @@ public:
UserNotify(QObject *parent = 0);
virtual ~UserNotify();
void initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem);
void initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem,const QString& subtext);
void createIcons(QMenu *notifyMenu);
QSystemTrayIcon* getTrayIcon(){ return mTrayIcon;}
QAction* getNotifyIcon(){ return mNotifyIcon;}
virtual bool hasSetting(QString */*name*/, QString */*group*/) { return false; }
// UserNotify is used to display tooltips when some services have no messages and so on, in the format of "Name (43242 new messages)"
// This method is used to pass the string that comes after the number.
virtual QString textInfo() const { return QString() ; }
bool notifyEnabled();
bool notifyCombined();
bool notifyBlink();
@ -82,6 +87,7 @@ private:
QAction *mNotifyIcon;
unsigned int mNewCount;
QString mButtonText;
QString mButtonText2;
bool mLastBlinking;
};

View file

@ -937,5 +937,7 @@
<file>emojione/1F1FF-1F1FC.png</file>
<file>emojione/flags.png</file>
<file>emojione/flags2.png</file>
<file>emojione/man-facepalming.png</file>
<file>emojione/woman-facepalming.png</file>
</qresource>
</RCC>

View file

@ -113,6 +113,8 @@
"emojione/people2.png"|":man_with_gua_pi_mao:":"emojione/1F472.png";
"emojione/people2.png"|":levitate:|:man_in_business_suit_levitating:":"emojione/1F574.png";
"emojione/people2.png"|":dancer:":"emojione/1F483.png";
"emojione/people2.png"|":man_facepalming:":"emojione/man-facepalming.png";
"emojione/people2.png"|":woman_facepalming:":"emojione/woman-facepalming.png";
"emojione/people2.png"|":bust_in_silhouette:":"emojione/1F464.png";
"emojione/people2.png"|":busts_in_silhouette:":"emojione/1F465.png";
"emojione/people2.png"|":family:":"emojione/1F46A.png";

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -141,7 +141,7 @@ GxsChannelPostItem::~GxsChannelPostItem()
bool GxsChannelPostItem::isUnread() const
{
return IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) ;
return IS_MSG_UNREAD(mPost.mMeta.mMsgStatus) ;
}
void GxsChannelPostItem::setup()
@ -319,8 +319,9 @@ void GxsChannelPostItem::loadMessage()
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
if(! rsGxsChannels->getChannelContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments))
if(! rsGxsChannels->getChannelContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments,votes))
{
RsErr() << "GxsGxsChannelGroupItem::loadGroup() ERROR getting data" << std::endl;
return;
@ -426,7 +427,7 @@ void GxsChannelPostItem::fill()
QString title;
float f = QFontMetricsF(font()).height()/14.0 ;
//float f = QFontMetricsF(font()).height()/14.0 ;
if(mPost.mThumbnail.mData != NULL)
{
@ -628,14 +629,21 @@ QString GxsChannelPostItem::messageName()
void GxsChannelPostItem::setReadStatus(bool isNew, bool isUnread)
{
if (isNew)
mPost.mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_NEW;
else
mPost.mMeta.mMsgStatus &= ~GXS_SERV::GXS_MSG_STATUS_GUI_NEW;
if (isUnread)
{
ui->readButton->setChecked(true);
mPost.mMeta.mMsgStatus |= GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
whileBlocking(ui->readButton)->setChecked(true);
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png"));
}
else
{
ui->readButton->setChecked(false);
mPost.mMeta.mMsgStatus &= ~GXS_SERV::GXS_MSG_STATUS_GUI_UNREAD;
whileBlocking(ui->readButton)->setChecked(false);
ui->readButton->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-read.png"));
}
@ -834,7 +842,7 @@ void GxsChannelPostItem::play()
}
}
void GxsChannelPostItem::readToggled(bool checked)
void GxsChannelPostItem::readToggled(bool /*checked*/)
{
if (mInFill) {
return;
@ -844,10 +852,9 @@ void GxsChannelPostItem::readToggled(bool checked)
RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId());
uint32_t token;
rsGxsChannels->setMessageReadStatus(token, msgPair, !checked);
rsGxsChannels->markRead(msgPair, isUnread());
setReadStatus(false, checked);
//setReadStatus(false, checked); // Updated by events
}
void GxsChannelPostItem::makeDownVote()

View file

@ -62,10 +62,13 @@ public:
QString getMsgLabel();
const std::list<SubFileItem *> &getFileItems() {return mFileItems; }
bool isUnread() const ;
const std::set<RsGxsMessageId>& olderVersions() const { return mPost.mOlderVersions; }
bool isLoaded() const {return mLoaded;};
bool isUnread() const ;
void setReadStatus(bool isNew, bool isUnread);
static uint64_t computeIdentifier(const RsGxsMessageId& msgid) { return hash64("GxsChannelPostItem " + msgid.toStdString()) ; }
const std::set<RsGxsMessageId>& olderVersions() const { return mPost.mOlderVersions; }
static uint64_t computeIdentifier(const RsGxsMessageId& msgid) { return hash64("GxsChannelPostItem " + msgid.toStdString()) ; }
protected:
//void init(const RsGxsMessageId& messageId,const std::set<RsGxsMessageId>& older_versions);
@ -112,7 +115,6 @@ private:
void setup();
void fill();
void fillExpandFrame();
void setReadStatus(bool isNew, bool isUnread);
private:
bool mInFill;

View file

@ -77,80 +77,101 @@ void GxsCircleItem::setup()
/* update circle information */
ui->membershipButton->setToolTip(tr("Grant membership request"));
ui->inviteeButton->setToolTip(tr("Revoke membership"));
connect(ui->membershipButton, SIGNAL(clicked()), this, SLOT(toggleCircleMembership()));
connect(ui->inviteeButton, SIGNAL(clicked()), this, SLOT(toggleCircleInvite()));
RsGxsCircleDetails circleDetails;
if (rsGxsCircles->getCircleDetails(mCircleId, circleDetails))
{
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()) + " (ID: " + QString::fromStdString(circleDetails.mCircleId.toStdString()) + ")");
// from here we can figure out if we already have requested membership or not
if (mType == RS_FEED_ITEM_CIRCLE_MEMB_REQ)
{
ui->titleLabel->setText(tr("You received a membership request for circle:"));
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
ui->gxsIdLabel->setText(idName);
ui->titleLabel->setText(tr("You received a membership request a circle you're administrating:"));
ui->iconLabel->setPixmap(pixmap);
ui->gxsIdLabel->setId(mGxsId);
if(circleDetails.mAmIAdmin)
{
ui->acceptButton->setToolTip(tr("Grant membership request"));
ui->revokeButton->setToolTip(tr("Revoke membership request"));
connect(ui->acceptButton, SIGNAL(clicked()), this, SLOT(grantCircleMembership()));
connect(ui->revokeButton, SIGNAL(clicked()), this, SLOT(revokeCircleMembership()));
}
else
{
ui->acceptButton->setEnabled(false);
ui->revokeButton->setEnabled(false);
}
ui->inviteeButton->setHidden(false);
ui->inviteeButton->setText(tr("Grant membership"));
ui->inviteeButton->setToolTip(tr("Grant membership to this circle, for this identity"));
ui->membershipButton->setHidden(true);
}
else if (mType == RS_FEED_ITEM_CIRCLE_INVIT_REC)
else if (mType == RS_FEED_ITEM_CIRCLE_INVITE_REC)
{
ui->titleLabel->setText(tr("You received an invitation for circle:"));
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
ui->gxsIdLabel->setText(idName);
ui->titleLabel->setText(tr("You received an invitation to join this circle:"));
ui->iconLabel->setPixmap(pixmap);
ui->gxsIdLabel->setId(mGxsId);
ui->acceptButton->setToolTip(tr("Accept invitation"));
connect(ui->acceptButton, SIGNAL(clicked()), this, SLOT(acceptCircleSubscription()));
ui->revokeButton->setHidden(true);
ui->membershipButton->setText(tr("Accept"));
ui->membershipButton->setToolTip(tr("Accept invitation"));
ui->membershipButton->setHidden(false);
connect(ui->membershipButton, SIGNAL(clicked()), this, SLOT(requestCircleSubscription()));
ui->inviteeButton->setHidden(true);
}
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_LEAVE)
{
ui->titleLabel->setText(idName + tr(" has left this circle you belong to."));
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
ui->gxsIdLabel->setText(idName);
ui->titleLabel->setText(idName + tr(" has left this circle."));
ui->iconLabel->setPixmap(pixmap);
ui->gxsIdLabel->setId(mGxsId);
ui->acceptButton->setHidden(true);
ui->revokeButton->setHidden(true);
ui->membershipButton->setHidden(true);
ui->inviteeButton->setHidden(true);
}
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_JOIN)
{
ui->titleLabel->setText(idName + tr(" has join this circle you also belong to."));
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
ui->gxsIdLabel->setText(idName);
ui->iconLabel->setPixmap(pixmap);
ui->gxsIdLabel->setId(mGxsId);
ui->acceptButton->setHidden(true);
ui->revokeButton->setHidden(true);
}
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED)
{
if(rsIdentity->isOwnId(mGxsId))
ui->titleLabel->setText(tr("Your identity %1 has been revoqued from this circle.").arg(idName));
if(circleDetails.mAmIAdmin)
{
ui->titleLabel->setText(idName + tr(" which you invited, has joined this circle you're administrating."));
ui->inviteeButton->setHidden(false);
ui->inviteeButton->setText(tr("Revoke membership"));
ui->inviteeButton->setToolTip(tr("Revoke membership for that identity"));
}
else
ui->titleLabel->setText(tr("Identity %1 has been revoqued from this circle you belong to.").arg(idName));
{
ui->inviteeButton->setHidden(true);
ui->titleLabel->setText(idName + tr(" has joined this circle."));
}
ui->nameLabel->setText(QString::fromUtf8(circleDetails.mCircleName.c_str()));
ui->gxsIdLabel->setText(idName);
ui->iconLabel->setPixmap(pixmap);
ui->gxsIdLabel->setId(mGxsId);
ui->acceptButton->setHidden(true);
ui->revokeButton->setHidden(true);
ui->membershipButton->setHidden(true);
}
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_REVOKED)
{
ui->titleLabel->setText(tr("Your identity %1 has been revoked from this circle.").arg(idName));
ui->iconLabel->setPixmap(pixmap);
ui->gxsIdLabel->setId(mGxsId);
ui->membershipButton->setHidden(false);
ui->membershipButton->setText(tr("Cancel membership request"));
ui->membershipButton->setToolTip(tr("Cancel your membership request from that circle"));
ui->inviteeButton->setHidden(true);
}
else if (mType == RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED)
{
ui->titleLabel->setText(tr("Your identity %1 as been accepted in this circle.").arg(idName));
ui->iconLabel->setPixmap(pixmap);
ui->gxsIdLabel->setId(mGxsId);
ui->membershipButton->setHidden(false);
ui->membershipButton->setText(tr("Cancel membership"));
ui->membershipButton->setToolTip(tr("Cancel your membership from that circle"));
ui->inviteeButton->setHidden(true);
}
}
else
{
@ -163,7 +184,7 @@ void GxsCircleItem::setup()
uint64_t GxsCircleItem::uniqueIdentifier() const
{
return hash_64bits("GxsCircle " + mCircleId.toStdString() + " " + mGxsId.toStdString() + " " + QString::number(mType).toStdString());
return hash_64bits("GxsCircle " + mCircleId.toStdString() + " " + mGxsId.toStdString());
}
/*********** SPECIFIC FUNCTIONS ***********************/
@ -176,25 +197,40 @@ void GxsCircleItem::showCircleDetails()
dlg.exec();
}
void GxsCircleItem::acceptCircleSubscription()
void GxsCircleItem::requestCircleSubscription()
{
if (rsGxsCircles->requestCircleMembership(mGxsId, mCircleId))
removeItem();
rsGxsCircles->requestCircleMembership(mGxsId, mCircleId);
}
void GxsCircleItem::grantCircleMembership()
void GxsCircleItem::toggleCircleMembership()
{
RsThread::async([this]()
{
rsGxsCircles->inviteIdsToCircle(std::set<RsGxsId>( { mGxsId } ),mCircleId);
});
if(!rsIdentity->isOwnId(mGxsId))
{
RsErr() << __PRETTY_FUNCTION__ << ": inconsistent call: identity " << mGxsId << " doesn't belong to you" << std::endl;
return;
}
if(mType == RS_FEED_ITEM_CIRCLE_INVITE_REC)
rsGxsCircles->requestCircleMembership(mGxsId,mCircleId);
else if(mType == RS_FEED_ITEM_CIRCLE_MEMB_REVOKED)
rsGxsCircles->cancelCircleMembership(mGxsId,mCircleId);
else
RsErr() << __PRETTY_FUNCTION__ << ": inconsistent call. mType is " << mType << std::endl;
}
void GxsCircleItem::revokeCircleMembership()
void GxsCircleItem::toggleCircleInvite()
{
RsThread::async([this]()
{
rsGxsCircles->revokeIdsFromCircle(std::set<RsGxsId>( { mGxsId } ),mCircleId);
});
if(mType == RS_FEED_ITEM_CIRCLE_MEMB_JOIN)
RsThread::async([this]()
{
rsGxsCircles->revokeIdsFromCircle(std::set<RsGxsId>( { mGxsId } ),mCircleId);
});
else if(mType == RS_FEED_ITEM_CIRCLE_MEMB_REQ)
RsThread::async([this]()
{
rsGxsCircles->inviteIdsToCircle(std::set<RsGxsId>( { mGxsId } ),mCircleId);
});
else
RsErr() << __PRETTY_FUNCTION__ << ": inconsistent call. mType is " << mType << std::endl;
}

View file

@ -65,9 +65,9 @@ protected:
private slots:
void showCircleDetails();
void acceptCircleSubscription();
void grantCircleMembership() ;
void revokeCircleMembership();
void requestCircleSubscription();
void toggleCircleMembership() ;
void toggleCircleInvite();
private:
void setup();

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>618</width>
<height>104</height>
<height>217</height>
</rect>
</property>
<layout class="QGridLayout" name="GxsCircleItemGLayout">
@ -104,8 +104,8 @@
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="logoLabel">
<property name="minimumSize">
<size>
@ -130,154 +130,8 @@
</property>
</widget>
</item>
<item row="1" column="1" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="forLabel">
<property name="text">
<string>for identity</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="iconLabel">
<property name="maximumSize">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="GxsIdLabel" name="gxsIdLabel">
<property name="text">
<string notr="true">name</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>358</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="acceptButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Accept</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/accepted16.png</normaloff>:/images/accepted16.png</iconset>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="revokeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Revoke</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/cancel.png</normaloff>:/images/cancel.png</iconset>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QPushButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Details</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/informations_24x24.png</normaloff>:/images/informations_24x24.png</iconset>
</property>
</widget>
</item>
<item row="2" column="4">
<spacer name="tollbarHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>285</width>
<height>18</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="5">
<widget class="QPushButton" name="clearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Remove Item</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/exit2.png</normaloff>:/icons/png/exit2.png</iconset>
</property>
</widget>
</item>
<item row="0" column="1" colspan="5">
<layout class="QHBoxLayout" name="nameHLayout">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="titleLabel">
<property name="sizePolicy">
@ -294,32 +148,193 @@
</font>
</property>
<property name="text">
<string notr="true">Circle</string>
<string notr="true">Circle msg</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="nameLabel">
<property name="text">
<string notr="true">name</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
<layout class="QHBoxLayout" name="nameHLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Circle name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="nameLabel">
<property name="text">
<string notr="true">name</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="nameHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="nameHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="forLabel">
<property name="text">
<string>Identity:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="iconLabel">
<property name="maximumSize">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="GxsIdLabel" name="gxsIdLabel">
<property name="text">
<string notr="true">name</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>358</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="membershipButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Accept</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/accepted16.png</normaloff>:/images/accepted16.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="inviteeButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string>Revoke</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/cancel.png</normaloff>:/images/cancel.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="expandButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Details</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/informations_24x24.png</normaloff>:/images/informations_24x24.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="tollbarHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>285</width>
<height>18</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="clearButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Remove Item</string>
</property>
<property name="icon">
<iconset resource="../icons.qrc">
<normaloff>:/icons/png/exit2.png</normaloff>:/icons/png/exit2.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
@ -336,8 +351,8 @@
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
<include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -20,6 +20,7 @@
#include "GxsForumGroupItem.h"
#include "ui_GxsForumGroupItem.h"
#include "gui/NewsFeed.h"
#include "FeedHolder.h"
#include "gui/RetroShareLink.h"
@ -37,6 +38,16 @@ GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, co
requestGroup();
}
GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const std::list<RsGxsId>& added_moderators,const std::list<RsGxsId>& removed_moderators,bool isHome, bool autoUpdate):
GxsGroupFeedItem(feedHolder, feedId, groupId, isHome, rsGxsForums, autoUpdate),
mAddedModerators(added_moderators),
mRemovedModerators(removed_moderators)
{
setup();
requestGroup();
}
GxsForumGroupItem::GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsForumGroup &group, bool isHome, bool autoUpdate) :
GxsGroupFeedItem(feedHolder, feedId, group.mMeta.mGroupId, isHome, rsGxsForums, autoUpdate)
{
@ -158,10 +169,62 @@ void GxsForumGroupItem::fill()
ui->subscribeButton->setEnabled(true);
}
// if (mIsNew)
// {
if(feedId() == NEWSFEED_UPDATED_FORUM)
{
if(!mAddedModerators.empty() || !mRemovedModerators.empty())
{
ui->titleLabel->setText(tr("Moderator list changed"));
ui->moderatorList_GB->show();
QString msg;
if(!mAddedModerators.empty())
{
msg += "<b>Added moderators:</b>" ;
msg += "<p>";
for(auto& gxsid: mAddedModerators)
{
RsIdentityDetails det;
if(rsIdentity->getIdDetails(gxsid,det))
msg += QString::fromUtf8(det.mNickname.c_str())+" ("+QString::fromStdString(gxsid.toStdString())+"), ";
else
msg += QString("[Unknown name]") + " ("+QString::fromStdString(gxsid.toStdString())+"), ";
}
msg.resize(msg.size()-2);
msg += "</p>";
}
if(!mRemovedModerators.empty())
{
msg += "<b>Removed moderators:</b>" ;
msg += "<p>";
for(auto& gxsid: mRemovedModerators)
{
RsIdentityDetails det;
if( rsIdentity->getIdDetails(gxsid,det))
msg += QString::fromUtf8(det.mNickname.c_str())+" ("+QString::fromStdString(gxsid.toStdString())+"), ";
else
msg += QString("[Unknown name]") + " ("+QString::fromStdString(gxsid.toStdString())+"), ";
}
msg.resize(msg.size()-2);
msg += "</p>";
}
ui->moderatorList_TE->setText(msg);
}
else
{
ui->moderatorList_GB->hide();
ui->titleLabel->setText(tr("Forum updated"));
ui->moderatorList_GB->hide();
}
}
else
{
ui->titleLabel->setText(tr("New Forum"));
// }
ui->moderatorList_GB->hide();
}
// else
// {
// ui->titleLabel->setText(tr("Updated Forum"));

View file

@ -37,6 +37,7 @@ class GxsForumGroupItem : public GxsGroupFeedItem
public:
/** Default Constructor */
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, bool isHome, bool autoUpdate);
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const std::list<RsGxsId>& added_moderators,const std::list<RsGxsId>& removed_moderators,bool isHome, bool autoUpdate);
GxsForumGroupItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsForumGroup &group, bool isHome, bool autoUpdate);
~GxsForumGroupItem();
@ -65,6 +66,9 @@ private:
/** Qt Designer generated object */
Ui::GxsForumGroupItem *ui;
std::list<RsGxsId> mAddedModerators;
std::list<RsGxsId> mRemovedModerators;
};
#endif

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>618</width>
<height>161</height>
<width>784</width>
<height>464</height>
</rect>
</property>
<layout class="QGridLayout">
@ -104,8 +104,8 @@
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<layout class="QGridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QLabel" name="forumlogo_label">
@ -280,7 +280,7 @@
</item>
</layout>
</item>
<item row="1" column="0">
<item>
<widget class="QFrame" name="expandFrame">
<layout class="QVBoxLayout">
<property name="spacing">
@ -334,6 +334,33 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="moderatorList_GB">
<property name="title">
<string>Moderator list</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTextEdit" name="moderatorList_TE"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>

View file

@ -29,6 +29,7 @@ class NewsFeedUserNotify : public UserNotify
{
Q_OBJECT
virtual QString textInfo() const override { return tr("logged event(s)"); }
public:
NewsFeedUserNotify(NewsFeed *newsFeed, QObject *parent = 0);

View file

@ -892,6 +892,10 @@ void GxsGroupDialog::getSelectedModerators(std::set<RsGxsId>& ids)
void GxsGroupDialog::setSelectedModerators(const std::set<RsGxsId>& ids)
{
ui.addAdmins_cb->setChecked(true);
ui.adminsList->show();
ui.filtercomboBox->show();
ui.adminsList->setSelectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(ids, false);
QString moderatorsListString ;

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>563</height>
<width>1231</width>
<height>967</height>
</rect>
</property>
<property name="windowTitle">
@ -223,14 +223,14 @@
<item>
<widget class="QRadioButton" name="publish_required">
<property name="text">
<string>Required</string>
<string>Re&amp;quired</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="publish_encrypt">
<property name="text">
<string>Encrypted Msgs</string>
<string>Encrypted &amp;Msgs</string>
</property>
</widget>
</item>
@ -856,7 +856,6 @@
</customwidgets>
<resources>
<include location="../icons.qrc"/>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -738,14 +738,15 @@ void CreateGxsChannelMsg::loadOriginalChannelPostInfo()
{
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
if( !rsGxsChannels->getChannelContent(mChannelId,std::set<RsGxsMessageId>({mOrigPostId}),posts,comments) || posts.size() != 1)
{
std::cerr << "Cannot get channel post data for channel " << mChannelId << " and post " << mOrigPostId << std::endl;
return;
}
if( !rsGxsChannels->getChannelContent(mChannelId,std::set<RsGxsMessageId>({mOrigPostId}),posts,comments,votes) || posts.size() != 1)
{
std::cerr << "Cannot get channel post data for channel " << mChannelId << " and post " << mOrigPostId << std::endl;
return;
}
RsQThreadUtils::postToObject( [posts,this]()
RsQThreadUtils::postToObject( [posts,this]()
{
/* 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

View file

@ -46,6 +46,8 @@
#define ROLE_FILE_HASH Qt::UserRole + 3
#define ROLE_MSG Qt::UserRole + 4
Q_DECLARE_METATYPE(Sha1CheckSum)
GxsChannelFilesWidget::GxsChannelFilesWidget(QWidget *parent) :
QWidget(parent), ui(new Ui::GxsChannelFilesWidget)
{

View file

@ -144,18 +144,24 @@ void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr<const RsEven
if(!e)
return;
switch(e->mChannelEventCode)
{
case RsChannelEventCode::UPDATED_CHANNEL:
case RsChannelEventCode::NEW_CHANNEL:
case RsChannelEventCode::UPDATED_MESSAGE:
case RsChannelEventCode::NEW_MESSAGE:
if(e->mChannelGroupId == groupId())
switch(e->mChannelEventCode)
{
case RsChannelEventCode::NEW_CHANNEL: // [[fallthrough]];
case RsChannelEventCode::UPDATED_CHANNEL: // [[fallthrough]];
case RsChannelEventCode::NEW_MESSAGE: // [[fallthrough]];
case RsChannelEventCode::UPDATED_MESSAGE:
if(e->mChannelGroupId == groupId())
updateDisplay(true);
break;
default:
break;
}
break;
case RsChannelEventCode::READ_STATUS_CHANGED:
if (FeedItem *feedItem = ui->feedWidget->findFeedItem(GxsChannelPostItem::computeIdentifier(e->mChannelMsgId)))
if (GxsChannelPostItem *channelPostItem = dynamic_cast<GxsChannelPostItem*>(feedItem))
channelPostItem->setReadStatus(false,!channelPostItem->isUnread());
//channelPostItem->setReadStatus(false,e->Don't get read status. Will be more easier and accurate);
break;
default:
break;
}
}
GxsChannelPostsWidget::~GxsChannelPostsWidget()
@ -694,7 +700,7 @@ void GxsChannelPostsWidget::insertChannelPosts(std::vector<RsGxsChannelPost>& po
break;
if (thread)
thread->emitAddPost(qVariantFromValue(*it), related, ++pos, count);
thread->emitAddPost(QVariant::fromValue(*it), related, ++pos, count);
else
createPostItem(*it, related);
}
@ -812,8 +818,9 @@ void GxsChannelPostsWidget::getMsgData(const std::set<RsGxsMessageId>& msgIds,st
{
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
rsGxsChannels->getChannelContent( groupId(),msgIds,posts,comments );
rsGxsChannels->getChannelContent( groupId(),msgIds,posts,comments,votes );
psts.clear();
@ -825,8 +832,9 @@ void GxsChannelPostsWidget::getAllMsgData(std::vector<RsGxsGenericMsgData*>& pst
{
std::vector<RsGxsChannelPost> posts;
std::vector<RsGxsComment> comments;
std::vector<RsGxsVote> votes;
rsGxsChannels->getChannelAllContent( groupId(),posts,comments );
rsGxsChannels->getChannelAllContent( groupId(),posts,comments,votes );
psts.clear();
@ -907,9 +915,9 @@ static void setAllMessagesReadCallback(FeedItem *feedItem, void *data)
}
GxsChannelPostsReadData *readData = (GxsChannelPostsReadData*) data;
bool is_not_new = !channelPostItem->isUnread() ;
bool isRead = !channelPostItem->isUnread() ;
if(is_not_new == readData->mRead)
if(channelPostItem->isLoaded() && (isRead == readData->mRead))
return ;
RsGxsGrpMsgIdPair msgPair = std::make_pair(channelPostItem->groupId(), channelPostItem->messageId());

View file

@ -21,6 +21,7 @@
#include "retroshare/rsgxschannels.h"
#include "GxsChannelUserNotify.h"
#include "gui/MainWindow.h"
#include "gui/common/FilesDefs.h"
GxsChannelUserNotify::GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
GxsUserNotify(ifaceImpl, g, parent)
@ -37,12 +38,12 @@ bool GxsChannelUserNotify::hasSetting(QString *name, QString *group)
QIcon GxsChannelUserNotify::getIcon()
{
return QIcon(":/icons/png/channel.png");
return FilesDefs::getIconFromQtResourcePath(":/icons/png/channel.png");
}
QIcon GxsChannelUserNotify::getMainIcon(bool hasNew)
{
return hasNew ? QIcon(":/icons/png/channels-notify.png") : QIcon(":/icons/png/channel.png");
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/channels-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/channel.png");
}
void GxsChannelUserNotify::iconClicked()

View file

@ -32,6 +32,7 @@ public:
GxsChannelUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group);
virtual QString textInfo() const override { return tr("new message(s)"); }
private:
virtual QIcon getIcon();

View file

@ -1225,7 +1225,7 @@ void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,boo
if(!i.isValid())
return ;
// no need to call preMods()/postMods() here because we'renot changing the model
// no need to call preMods()/postMods() here because we'renot changing the model
void *ref = i.internalPointer();
uint32_t entry = 0;
@ -1233,18 +1233,10 @@ void RsGxsForumModel::setMsgReadStatus(const QModelIndex& i,bool read_status,boo
if(!convertRefPointerToTabEntry(ref,entry) || entry >= mPosts.size())
return ;
bool has_unread_below,has_read_below;
recursSetMsgReadStatus(entry,read_status,with_children) ;
bool has_unread_below, has_read_below;
recursSetMsgReadStatus(entry,read_status,with_children) ;
recursUpdateReadStatusAndTimes(0,has_unread_below,has_read_below);
// Normally we should only update the parents up to the top of the tree, but it's complicated and the update here doesn't really cost,
// so we blindly update the whole widget.
if(mTreeMode == TREE_MODE_FLAT)
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
else
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(mPosts[0].mChildren.size(),COLUMN_THREAD_NB_COLUMNS-1,(void*)NULL));
}
void RsGxsForumModel::recursSetMsgReadStatus(ForumModelIndex i,bool read_status,bool with_children)
@ -1270,6 +1262,9 @@ void RsGxsForumModel::recursSetMsgReadStatus(ForumModelIndex i,bool read_status,
}
else
rsGxsForums->setMessageReadStatus(token,std::make_pair( mForumGroup.mMeta.mGroupId, mPosts[i].mMsgId ), read_status);
QModelIndex itemIndex = createIndex(i - 1, 0, &mPosts[i]);
emit dataChanged(itemIndex, itemIndex);
}
if(!with_children)

View file

@ -1165,16 +1165,14 @@ void GxsForumThreadWidget::insertMessageData(const RsGxsForumMsg &msg)
flags |= RSHTML_OPTIMIZEHTML_MASK;
QColor backgroundColor = ui->postText->palette().base().color();
qreal desiredContrast = Settings->valueFromGroup("Chat",
qreal desiredContrast = Settings->valueFromGroup("Forum",
"MinimumContrast", 4.5).toDouble();
int desiredMinimumFontSize = Settings->valueFromGroup("Chat",
int desiredMinimumFontSize = Settings->valueFromGroup("Forum",
"MinimumFontSize", 10).toInt();
QString extraTxt = RsHtml().formatText(ui->postText->document(),
QString::fromUtf8(msg.mMsg.c_str()), flags
#ifndef DEBUG_FORUMS \
, backgroundColor, desiredContrast, desiredMinimumFontSize
#endif
);
ui->postText->setHtml(extraTxt);
}

View file

@ -506,6 +506,11 @@
<verstretch>10</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>MS Sans Serif</family>
</font>
</property>
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>

View file

@ -19,6 +19,7 @@
*******************************************************************************/
#include "retroshare/rsgxsforums.h"
#include "gui/common/FilesDefs.h"
#include "GxsForumUserNotify.h"
#include "gui/MainWindow.h"
@ -38,12 +39,12 @@ bool GxsForumUserNotify::hasSetting(QString *name, QString *group)
QIcon GxsForumUserNotify::getIcon()
{
return QIcon(":/icons/png/forums.png");
return FilesDefs::getIconFromQtResourcePath(":/icons/png/forums.png");
}
QIcon GxsForumUserNotify::getMainIcon(bool hasNew)
{
return hasNew ? QIcon(":/icons/png/forums-notify.png") : QIcon(":/icons/png/forums.png");
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/forums-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/forums.png");
}
void GxsForumUserNotify::iconClicked()

View file

@ -31,6 +31,7 @@ public:
GxsForumUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group);
virtual QString textInfo() const override { return tr("new message(s)"); }
private:
virtual QIcon getIcon();

View file

@ -301,6 +301,7 @@
<file>icons/png/arrow-left.png</file>
<file>icons/png/next-unread.png</file>
<file>icons/mail/compose.png</file>
<file>icons/mail/downloadall.png</file>
<file>icons/mail/delete.png</file>
<file>icons/mail/tags.png</file>
<file>icons/mail/quote.png</file>
@ -311,6 +312,7 @@
<file>icons/mail/foward.png</file>
<file>icons/mail/reply.png</file>
<file>icons/mail/reply-all.png</file>
<file>icons/mail/attach16.png</file>
<file>icons/mail/attach24.png</file>
<file>icons/mail/write-mail.png</file>
<file>icons/textedit/align.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before After
Before After

View file

@ -1206,6 +1206,12 @@ MessageComposer *MessageComposer::replyMsg(const std::string &msgId, bool all)
// needed to send system flags with reply
msgComposer->msgFlags = (msgInfo.msgflags & RS_MSG_SYSTEM);
MsgTagInfo tagInfo;
rsMail->getMessageTag(msgId, tagInfo);
msgComposer->m_tagIds = tagInfo.tagIds;
msgComposer->showTagLabels();
msgComposer->calculateTitle();
/* window will destroy itself! */

View file

@ -342,7 +342,8 @@ bool RsMessageModel::passesFilter(const Rs::Msgs::MsgInfoSummary& fmpe,int colum
|| (std::find(fmpe.msgtags.begin(),fmpe.msgtags.end(),mQuickViewFilter) != fmpe.msgtags.end())
|| (mQuickViewFilter==QUICK_VIEW_STARRED && (fmpe.msgflags & RS_MSG_STAR))
|| (mQuickViewFilter==QUICK_VIEW_SYSTEM && (fmpe.msgflags & RS_MSG_SYSTEM))
|| (mQuickViewFilter==QUICK_VIEW_SPAM && (fmpe.msgflags & RS_MSG_SPAM));
|| (mQuickViewFilter==QUICK_VIEW_SPAM && (fmpe.msgflags & RS_MSG_SPAM))
|| (mQuickViewFilter==QUICK_VIEW_ATTACHMENT && (fmpe.count >= 1));
#ifdef DEBUG_MESSAGE_MODEL
std::cerr << "Passes filter: type=" << mFilterType << " s=\"" << s.toStdString() << "MsgFlags=" << fmpe.msgflags << " msgtags=" ;
foreach(uint32_t i,fmpe.msgtags) std::cerr << i << " " ;

View file

@ -76,6 +76,7 @@ public:
QUICK_VIEW_STARRED = 0x06,
QUICK_VIEW_SYSTEM = 0x07,
QUICK_VIEW_SPAM = 0x08,
QUICK_VIEW_ATTACHMENT = 0x09,
QUICK_VIEW_USER = 100
};
@ -109,7 +110,6 @@ public:
void setCurrentBox(BoxName bn) ;
void setQuickViewFilter(QuickViewFilter fn) ;
const RsMessageId& currentMessageId() const;
void setFilter(FilterType filter_type, const QStringList& strings) ;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;

View file

@ -31,6 +31,7 @@ public:
MessageUserNotify(QObject *parent = 0);
virtual bool hasSetting(QString *name, QString *group);
virtual QString textInfo() const override { return tr("new mail(s)"); }
private:
virtual QIcon getIcon();

View file

@ -36,6 +36,7 @@
#include "gui/common/TagDefs.h"
#include "gui/common/PeerDefs.h"
#include "gui/common/Emoticons.h"
#include "gui/common/FilesDefs.h"
#include "gui/settings/rsharesettings.h"
#include "MessageComposer.h"
#include "MessageWidget.h"
@ -51,8 +52,8 @@
#include <retroshare/rsmsgs.h>
/* Images for context menu icons */
#define IMAGE_DOWNLOAD ":/images/start.png"
#define IMAGE_DOWNLOADALL ":/images/startall.png"
#define IMAGE_DOWNLOAD ":/icons/png/download.png"
#define IMAGE_DOWNLOADALL ":/icons/mail/downloadall.png"
#define COLUMN_FILE_NAME 0
#define COLUMN_FILE_SIZE 1
@ -511,6 +512,7 @@ void MessageWidget::fill(const std::string &msgId)
ui.inviteFrame->hide();
ui.expandFilesButton->setChecked(false);
ui.downloadButton->setEnabled(false);
togglefileview(true);
ui.replyButton->setEnabled(false);
@ -554,6 +556,7 @@ void MessageWidget::fill(const std::string &msgId)
for (it = recList.begin(); it != recList.end(); ++it) {
QTreeWidgetItem *item = new QTreeWidgetItem;
item->setText(COLUMN_FILE_NAME, QString::fromUtf8(it->fname.c_str()));
item->setIcon(COLUMN_FILE_NAME, FilesDefs::getIconFromFileType(it->fname.c_str()));
item->setText(COLUMN_FILE_SIZE, misc::friendlyUnit(it->size));
item->setData(COLUMN_FILE_SIZE, Qt::UserRole, QVariant(qulonglong(it->size)) );
item->setText(COLUMN_FILE_HASH, QString::fromStdString(it->hash.toStdString()));
@ -566,6 +569,7 @@ void MessageWidget::fill(const std::string &msgId)
/* add the items in! */
ui.msgList->insertTopLevelItems(0, items);
ui.expandFilesButton->setChecked(expandFiles && (items.count()>0) );
ui.downloadButton->setEnabled(items.count()>0);
togglefileview(true);
/* iterate through the sources */
@ -665,10 +669,14 @@ void MessageWidget::fill(const std::string &msgId)
}
ui.subjectText->setText(QString::fromUtf8(msgInfo.title.c_str()));
unsigned int formatTextFlag = RSHTML_FORMATTEXT_EMBED_LINKS ;
// emoticons disabled because of crazy cost.
//text = RsHtmlMsg(msgInfo.msgflags).formatText(ui.msgText->document(), QString::fromUtf8(msgInfo.msg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS);
text = RsHtmlMsg(msgInfo.msgflags).formatText(ui.msgText->document(), QString::fromUtf8(msgInfo.msg.c_str()), RSHTML_FORMATTEXT_EMBED_LINKS);
// embed smileys ?
if (Settings->valueFromGroup(QString("Messages"), QString::fromUtf8("Emoticons"), true).toBool()) {
formatTextFlag |= RSHTML_FORMATTEXT_EMBED_SMILEYS ;
}
text = RsHtmlMsg(msgInfo.msgflags).formatText(ui.msgText->document(), QString::fromUtf8(msgInfo.msg.c_str()), formatTextFlag);
ui.msgText->resetImagesStatus(Settings->getMsgLoadEmbeddedImages() || (msgInfo.msgflags & RS_MSG_LOAD_EMBEDDED_IMAGES));
ui.msgText->setHtml(text);

View file

@ -53,16 +53,19 @@
#include <algorithm>
/* Images for context menu icons */
#define IMAGE_MAIL ":/icons/png/message.png"
#define IMAGE_MESSAGE ":/icons/mail/compose.png"
#define IMAGE_MESSAGEREMOVE ":/icons/mail/delete.png"
#define IMAGE_STAR_ON ":/images/star-on-16.png"
#define IMAGE_STAR_OFF ":/images/star-off-16.png"
#define IMAGE_SYSTEM ":/images/user/user_request16.png"
#define IMAGE_SYSTEM ":/icons/notification.png"
#define IMAGE_DECRYPTMESSAGE ":/images/decrypt-mail.png"
#define IMAGE_AUTHOR_INFO ":/images/info16.png"
#define IMAGE_NOTFICATION ":/icons/notification.png"
#define IMAGE_SPAM_ON ":/images/junk_on.png"
#define IMAGE_SPAM_OFF ":/images/junk_off.png"
#define IMAGE_ATTACHMENTS ":/icons/mail/attach24.png"
#define IMAGE_ATTACHMENT ":/icons/mail/attach16.png"
#define IMAGE_INBOX ":/images/folder-inbox.png"
#define IMAGE_OUTBOX ":/images/folder-outbox.png"
@ -82,6 +85,7 @@
#define QUICKVIEW_STATIC_ID_STARRED 1
#define QUICKVIEW_STATIC_ID_SYSTEM 2
#define QUICKVIEW_STATIC_ID_SPAM 3
#define QUICKVIEW_STATIC_ID_ATTACHMENT 4
#define ROW_INBOX 0
#define ROW_OUTBOX 1
@ -93,7 +97,7 @@
class MessageSortFilterProxyModel: public QSortFilterProxyModel
{
public:
MessageSortFilterProxyModel(const QHeaderView *header,QObject *parent = NULL): QSortFilterProxyModel(parent),m_header(header) , m_sortingEnabled(false) {}
MessageSortFilterProxyModel(QObject *parent = NULL): QSortFilterProxyModel(parent), m_sortingEnabled(false) {}
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override
{
@ -113,7 +117,6 @@ public:
void setSortingEnabled(bool b) { m_sortingEnabled = b ; }
private:
const QHeaderView *m_header ;
bool m_sortingEnabled;
};
@ -138,7 +141,7 @@ MessagesDialog::MessagesDialog(QWidget *parent)
listMode = LIST_NOTHING;
mMessageModel = new RsMessageModel(this);
mMessageProxyModel = new MessageSortFilterProxyModel(ui.messageTreeWidget->header(),this);
mMessageProxyModel = new MessageSortFilterProxyModel(this);
mMessageProxyModel->setSourceModel(mMessageModel);
mMessageProxyModel->setSortRole(RsMessageModel::SortRole);
mMessageProxyModel->setDynamicSortFilter(false);
@ -240,8 +243,9 @@ MessagesDialog::MessagesDialog(QWidget *parent)
//ui.messageTreeWidget->installEventFilter(this);
// remove close button of the the first tab
ui.tabWidget->hideCloseButton(0);
// remove close button of the the first tab
ui.tabWidget->hideCloseButton(0);
ui.tabWidget->setHideTabBarWithOneTab(true);
int S = QFontMetricsF(font()).height();
QString help_str = tr(
@ -447,12 +451,24 @@ void MessagesDialog::fillQuickView()
itemToSelect = item;
}
item = new QListWidgetItem(tr("Attachment"), ui.quickViewWidget);
item->setIcon(QIcon(IMAGE_ATTACHMENT));
item->setData(ROLE_QUICKVIEW_TYPE, QUICKVIEW_TYPE_STATIC);
item->setData(ROLE_QUICKVIEW_ID, QUICKVIEW_STATIC_ID_ATTACHMENT);
item->setData(ROLE_QUICKVIEW_TEXT, item->text()); // for updateMessageSummaryList
if (selectedType == QUICKVIEW_TYPE_STATIC && selectedId == QUICKVIEW_STATIC_ID_ATTACHMENT) {
itemToSelect = item;
}
for (tag = tags.types.begin(); tag != tags.types.end(); ++tag) {
text = TagDefs::name(tag->first, tag->second.first);
QPixmap tagpixmap(16,16);
tagpixmap.fill(QColor(tag->second.second));
item = new QListWidgetItem (text, ui.quickViewWidget);
item->setForeground(QBrush(QColor(tag->second.second)));
item->setIcon(QIcon(":/images/foldermail.png"));
item->setData(Qt::ForegroundRole, QColor(tag->second.second));
item->setIcon(tagpixmap);
item->setData(ROLE_QUICKVIEW_TYPE, QUICKVIEW_TYPE_TAG);
item->setData(ROLE_QUICKVIEW_ID, tag->first);
item->setData(ROLE_QUICKVIEW_TEXT, text); // for updateMessageSummaryList
@ -473,15 +489,22 @@ void MessagesDialog::fillQuickView()
int MessagesDialog::getSelectedMessages(QList<QString>& mid)
{
//To check if the selection has more than one row.
//To check if the selection has more than one row.
mid.clear();
QModelIndexList qmil = ui.messageTreeWidget->selectionModel()->selectedRows();
mid.clear();
QModelIndexList qmil = ui.messageTreeWidget->selectionModel()->selectedRows();
foreach(const QModelIndex& m, qmil)
foreach(const QModelIndex& m, qmil)
mid.push_back(m.sibling(m.row(),RsMessageModel::COLUMN_THREAD_MSGID).data(RsMessageModel::MsgIdRole).toString()) ;
return mid.size();
if (mid.isEmpty())
{
const QModelIndex& m = ui.messageTreeWidget->currentIndex();
if (m.isValid())
mid.push_back(m.sibling(m.row(),RsMessageModel::COLUMN_THREAD_MSGID).data(RsMessageModel::MsgIdRole).toString()) ;
}
return mid.size();
}
int MessagesDialog::getSelectedMsgCount (QList<QModelIndex> *items, QList<QModelIndex> *itemsRead, QList<QModelIndex> *itemsUnread, QList<QModelIndex> *itemsStar, QList<QModelIndex> *itemsJunk)
@ -663,17 +686,17 @@ void MessagesDialog::messageTreeWidgetCustomPopupMenu(QPoint /*point*/)
void MessagesDialog::showAuthorInPeopleTab()
{
std::string cid;
std::string mid;
std::string mid;
if(!getCurrentMsg(cid, mid))
return ;
if(!getCurrentMsg(cid, mid))
return ;
MessageInfo msgInfo;
if (!rsMail->getMessage(mid, msgInfo))
return;
MessageInfo msgInfo;
if (!rsMail->getMessage(mid, msgInfo))
return;
if(msgInfo.rsgxsid_srcId.isNull())
return ;
return ;
/* window will destroy itself! */
IdDialog *idDialog = dynamic_cast<IdDialog*>(MainWindow::getPage(MainWindow::People));
@ -744,7 +767,7 @@ void MessagesDialog::openAsTab()
return;
}
ui.tabWidget->addTab(msgWidget, msgWidget->subject(true));
ui.tabWidget->addTab(msgWidget,QIcon(IMAGE_MAIL), msgWidget->subject(true));
ui.tabWidget->setCurrentWidget(msgWidget);
connect(msgWidget, SIGNAL(messageRemoved()), this, SLOT(messageRemoved()));
@ -772,96 +795,94 @@ void MessagesDialog::editmessage()
void MessagesDialog::changeBox(int box_row)
{
if (inChange) {
// already in change method
return;
}
if (inChange) {
// already in change method
return;
}
inChange = true;
inChange = true;
ui.quickViewWidget->setCurrentItem(NULL);
listMode = LIST_BOX;
QListWidgetItem* item = ui.listWidget->item(box_row);
switch(box_row)
{
case 0: mMessageModel->setCurrentBox(RsMessageModel::BOX_INBOX );
ui.tabWidget->setTabText(0, tr("Inbox"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_INBOX));
break;
case 1: mMessageModel->setCurrentBox(RsMessageModel::BOX_OUTBOX);
ui.tabWidget->setTabText(0, tr("Outbox"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_OUTBOX));
break;
case 2: mMessageModel->setCurrentBox(RsMessageModel::BOX_DRAFTS);
ui.tabWidget->setTabText(0, tr("Drafts"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_DRAFTS));
break;
case 3: mMessageModel->setCurrentBox(RsMessageModel::BOX_SENT );
ui.tabWidget->setTabText(0, tr("Sent"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_SENT));
break;
case 4: mMessageModel->setCurrentBox(RsMessageModel::BOX_TRASH );
ui.tabWidget->setTabText(0, tr("Trash"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_TRASH));
break;
default:
mMessageModel->setCurrentBox(RsMessageModel::BOX_NONE); break;
}
inChange = false;
insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex());
if (item)
{
ui.quickViewWidget->setCurrentItem(NULL);
changeQuickView(-1);
listMode = LIST_BOX;
QString placeholderText = tr("No message available in your %1.").arg(item->text());
switch(box_row)
{
case ROW_INBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_INBOX );
break;
case ROW_OUTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_OUTBOX);
break;
case ROW_DRAFTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_DRAFTS);
break;
case ROW_SENTBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_SENT );
break;
case ROW_TRASHBOX: mMessageModel->setCurrentBox(RsMessageModel::BOX_TRASH );
break;
default:
mMessageModel->setCurrentBox(RsMessageModel::BOX_NONE);
}
insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex());
ui.messageTreeWidget->setPlaceholderText(placeholderText);
}
else
{
mMessageModel->setCurrentBox(RsMessageModel::BOX_NONE);
}
inChange = false;
}
void MessagesDialog::changeQuickView(int newrow)
{
Q_UNUSED(newrow);
ui.listWidget->setCurrentItem(NULL);
listMode = LIST_QUICKVIEW;
RsMessageModel::QuickViewFilter f = RsMessageModel::QUICK_VIEW_ALL ;
QListWidgetItem* item = ui.quickViewWidget->item(newrow);
RsMessageModel::QuickViewFilter f = RsMessageModel::QUICK_VIEW_ALL ;
if(item )
{
ui.listWidget->setCurrentItem(NULL);
changeBox(-1);
if(newrow >= 0) // -1 means that nothing is selected
switch(newrow)
{
case 0x00: f = RsMessageModel::QUICK_VIEW_STARRED ;
ui.tabWidget->setTabText(0, tr("Starred"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_STAR_ON));
break;
case 0x01: f = RsMessageModel::QUICK_VIEW_SYSTEM ;
ui.tabWidget->setTabText(0, tr("System"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_SYSTEM));
break;
case 0x02: f = RsMessageModel::QUICK_VIEW_SPAM ;
ui.tabWidget->setTabText(0, tr("Spam"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_SPAM_ON));
break;
case 0x03: f = RsMessageModel::QUICK_VIEW_IMPORTANT;
ui.tabWidget->setTabText(0, tr("Important"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_FOLDER));
break;
case 0x04: f = RsMessageModel::QUICK_VIEW_WORK ;
ui.tabWidget->setTabText(0, tr("Work"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_FOLDER));
break;
case 0x05: f = RsMessageModel::QUICK_VIEW_PERSONAL ;
ui.tabWidget->setTabText(0, tr("Personal"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_FOLDER));
break;
case 0x06: f = RsMessageModel::QUICK_VIEW_TODO ;
ui.tabWidget->setTabText(0, tr("Todo"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_FOLDER));
break;
case 0x07: f = RsMessageModel::QUICK_VIEW_LATER ;
ui.tabWidget->setTabText(0, tr("Later"));
ui.tabWidget->setTabIcon(0, QIcon(IMAGE_FOLDER));
break;
default:
f = RsMessageModel::QuickViewFilter( (int)RsMessageModel::QUICK_VIEW_USER + newrow - 0x07);
listMode = LIST_QUICKVIEW;
QString placeholderText;
switch (item->data(ROLE_QUICKVIEW_TYPE).toInt()) {
case QUICKVIEW_TYPE_TAG:
{
placeholderText = tr("No message using %1 tag available.").arg(item->data(ROLE_QUICKVIEW_TEXT).toString());
f = RsMessageModel::QuickViewFilter( item->data(ROLE_QUICKVIEW_ID).toUInt());
}
break;
case QUICKVIEW_TYPE_STATIC:
{
placeholderText = tr("No %1 message available.").arg(item->data(ROLE_QUICKVIEW_TEXT).toString());
switch (item->data(ROLE_QUICKVIEW_ID).toInt()) {
case QUICKVIEW_STATIC_ID_STARRED:{
f = RsMessageModel::QUICK_VIEW_STARRED;
placeholderText = tr("No starred message available. Stars let you give messages a special status to make them easier to find. To star a message, click on the light gray star beside any message.");
}
break;
case QUICKVIEW_STATIC_ID_SYSTEM: f = RsMessageModel::QUICK_VIEW_SYSTEM;
break;
case QUICKVIEW_STATIC_ID_SPAM: f = RsMessageModel::QUICK_VIEW_SPAM;
break;
case QUICKVIEW_STATIC_ID_ATTACHMENT: f = RsMessageModel::QUICK_VIEW_ATTACHMENT;
}
}
}
mMessageModel->setQuickViewFilter(f);
mMessageProxyModel->setFilterRegExp(QRegExp(RsMessageModel::FilterString)); // this triggers the update of the proxy model
insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex());
insertMsgTxtAndFiles(ui.messageTreeWidget->currentIndex());
ui.messageTreeWidget->setPlaceholderText(placeholderText);
}
mMessageModel->setQuickViewFilter(f);
mMessageProxyModel->setFilterRegExp(QRegExp(RsMessageModel::FilterString)); // this triggers the update of the proxy model
}
void MessagesDialog::messagesTagsChanged()
@ -870,49 +891,48 @@ void MessagesDialog::messagesTagsChanged()
mMessageModel->updateMessages();
}
static void InitIconAndFont(QTreeWidgetItem *item)
{
}
// click in messageTreeWidget
void MessagesDialog::currentChanged(const QModelIndex& new_proxy_index,const QModelIndex& old_proxy_index)
void MessagesDialog::currentChanged(const QModelIndex& new_proxy_index,const QModelIndex& /*old_proxy_index*/)
{
if(!new_proxy_index.isValid())
return;
if(!new_proxy_index.isValid())
return;
// show current message directly
// show current message directly
insertMsgTxtAndFiles(new_proxy_index);
}
// click in messageTreeWidget
void MessagesDialog::clicked(const QModelIndex& proxy_index)
{
if(!proxy_index.isValid())
return;
if(!proxy_index.isValid())
return;
QModelIndex real_index = mMessageProxyModel->mapToSource(proxy_index);
QModelIndex real_index = mMessageProxyModel->mapToSource(proxy_index);
switch (proxy_index.column())
{
case RsMessageModel::COLUMN_THREAD_READ:
{
mMessageModel->setMsgReadStatus(real_index, !isMessageRead(proxy_index));
//Already updated by currentChanged
//insertMsgTxtAndFiles(proxy_index);
updateMessageSummaryList();
return;
}
case RsMessageModel::COLUMN_THREAD_STAR:
{
mMessageModel->setMsgStar(real_index, !hasMessageStar(proxy_index));
return;
}
case RsMessageModel::COLUMN_THREAD_SPAM:
{
mMessageModel->setMsgJunk(real_index, !hasMessageSpam(proxy_index));
return;
}
}
switch (proxy_index.column())
{
case RsMessageModel::COLUMN_THREAD_READ:
{
mMessageModel->setMsgReadStatus(real_index, !isMessageRead(proxy_index));
//Already updated by currentChanged
//insertMsgTxtAndFiles(proxy_index);
updateMessageSummaryList();
return;
}
case RsMessageModel::COLUMN_THREAD_STAR:
{
mMessageModel->setMsgStar(real_index, !hasMessageStar(proxy_index));
updateMessageSummaryList();
return;
}
case RsMessageModel::COLUMN_THREAD_SPAM:
{
mMessageModel->setMsgJunk(real_index, !hasMessageSpam(proxy_index));
updateMessageSummaryList();
return;
}
}
// show current message directly
//Already updated by currentChanged
@ -1038,9 +1058,8 @@ void MessagesDialog::insertMsgTxtAndFiles(const QModelIndex& proxy_index)
else if ((msgInfo.msgflags & RS_MSG_UNREAD_BY_USER) && bSetToReadOnActive) // set to read
mMessageModel->setMsgReadStatus(real_index, true);
updateInterface();
msgWidget->fill(mid);
updateMessageSummaryList();
msgWidget->fill(mid);
}
bool MessagesDialog::getCurrentMsg(std::string &cid, std::string &mid)
@ -1086,7 +1105,10 @@ void MessagesDialog::removemessage()
void MessagesDialog::messageRemoved()
{
ui.messageTreeWidget->setCurrentIndex(lastSelectedIndex);
if (lastSelectedIndex.isValid())
ui.messageTreeWidget->setCurrentIndex(lastSelectedIndex);
else
insertMsgTxtAndFiles(QModelIndex());
}
void MessagesDialog::undeletemessage()
@ -1163,6 +1185,7 @@ void MessagesDialog::updateMessageSummaryList()
unsigned int starredCount = 0;
unsigned int systemCount = 0;
unsigned int spamCount = 0;
unsigned int attachmentCount = 0;
/* calculating the new messages */
@ -1262,7 +1285,7 @@ void MessagesDialog::updateMessageSummaryList()
qf.setBold(true);
item->setFont(qf);
item->setIcon(QIcon(":/images/folder-inbox-new.png"));
item->setForeground(QBrush(mTextColorInbox));
item->setData(Qt::ForegroundRole, mTextColorInbox);
}
else
{
@ -1272,7 +1295,7 @@ void MessagesDialog::updateMessageSummaryList()
qf.setBold(false);
item->setFont(qf);
item->setIcon(QIcon(":/images/folder-inbox.png"));
item->setForeground(QBrush(ui.messageTreeWidget->palette().color(QPalette::Text)));
item->setData(Qt::ForegroundRole, QVariant());
}
//QList<QListWidgetItem *> QListWidget::findItems ( const QString & text, Qt::MatchFlags flags ) const
@ -1357,6 +1380,9 @@ void MessagesDialog::updateMessageSummaryList()
case QUICKVIEW_STATIC_ID_SPAM:
text += " (" + QString::number(spamCount) + ")";
break;
case QUICKVIEW_STATIC_ID_ATTACHMENT:
text += " (" + QString::number(attachmentCount) + ")";
break;
}
item->setText(text);
@ -1364,6 +1390,7 @@ void MessagesDialog::updateMessageSummaryList()
break;
}
}
updateInterface();
}
void MessagesDialog::tagAboutToShow()
@ -1497,12 +1524,12 @@ void MessagesDialog::updateInterface()
int tab = ui.tabWidget->currentIndex();
if (tab == 0)
{
QList<QString> msgs;
{
QList<QString> msgs;
count = getSelectedMessages(msgs);
}
else
{
else
{
MessageWidget *msg = dynamic_cast<MessageWidget*>(ui.tabWidget->widget(tab));
if (msg && msg->msgId().empty() == false)
count = 1;
@ -1512,4 +1539,20 @@ void MessagesDialog::updateInterface()
ui.actionPrintPreview->setEnabled(count == 1);
ui.actionSaveAs->setEnabled(count == 1);
ui.tagButton->setEnabled(count >= 1);
if (ui.listWidget->currentItem())
{
ui.tabWidget->setTabText(0, ui.listWidget->currentItem()->text());
ui.tabWidget->setTabIcon(0, ui.listWidget->currentItem()->icon());
}
else if (ui.quickViewWidget->currentItem())
{
ui.tabWidget->setTabText(0, ui.quickViewWidget->currentItem()->text());
ui.tabWidget->setTabIcon(0, ui.quickViewWidget->currentItem()->icon());
}
else
{
ui.tabWidget->setTabText(0, tr("No Box selected."));
ui.tabWidget->setTabIcon(0, QIcon(":/icons/warning_yellow_128.png"));
}
}

View file

@ -205,6 +205,9 @@
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="quickViewFrameHLayout">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
@ -367,7 +370,7 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QTreeView" name="messageTreeWidget">
<widget class="RSTreeView" name="messageTreeWidget">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
@ -462,6 +465,12 @@
<header>gui/common/RSTabWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>RSTreeView</class>
<extends>QTreeView</extends>
<header>gui/common/RSTreeView.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>listWidget</tabstop>

View file

@ -904,6 +904,16 @@ MessagesDialog QWidget#messageTreeWidget::item {
padding: 2px;
}
MessagesDialog QWidget#messageTreeWidget::item:selected {
background-color: #cde8ff;
color: black;
}
MessagesDialog QWidget#messageTreeWidget::item:hover {
background-color: #e5f3ff;
color: black;
}
GxsForumThreadWidget QWidget#threadTreeWidget::item {
padding: 2px;
}

View file

@ -186,7 +186,7 @@ NetworkDialog
RSTextBrowser, MimeTextEdit
{
qproperty-textColorQuote: rgb(120, 153, 34);
/*qproperty-textColorQuote: rgb(120, 153, 34);*/
qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970);
}

View file

@ -35,6 +35,8 @@ ForumPage::ForumPage(QWidget * parent, Qt::WindowFlags flags)
connect(ui.expandNewMessages , SIGNAL(toggled(bool)), this, SLOT( updateExpandNewMessages()));
connect(ui.loadEmbeddedImages , SIGNAL(toggled(bool)), this, SLOT(updateLoadEmbeddedImages() ));
connect(ui.loadEmoticons , SIGNAL(toggled(bool)), this, SLOT( updateLoadEmoticons() ));
connect(ui.minimumFontSize , SIGNAL(valueChanged(int)), this, SLOT(updateFonts()));
connect(ui.minimumContrast , SIGNAL(valueChanged(int)), this, SLOT(updateFonts()));
ui.groupFrameSettingsWidget->setType(GroupFrameSettings::Forum) ;
}
@ -51,10 +53,22 @@ void ForumPage::updateLoadEmoticons() { Settings->setForumLoadEmoticons(
/** Loads the settings for this page */
void ForumPage::load()
{
Settings->beginGroup(QString("Forum"));
whileBlocking(ui.setMsgToReadOnActivate)->setChecked(Settings->getForumMsgSetToReadOnActivate());
whileBlocking(ui.expandNewMessages)->setChecked(Settings->getForumExpandNewMessages());
whileBlocking(ui.loadEmbeddedImages)->setChecked(Settings->getForumLoadEmbeddedImages());
whileBlocking(ui.loadEmoticons)->setChecked(Settings->getForumLoadEmoticons());
whileBlocking(ui.minimumFontSize)->setValue(Settings->value("MinimumFontSize", 10).toInt());
whileBlocking(ui.minimumContrast)->setValue(Settings->value("MinimumContrast", 4.5).toDouble());
Settings->endGroup();
ui.groupFrameSettingsWidget->loadSettings(GroupFrameSettings::Forum);
}
void ForumPage::updateFonts()
{
Settings->beginGroup(QString("Forum"));
Settings->setValue("MinimumFontSize", ui.minimumFontSize->value());
Settings->setValue("MinimumContrast", ui.minimumContrast->value());
Settings->endGroup();
}

View file

@ -45,6 +45,9 @@ protected slots:
void updateLoadEmbeddedImages();
void updateLoadEmoticons();
private slots:
void updateFonts();
private:
Ui::ForumPage ui;
};

View file

@ -17,6 +17,16 @@
<string>Misc</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="0">
<widget class="QCheckBox" name="loadEmoticons">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option is costly and it's in the dev's plans to improve it. In the mean time it's disabled by default. If you enable it and long forum posts take a while to display, then disable it again. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Load emoticons (costly)</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="setMsgToReadOnActivate">
<property name="text">
@ -38,15 +48,71 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="loadEmoticons">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option is costly and it's in the dev's plans to improve it. In the mean time it's disabled by default. If you enable it and long forum posts take a while to display, then disable it again. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Load emoticons (costly)</string>
</property>
</widget>
<item row="4" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="minimumFontSizeLabel">
<property name="text">
<string>Minimum font size</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="minimumFontSize">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>64</number>
</property>
</widget>
</item>
<item row="0" column="2" rowspan="2">
<spacer name="minimumFontSizeHSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>38</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="minimumContrastLabel">
<property name="text">
<string>Minimum text contrast</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="minimumContrast">
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>21.000000000000000</double>
</property>
<property name="singleStep">
<double>0.500000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="tabsGroupBox">
<property name="title">
<string>Tabs</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="GroupFrameSettingsWidget" name="groupFrameSettingsWidget" native="true"/>
</item>
</layout>
</widget>
@ -64,18 +130,6 @@
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="tabsGroupBox">
<property name="title">
<string>Tabs</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="GroupFrameSettingsWidget" name="groupFrameSettingsWidget" native="true"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View file

@ -39,7 +39,6 @@ MessagePage::MessagePage(QWidget * parent, Qt::WindowFlags flags)
connect (ui.editpushButton, SIGNAL(clicked(bool)), this, SLOT (editTag()));
connect (ui.deletepushButton, SIGNAL(clicked(bool)), this, SLOT (deleteTag()));
connect (ui.defaultTagButton, SIGNAL(clicked(bool)), this, SLOT (defaultTag()));
//connect (ui.encryptedMsgs_CB, SIGNAL(toggled(bool)), this, SLOT (toggleEnableEncryptedDistantMsgs(bool)));
connect (ui.tags_listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(currentRowChangedTag(int)));
@ -54,6 +53,7 @@ MessagePage::MessagePage(QWidget * parent, Qt::WindowFlags flags)
connect(ui.setMsgToReadOnActivate,SIGNAL(toggled(bool)), this,SLOT(updateMsgToReadOnActivate()));
connect(ui.loadEmbeddedImages, SIGNAL(toggled(bool)), this,SLOT(updateLoadEmbededImages() ));
connect(ui.openComboBox, SIGNAL(currentIndexChanged(int)),this,SLOT(updateMsgOpen() ));
connect(ui.emoticonscheckBox, SIGNAL(toggled(bool)), this,SLOT(updateLoadEmoticons() ));
}
MessagePage::~MessagePage()
@ -84,6 +84,7 @@ void MessagePage::updateMsgToReadOnActivate() { Settings->setMsgSetToReadOnActiv
void MessagePage::updateLoadEmbededImages() { Settings->setMsgLoadEmbeddedImages(ui.loadEmbeddedImages->isChecked()); }
void MessagePage::updateMsgOpen() { Settings->setMsgOpen( static_cast<RshareSettings::enumMsgOpen>(ui.openComboBox->itemData(ui.openComboBox->currentIndex()).toInt()) ); }
void MessagePage::updateDistantMsgs() { Settings->setValue("DistantMessages", ui.comboBox->currentIndex()); }
void MessagePage::updateLoadEmoticons() { Settings->setValueToGroup("Messages", "Emoticons", ui.emoticonscheckBox->isChecked()); }
void MessagePage::updateMsgTags()
{
@ -110,9 +111,12 @@ void MessagePage::updateMsgTags()
void
MessagePage::load()
{
Settings->beginGroup(QString("Messages"));
whileBlocking(ui.setMsgToReadOnActivate)->setChecked(Settings->getMsgSetToReadOnActivate());
whileBlocking(ui.loadEmbeddedImages)->setChecked(Settings->getMsgLoadEmbeddedImages());
whileBlocking(ui.openComboBox)->setCurrentIndex(ui.openComboBox->findData(Settings->getMsgOpen()));
whileBlocking(ui.emoticonscheckBox)->setChecked(Settings->value("Emoticons", true).toBool());
Settings->endGroup();
// state of filter combobox
@ -140,7 +144,7 @@ void MessagePage::fillTags()
QString text = TagDefs::name(Tag->first, Tag->second.first);
QListWidgetItem *pItemWidget = new QListWidgetItem(text, ui.tags_listWidget);
pItemWidget->setTextColor(QColor(Tag->second.second));
pItemWidget->setData(Qt::ForegroundRole, QColor(Tag->second.second));
pItemWidget->setData(Qt::UserRole, Tag->first);
}
}
@ -155,7 +159,7 @@ void MessagePage::addTag()
QString text = TagDefs::name(Tag->first, Tag->second.first);
QListWidgetItem *pItemWidget = new QListWidgetItem(text, ui.tags_listWidget);
pItemWidget->setTextColor(QColor(Tag->second.second));
pItemWidget->setData(Qt::ForegroundRole, QColor(Tag->second.second));
pItemWidget->setData(Qt::UserRole, TagDlg.m_nId);
m_changedTagIds.push_back(TagDlg.m_nId);
@ -186,7 +190,7 @@ void MessagePage::editTag()
if (Tag->first >= RS_MSGTAGTYPE_USER) {
pItemWidget->setText(QString::fromStdString(Tag->second.first));
}
pItemWidget->setTextColor(QColor(Tag->second.second));
pItemWidget->setData(Qt::ForegroundRole, QColor(Tag->second.second));
if (std::find(m_changedTagIds.begin(), m_changedTagIds.end(), TagDlg.m_nId) == m_changedTagIds.end()) {
m_changedTagIds.push_back(TagDlg.m_nId);
@ -267,3 +271,4 @@ void MessagePage::currentRowChangedTag(int row)
ui.editpushButton->setEnabled(bEditEnable);
ui.deletepushButton->setEnabled(bDeleteEnable);
}

View file

@ -58,6 +58,7 @@ private slots:
void updateMsgOpen() ;
void updateDistantMsgs() ;
void updateMsgTags() ;
void updateLoadEmoticons();
private:
void fillTags();

View file

@ -65,14 +65,7 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="loadEmbeddedImages">
<property name="text">
<string>Load embedded images</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="openLabel">
@ -86,6 +79,20 @@
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="loadEmbeddedImages">
<property name="text">
<string>Load embedded images</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="emoticonscheckBox">
<property name="text">
<string>Load Emoticons</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View file

@ -1157,7 +1157,7 @@ void RshareSettings::setWebinterfaceEnabled(bool enabled)
QString RshareSettings::getWebinterfaceFilesDirectory()
{
#ifdef WINDOWS_SYS
return valueFromGroup("Webinterface","directory","data/webui/").toString();
return valueFromGroup("Webinterface","directory","./webui/").toString();
#else
return valueFromGroup("Webinterface","directory","/usr/share/retroshare/webui/").toString();
#endif

View file

@ -51,6 +51,10 @@ background: black;
color: lightgray;
border-color: transparent;
}
QTreeView::item, QTreeWidget::item, QListWidget::item{
color: lightgray;
}
QDialog, QMainWindow{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgb(25, 25, 25), stop:0.05 rgb(0, 0, 0), stop:0.95 rgb(0, 0, 0), stop:1 rgb(25, 25, 25));
}
@ -255,6 +259,12 @@ QTextEdit {
color: white;
}
RSTextBrowser, MimeTextEdit
{
/*qproperty-textColorQuote: rgb(125, 125, 255);*/
qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970);
}
/* OpModeStatus need to be at end to overload other values*/
OpModeStatus {
qproperty-opMode_Full_Color: #007000;

View file

@ -51,6 +51,9 @@ QWidget {
selection-background-color: #1464A0;
selection-color: #F0F0F0;
}
QTreeView::item, QTreeWidget::item, QListWidget::item{
color: #F0F0F0;
}
QWidget:disabled {
background-color: #19232D;
@ -2151,6 +2154,6 @@ GxsChannelDialog GroupTreeWidget QTreeWidget#treeWidget::item{
RSTextBrowser, MimeTextEdit
{
qproperty-textColorQuote: rgb(125, 125, 255);
qproperty-textColorQuotes: ColorList(#0000ff #00ff00 #00ffff #ff0000 #ff00ff #ffff00 #ffffff);
/*qproperty-textColorQuote: rgb(125, 125, 255);*/
qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970);
}

View file

@ -60,6 +60,9 @@ QWidget
border-image: none;
outline: 0;
}
QTreeView::item, QTreeWidget::item, QListWidget::item{
color: silver;
}
QWidget:item:hover
{
@ -1298,6 +1301,11 @@ WireGroupItem QFrame#frame{
RSTextBrowser, MimeTextEdit
{
qproperty-textColorQuote: rgb(125, 125, 255);
qproperty-textColorQuotes: ColorList(#0000ff #00ff00 #00ffff #ff0000 #ff00ff #ffff00 #ffffff);
/*qproperty-textColorQuote: rgb(125, 125, 255);*/
qproperty-textColorQuotes: ColorList(#789922 #039bd5 #800000 #800080 #008080 #b10dc9 #85144b #3d9970);
}
ChatWidget QFrame#pluginTitleFrame
{
background: transparent;
}

View file

@ -31,6 +31,8 @@
#include "gui/RetroShareLink.h"
#include "util/ObjectPainter.h"
#include "util/imageutil.h"
#include "util/rsdebug.h"
#include "util/rstime.h"
#ifdef USE_CMARK
@ -40,6 +42,8 @@
#include <iostream>
//#define DEBUG_SAVESPACE 1
/**
* The type of embedding we'd like to do
*/
@ -554,18 +558,24 @@ static QString saveSpace(const QString text)
if(cursChar==QLatin1Char('>')) {
if(!echapChar && i>0) {outBrackets=true; firstOutBracket=true;}
} else if(cursChar==QLatin1Char('\t')) {
if(outBrackets && firstOutBracket && (keyName!="style")) savedSpaceText.replace(i, 1, "&nbsp;&nbsp;");
if(outBrackets && firstOutBracket && (keyName!="style")) { savedSpaceText.replace(i, 1, "&nbsp;&nbsp;"); i+= 11; }
} else if(cursChar==QLatin1Char(' ')) {
if(outBrackets && firstOutBracket && (keyName!="style")) savedSpaceText.replace(i, 1, "&nbsp;");
if(outBrackets && firstOutBracket && (keyName!="style")) { savedSpaceText.replace(i, 1, "&nbsp;"); i+= 5; }
} else if(cursChar==QChar(0xA0)) {
if(outBrackets && firstOutBracket && (keyName!="style")) savedSpaceText.replace(i, 1, "&nbsp;");
if(outBrackets && firstOutBracket && (keyName!="style")) { savedSpaceText.replace(i, 1, "&nbsp;"); i+= 5; }
} else if(cursChar==QLatin1Char('<')) {
if(!echapChar) {outBrackets=false; getKeyName=true; keyName.clear();}
} else firstOutBracket=false;
echapChar=(cursChar==QLatin1Char('\\'));
}
#ifdef DEBUG_SAVESPACE
RsDbg() << __PRETTY_FUNCTION__ << "Text to save:" << std::endl
<< text.toStdString() << std::endl
<< "---------------------- Saved Text:" << std::endl
<< savedSpaceText.toStdString() << std::endl;
#endif
return savedSpaceText;
}