diff --git a/libretroshare/src/retroshare/rsstatus.h b/libretroshare/src/retroshare/rsstatus.h index 42d90b17d..3173726bb 100644 --- a/libretroshare/src/retroshare/rsstatus.h +++ b/libretroshare/src/retroshare/rsstatus.h @@ -48,11 +48,7 @@ const uint32_t RS_STATUS_COUNT = 0x0005; // count of status class StatusInfo { public: - StatusInfo() - { - status = 0; - time_stamp = 0; - } + StatusInfo() : status(RS_STATUS_OFFLINE), time_stamp(0) {} public: RsPeerId id; diff --git a/retroshare-gui/src/gui/common/FriendListModel.cpp b/retroshare-gui/src/gui/common/FriendListModel.cpp index bbb8b35a5..a7cfb8f0d 100644 --- a/retroshare-gui/src/gui/common/FriendListModel.cpp +++ b/retroshare-gui/src/gui/common/FriendListModel.cpp @@ -406,14 +406,14 @@ QVariant RsFriendListModel::data(const QModelIndex &index, int role) const QVariant RsFriendListModel::textColorRole(const EntryIndex& fmpe,int column) const { - switch(fmpe.type) - { - case ENTRY_TYPE_GROUP: return QVariant(QBrush(mTextColorGroup)); - case ENTRY_TYPE_PROFILE: - case ENTRY_TYPE_NODE: return QVariant(QBrush(mTextColorStatus[ onlineRole(fmpe,column).toBool() ?RS_STATUS_ONLINE:RS_STATUS_OFFLINE])); - default: + switch(fmpe.type) + { + case ENTRY_TYPE_GROUP: return QVariant(QBrush(mTextColorGroup)); + case ENTRY_TYPE_PROFILE: + case ENTRY_TYPE_NODE: return QVariant(QBrush(mTextColorStatus[onlineRole(fmpe,column).toInt()])); + default: return QVariant(); - } + } } QVariant RsFriendListModel::statusRole(const EntryIndex& /*fmpe*/,int /*column*/) const @@ -545,47 +545,51 @@ QVariant RsFriendListModel::sortRole(const EntryIndex& entry,int column) const QVariant RsFriendListModel::onlineRole(const EntryIndex& e, int /*col*/) const { - switch(e.type) + switch(e.type) { - default: - case ENTRY_TYPE_GROUP: - { - const HierarchicalGroupInformation& g(mGroups[e.group_index]); - - for(uint32_t j=0;jchild_node_indices.size();++i) + if(mLocations[prof->child_node_indices[i]].node_info.state & RS_PEER_STATE_CONNECTED) + return QVariant(RS_STATUS_ONLINE); + } + } + break; - for(uint32_t i=0;ichild_node_indices.size();++i) - if(mLocations[prof->child_node_indices[i]].node_info.state & RS_PEER_STATE_CONNECTED) - return QVariant(true); + case ENTRY_TYPE_NODE: + { + const HierarchicalNodeInformation *node = getNodeInfo(e); - return QVariant(); - } - break; + if(node) + { + StatusInfo status; + rsStatus->getStatus(node->node_info.id, status); - case ENTRY_TYPE_NODE: - const HierarchicalNodeInformation *node = getNodeInfo(e); - - if(!node) - return QVariant(); - - return QVariant(bool(node->node_info.state & RS_PEER_STATE_CONNECTED)); + return QVariant(status.status); + } + } } + return QVariant(RS_STATUS_OFFLINE); } QVariant RsFriendListModel::fontRole(const EntryIndex& e, int col) const @@ -594,17 +598,23 @@ QVariant RsFriendListModel::fontRole(const EntryIndex& e, int col) const std::cerr << " font role " << e.type << ", (" << (int)e.group_index << ","<< (int)e.profile_index << ","<< (int)e.node_index << ") col="<< col<<": " << std::endl; #endif - bool b = onlineRole(e,col).toBool(); + int status = onlineRole(e,col).toInt(); - if(b) - { - QFont font ; - font.setBold(b); + switch (status) + { + case RS_STATUS_AWAY: + case RS_STATUS_BUSY: + case RS_STATUS_ONLINE: + case RS_STATUS_INACTIVE: + { + QFont font ; + font.setBold(true); - return QVariant(font); - } - else - return QVariant(); + return QVariant(font); + } + default: + return QVariant(); + } } class AutoEndel @@ -617,7 +627,6 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const { #ifdef DEBUG_MODEL_INDEX std::cerr << " Display role " << e.type << ", (" << (int)e.group_index << ","<< (int)e.profile_index << ","<< (int)e.node_index << ") col="<< col<<": "; - AutoEndel x; #endif switch(e.type) @@ -651,7 +660,7 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const else return QVariant(QString::fromUtf8(group->group_info.name.c_str())); - case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(group->group_info.id.toStdString())); + //case COLUMN_THREAD_ID: return QVariant(QString::fromStdString(group->group_info.id.toStdString())); default: return QVariant(); } @@ -724,8 +733,15 @@ QVariant RsFriendListModel::displayRole(const EntryIndex& e, int col) const { std::string css = rsMsgs->getCustomStateString(node->node_info.id); - if(!css.empty() && mDisplayStatusString) - return QVariant(QString::fromUtf8(node->node_info.location.c_str())+"\n"+QString::fromUtf8(css.c_str())); + if (mDisplayStatusString) + if(!css.empty()) + return QVariant(QString::fromUtf8(node->node_info.location.c_str())+"\n" + + QString::fromUtf8(css.c_str())); + else + { + return QVariant(QString::fromUtf8(node->node_info.location.c_str())+"\n" + + "(" + StatusDefs::name(onlineRole(e,col).toInt()) + ")"); + } else return QVariant(QString::fromUtf8(node->node_info.location.c_str())); } diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 2b06cb1db..0329bc6af 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -33,6 +33,7 @@ #include "gui/chat/ChatDialog.h" #include "gui/common/AvatarDefs.h" #include "gui/common/FilesDefs.h" +#include "gui/common/RSElidedItemDelegate.h" #include "gui/connect/ConfCertDialog.h" #include "gui/connect/PGPKeyDialog.h" @@ -106,44 +107,45 @@ Q_DECLARE_METATYPE(ElidedLabel*) class FriendListSortFilterProxyModel: public QSortFilterProxyModel { public: - FriendListSortFilterProxyModel(const QHeaderView *header,QObject *parent = NULL): QSortFilterProxyModel(parent), - m_header(header), - m_sortingEnabled(false), - m_showOfflineNodes(true) {} + explicit FriendListSortFilterProxyModel(const QHeaderView *header,QObject *parent = NULL) + : QSortFilterProxyModel(parent) + , m_header(header) + , m_sortingEnabled(false), m_sortByState(false) + , m_showOfflineNodes(true) {} - bool lessThan(const QModelIndex& left, const QModelIndex& right) const override - { - bool is_group_1 = left.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; - bool is_group_2 = right.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; + bool lessThan(const QModelIndex& left, const QModelIndex& right) const override + { + bool is_group_1 = left.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; + bool is_group_2 = right.data(RsFriendListModel::TypeRole).toUInt() == (uint)RsFriendListModel::ENTRY_TYPE_GROUP; - if(is_group_1 ^ is_group_2) // if the two are different, put the group first. - return is_group_1 ; + if(is_group_1 ^ is_group_2) // if the two are different, put the group first. + return is_group_1 ; - bool online1 = left .data(RsFriendListModel::OnlineRole).toBool(); - bool online2 = right.data(RsFriendListModel::OnlineRole).toBool(); + bool online1 = (left .data(RsFriendListModel::OnlineRole).toInt() != RS_STATUS_OFFLINE); + bool online2 = (right.data(RsFriendListModel::OnlineRole).toInt() != RS_STATUS_OFFLINE); - if(online1 != online2 && m_sortByState) - return (m_header->sortIndicatorOrder()==Qt::AscendingOrder)?online1:online2 ; // always put online nodes first + if(online1 != online2 && m_sortByState) + return (m_header->sortIndicatorOrder()==Qt::AscendingOrder)?online1:online2 ; // always put online nodes first return left.data(RsFriendListModel::SortRole) < right.data(RsFriendListModel::SortRole) ; - } + } - bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override - { - // do not show empty groups + bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override + { + // do not show empty groups - QModelIndex index = sourceModel()->index(source_row,0,source_parent); + QModelIndex index = sourceModel()->index(source_row,0,source_parent); - if(index.data(RsFriendListModel::TypeRole) == RsFriendListModel::ENTRY_TYPE_GROUP) // always show groups, so we can delete them even when empty - return true; + if(index.data(RsFriendListModel::TypeRole) == RsFriendListModel::ENTRY_TYPE_GROUP) // always show groups, so we can delete them even when empty + return true; - // Filter offline friends + // Filter offline friends - if(!m_showOfflineNodes && !index.data(RsFriendListModel::OnlineRole).toBool()) - return false; + if(!m_showOfflineNodes && (index.data(RsFriendListModel::OnlineRole).toInt() == RS_STATUS_OFFLINE)) + return false; - return index.data(RsFriendListModel::FilterRole).toString() == RsFriendListModel::FilterString ; - } + return index.data(RsFriendListModel::FilterRole).toString() == RsFriendListModel::FilterString ; + } void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) override { @@ -187,7 +189,9 @@ NewFriendList::NewFriendList(QWidget */*parent*/) : /* RsAutoUpdatePage(5000,par mProxyModel->setFilterRole(RsFriendListModel::FilterRole); mProxyModel->setFilterRegExp(QRegExp(RsFriendListModel::FilterString)); - ui->peerTreeWidget->setModel(mProxyModel); + ui->peerTreeWidget->setModel(mProxyModel); + ui->peerTreeWidget->setItemDelegate(new RSElidedItemDelegate()); + ui->peerTreeWidget->setWordWrap(false); /* Add filter actions */ QString headerText = mModel->headerData(RsFriendListModel::COLUMN_THREAD_NAME,Qt::Horizontal,Qt::DisplayRole).toString(); @@ -1255,7 +1259,7 @@ bool NewFriendList::exportFriendlist(QString &fileName) QDomElement pgpIDs = doc.createElement("pgpIDs"); RsPeerDetails detailPGP; - for(std::list::iterator list_iter = gpg_ids.begin(); list_iter != gpg_ids.end(); list_iter++) { + for(std::list::iterator list_iter = gpg_ids.begin(); list_iter != gpg_ids.end(); ++list_iter) { rsPeers->getGPGDetails(*list_iter, detailPGP); QDomElement pgpID = doc.createElement("pgpID"); // these values aren't used and just stored for better human readability @@ -1264,9 +1268,9 @@ bool NewFriendList::exportFriendlist(QString &fileName) std::list ssl_ids; rsPeers->getAssociatedSSLIds(*list_iter, ssl_ids); - for(std::list::iterator list_iter = ssl_ids.begin(); list_iter != ssl_ids.end(); list_iter++) { + for(std::list::iterator list_iter2 = ssl_ids.begin(); list_iter2 != ssl_ids.end(); ++list_iter2) { RsPeerDetails detailSSL; - if (!rsPeers->getPeerDetails(*list_iter, detailSSL)) + if (!rsPeers->getPeerDetails(*list_iter2, detailSSL)) continue; std::string certificate = rsPeers->GetRetroshareInvite(detailSSL.id, RetroshareInviteFlags::CURRENT_IP | RetroshareInviteFlags::DNS | RetroshareInviteFlags::RADIX_FORMAT); @@ -1291,7 +1295,7 @@ bool NewFriendList::exportFriendlist(QString &fileName) root.appendChild(pgpIDs); QDomElement groups = doc.createElement("groups"); - for(std::list::iterator list_iter = group_info_list.begin(); list_iter != group_info_list.end(); list_iter++) { + for(std::list::iterator list_iter = group_info_list.begin(); list_iter != group_info_list.end(); ++list_iter) { RsGroupInfo group_info = *list_iter; //skip groups without peers @@ -1303,7 +1307,7 @@ bool NewFriendList::exportFriendlist(QString &fileName) group.setAttribute("name", QString::fromUtf8(group_info.name.c_str())); group.setAttribute("flag", group_info.flag); - for(std::set::iterator i = group_info.peerIds.begin(); i != group_info.peerIds.end(); i++) { + for(std::set::iterator i = group_info.peerIds.begin(); i != group_info.peerIds.end(); ++i) { QDomElement pgpID = doc.createElement("pgpID"); std::string pid = i->toStdString(); pgpID.setAttribute("id", QString::fromStdString(pid)); @@ -1344,6 +1348,9 @@ static void showXMLParsingError() */ bool NewFriendList::importFriendlist(QString &fileName, bool &errorPeers, bool &errorGroups) { + errorPeers = false; + errorGroups = false; + QDomDocument doc; // load from file { @@ -1375,10 +1382,6 @@ bool NewFriendList::importFriendlist(QString &fileName, bool &errorPeers, bool & return false; } - errorPeers = false; - errorGroups = false; - - std::string error_string; RsPeerDetails rsPeerDetails; RsPeerId rsPeerID; RsPgpId rsPgpID; diff --git a/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp b/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp index 63ebb8ce4..34879b10c 100644 --- a/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp +++ b/retroshare-gui/src/gui/common/RSElidedItemDelegate.cpp @@ -309,21 +309,21 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & // draw the check mark if (ownOption.features & QStyleOptionViewItem::HasCheckIndicator) { - QStyleOptionViewItem option(*&ownOption); - option.rect = checkRect; - option.state = option.state & ~QStyle::State_HasFocus; + QStyleOptionViewItem cmOption(*&ownOption); + cmOption.rect = checkRect; + cmOption.state = cmOption.state & ~QStyle::State_HasFocus; switch (ownOption.checkState) { case Qt::Unchecked: - option.state |= QStyle::State_Off; + cmOption.state |= QStyle::State_Off; break; case Qt::PartiallyChecked: - option.state |= QStyle::State_NoChange; + cmOption.state |= QStyle::State_NoChange; break; case Qt::Checked: - option.state |= QStyle::State_On; + cmOption.state |= QStyle::State_On; break; } - ownStyle->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &option, painter, widget); + ownStyle->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &cmOption, painter, widget); } // draw the icon { @@ -340,7 +340,7 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & mode = QIcon::Disabled; else if (ownOption.state & QStyle::State_Selected) mode = QIcon::Selected; - QIcon::State state = ownOption.state & QStyle::State_Open ? QIcon::On : QIcon::Off; + QIcon::State state = (ownOption.state & QStyle::State_Open) ? QIcon::On : QIcon::Off; ownOption.icon.paint(painter, iconRect, ownOption.decorationAlignment, mode, state); } // Then overlay with waiting @@ -380,11 +380,12 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & QTextLayout textLayout(ownOption.text, painter->font()); QTextOption to = textLayout.textOption(); + to.setWrapMode((ownOption.features & QStyleOptionViewItem::WrapText) ? QTextOption::WordWrap : QTextOption::NoWrap); const int textHMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr, widget) + 1; const int textVMargin = ownStyle->pixelMetric(QStyle::PM_FocusFrameVMargin, nullptr, widget) + 1; textRect = textRect.adjusted(textHMargin, textVMargin, -textHMargin, -textVMargin); // remove width padding - StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode()&QTextOption::WordWrap,mPaintRoundedRect); + StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),mPaintRoundedRect); } painter->restore(); #ifdef DEBUG_EID_PAINT @@ -400,6 +401,7 @@ bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, if (ev->buttons()==Qt::LeftButton) { #ifdef DEBUG_EID_PAINT QVariant var = index.data(); + Q_UNUSED(var); #endif if (index.data().type() == QVariant::String) { QString text = index.data().toString(); @@ -430,10 +432,11 @@ bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, QTextLayout textLayout(text, ownOption.font); QTextOption to = textLayout.textOption(); + to.setWrapMode((ownOption.features & QStyleOptionViewItem::WrapText) ? QTextOption::WordWrap : QTextOption::NoWrap); //Update RSElidedItemDelegate as only one delegate for all items QRect rectElision; - bool elided = StyledElidedLabel::paintElidedLine(nullptr,text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode()&QTextOption::WordWrap,true,&rectElision); + bool elided = StyledElidedLabel::paintElidedLine(nullptr,text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode(),true,&rectElision); if (elided && (rectElision.contains(ev->pos()))){ QToolTip::showText(ev->globalPos(),QString("") + text + QString("")); return true; // eat event diff --git a/retroshare-gui/src/qss/blacknight.qss b/retroshare-gui/src/qss/blacknight.qss index 62adfe013..6291f5ca4 100644 --- a/retroshare-gui/src/qss/blacknight.qss +++ b/retroshare-gui/src/qss/blacknight.qss @@ -25,11 +25,11 @@ FriendSelectionWidget NewFriendList { - qproperty-textColorStatusOffline: white; - qproperty-textColorStatusAway: gray; - qproperty-textColorStatusBusy: gray; - qproperty-textColorStatusOnline: lightBlue; - qproperty-textColorStatusInactive: gray; + qproperty-textColorStatusAway: #4040A0; + qproperty-textColorStatusBusy: #A04040; + qproperty-textColorStatusOnline: #40A040; + qproperty-textColorStatusInactive: #A0A040; + qproperty-textColorStatusOffline: gray; qproperty-textColorGroup: rgb(123, 123, 123); } diff --git a/retroshare-gui/src/qss/qdarkstyle-v2.qss b/retroshare-gui/src/qss/qdarkstyle-v2.qss index 8a40da319..a3ec2cbbe 100644 --- a/retroshare-gui/src/qss/qdarkstyle-v2.qss +++ b/retroshare-gui/src/qss/qdarkstyle-v2.qss @@ -1945,11 +1945,12 @@ PlotWidget { } NewFriendList { - qproperty-textColorStatusAway: lightgray; - qproperty-textColorStatusBusy: lightgray; - qproperty-textColorStatusOnline: green; - qproperty-textColorStatusInactive: lightgray; + qproperty-textColorStatusAway: #4040A0; + qproperty-textColorStatusBusy: #A04040; + qproperty-textColorStatusOnline: #40A040; + qproperty-textColorStatusInactive: #A0A040; qproperty-textColorStatusOffline: gray; + qproperty-textColorGroup: rgb(123, 123, 123); } NetworkDialog { diff --git a/retroshare-gui/src/qss/qdarkstyle.qss b/retroshare-gui/src/qss/qdarkstyle.qss index b1cf7c023..76412701d 100644 --- a/retroshare-gui/src/qss/qdarkstyle.qss +++ b/retroshare-gui/src/qss/qdarkstyle.qss @@ -849,11 +849,12 @@ QDockWidget::close-button:pressed, QDockWidget::float-button:pressed { } NewFriendList { - qproperty-textColorStatusAway: lightgray; - qproperty-textColorStatusBusy: lightgray; - qproperty-textColorStatusOnline: green; - qproperty-textColorStatusInactive: lightgray; + qproperty-textColorStatusAway: #4040A0; + qproperty-textColorStatusBusy: #A04040; + qproperty-textColorStatusOnline: #40A040; + qproperty-textColorStatusInactive: #A0A040; qproperty-textColorStatusOffline: gray; + qproperty-textColorGroup: rgb(123, 123, 123); } QTreeView, QListView