diff --git a/retroshare-gui/src/gui/common/ElidedLabel.cpp b/retroshare-gui/src/gui/common/ElidedLabel.cpp index 02c3881ff..15cdbd1ed 100644 --- a/retroshare-gui/src/gui/common/ElidedLabel.cpp +++ b/retroshare-gui/src/gui/common/ElidedLabel.cpp @@ -74,19 +74,9 @@ void ElidedLabel::clear() void ElidedLabel::paintEvent(QPaintEvent *event) { QLabel::paintEvent(event); - QList > lLines; - QString elidedLastLine = ""; + QPainter painter(this); - QFontMetrics fontMetrics = painter.fontMetrics(); - QRect cr = contentsRect(); - cr.adjust(margin(), margin(), -margin(), -margin()); - - bool didElide = false; - QChar ellipsisChar(0x2026);//= "…" - int lineSpacing = fontMetrics.lineSpacing(); - int y = 0; - - QString plainText = ""; + QString plainText = ""; if (mOnlyPlainText) { plainText = mContent; @@ -95,13 +85,38 @@ void ElidedLabel::paintEvent(QPaintEvent *event) td.setHtml(mContent); plainText = td.toPlainText(); } + QRect cr(contentsRect()); + cr.adjust(margin(), margin(), -margin(), -margin()); + + bool didElide = paintElidedLine(painter,plainText,cr,alignment(),wordWrap(),true,mRectElision); + + //Send signal if changed + + if (didElide != mElided) + { + mElided = didElide; + emit elisionChanged(didElide); + } +} + +bool ElidedLabel::paintElidedLine(QPainter& painter,QString plainText,const QRect& cr,Qt::Alignment alignment,bool wordWrap,bool drawRoundRect,QRect& rectElision) +{ + QList > lLines; + QString elidedLastLine = ""; + QFontMetrics fontMetrics = painter.fontMetrics(); + + bool didElide = false; + QChar ellipsisChar(0x2026);//= "…" + int lineSpacing = fontMetrics.lineSpacing(); + int y = 0; + plainText = plainText.replace("\n",QChar(QChar::LineSeparator)); plainText = plainText.replace("\r",QChar(QChar::LineSeparator)); QTextLayout textLayout(plainText, painter.font()); QTextOption to = textLayout.textOption(); - to.setAlignment(alignment()); - to.setWrapMode(wordWrap() ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap); + to.setAlignment(alignment); + to.setWrapMode(wordWrap ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap); textLayout.setTextOption(to); textLayout.beginLayout(); @@ -115,7 +130,7 @@ void ElidedLabel::paintEvent(QPaintEvent *event) line.setLineWidth(cr.width()); int nextLineY = y + lineSpacing; - if ((cr.height() >= nextLineY + lineSpacing) && wordWrap()) { + if ((cr.height() >= nextLineY + lineSpacing) && wordWrap) { //Line written normaly, next line will too lLines.append(QPair(line, QPoint(0, y))); y = nextLineY; @@ -123,8 +138,7 @@ void ElidedLabel::paintEvent(QPaintEvent *event) //The next line can't be written. QString lastLine = plainText.mid(line.textStart()).split(QChar(QChar::LineSeparator)).at(0); QTextLine lineEnd = textLayout.createLine(); - if (!lineEnd.isValid() && (wordWrap() - || (fontMetrics.width(lastLine) < cr.width()))) { + if (!lineEnd.isValid() && (wordWrap || (fontMetrics.width(lastLine) < cr.width()))) { //No more text for next line so this one is OK lLines.append(QPair(line, QPoint(0, y))); elidedLastLine=""; @@ -150,11 +164,11 @@ void ElidedLabel::paintEvent(QPaintEvent *event) if (didElide) iHeight += lineSpacing; //Compute lines translation with alignment - if (alignment() & Qt::AlignTop) + if (alignment & Qt::AlignTop) iTransY = 0; - if (alignment() & Qt::AlignBottom) + if (alignment & Qt::AlignBottom) iTransY = cr.height() - iHeight; - if (alignment() & Qt::AlignVCenter) + if (alignment & Qt::AlignVCenter) iTransY = (cr.height() - iHeight) / 2; QPair pair; @@ -166,7 +180,8 @@ void ElidedLabel::paintEvent(QPaintEvent *event) } //Print last elided line - if (didElide) { + if (didElide) + { int width = fontMetrics.width(elidedLastLine); if (lastPos.y() == -1){ y = iTransY;// Only one line @@ -175,32 +190,35 @@ void ElidedLabel::paintEvent(QPaintEvent *event) } if (width < cr.width()){ //Text don't taking all line (with line break), so align it - if (alignment() & Qt::AlignLeft) + if (alignment & Qt::AlignLeft) iTransX = 0; - if (alignment() & Qt::AlignRight) + if (alignment & Qt::AlignRight) iTransX = cr.width() - width; - if (alignment() & Qt::AlignHCenter) + if (alignment & Qt::AlignHCenter) iTransX = (cr.width() - width) / 2; - if (alignment() & Qt::AlignJustify) + if (alignment & Qt::AlignJustify) iTransX = 0; } painter.drawText(QPoint(iTransX + cr.left(), y + fontMetrics.ascent() + cr.top()), elidedLastLine); //Draw button to get ToolTip - mRectElision = QRect(iTransX + width - fontMetrics.width(ellipsisChar) + cr.left() - , y + cr.top() - , fontMetrics.width(ellipsisChar) - , fontMetrics.height() - 1); - painter.drawRoundRect(mRectElision); - } else { - mRectElision = QRect(); - } - //Send signal if changed - if (didElide != mElided) { - mElided = didElide; - emit elisionChanged(didElide); + if(drawRoundRect) + { + rectElision = QRect(iTransX + width - fontMetrics.width(ellipsisChar) + cr.left() + , y + cr.top() + , fontMetrics.width(ellipsisChar) + , fontMetrics.height() - 1); + painter.drawRoundRect(rectElision); + } + else + rectElision = QRect(); } + else + rectElision = QRect(); + + return didElide; + } void ElidedLabel::mousePressEvent(QMouseEvent *ev) diff --git a/retroshare-gui/src/gui/common/ElidedLabel.h b/retroshare-gui/src/gui/common/ElidedLabel.h index 3b935e444..866af18ed 100644 --- a/retroshare-gui/src/gui/common/ElidedLabel.h +++ b/retroshare-gui/src/gui/common/ElidedLabel.h @@ -48,6 +48,8 @@ public: QColor textColor() const { return mTextColor; } void setTextColor(const QColor &color); + static bool paintElidedLine(QPainter& painter, QString plainText, const QRect &cr, Qt::Alignment alignment, bool wordWrap, bool drawRoundRect, QRect &rectElision); + public slots: void setText(const QString &text); void setOnlyPlainText(const bool &value); diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp index 5bfcdf93b..39e0f0216 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp @@ -178,3 +178,104 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const return RSTreeWidgetItem::data(column, role); } + +QSize GxsIdTreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + RsGxsId id(index.data(Qt::UserRole).toString().toStdString()); + + if(id.isNull()) + return QStyledItemDelegate::sizeHint(option,index); + + QStyleOptionViewItemV4 opt = option; + initStyleOption(&opt, index); + + // disable default icon + opt.icon = QIcon(); + const QRect r = option.rect; + QString str; + QList icons; + QString comment; + + QFontMetricsF fm(option.font); + float f = fm.height(); + + QIcon icon ; + + if(!GxsIdDetails::MakeIdDesc(id, true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR)) + { + icon = GxsIdDetails::getLoadingIcon(id); + launchAsyncLoading(); + } + else + icon = *icons.begin(); + + QPixmap pix = icon.pixmap(r.size()); + + return QSize(1.2*(pix.width() + fm.width(str)),std::max(1.1*pix.height(),1.4*fm.height())); +} + + +void GxsIdTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const +{ + if(!index.isValid()) + { + std::cerr << "(EE) attempt to draw an invalid index." << std::endl; + return ; + } + + RsGxsId id(index.data(Qt::UserRole).toString().toStdString()); + + if(id.isNull()) + return QStyledItemDelegate::paint(painter,option,index); + + QStyleOptionViewItemV4 opt = option; + initStyleOption(&opt, index); + + // disable default icon + opt.icon = QIcon(); + // draw default item + QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0); + + QRect r = option.rect; + + QString str; + QString comment; + + QFontMetricsF fm(painter->font()); + float f = fm.height(); + + QIcon icon ; + + if(id.isNull()) + { + str = tr("[Notification]"); + icon = QIcon(":/icons/logo_128.png"); + } + else if(! computeNameIconAndComment(id,str,icon,comment)) + if(mReloadPeriod > 3) + { + str = tr("[Unknown]"); + icon = QIcon(); + } + else + { + icon = GxsIdDetails::getLoadingIcon(id); + launchAsyncLoading(); + } + + QPixmap pix = icon.pixmap(r.size()); + const QPoint p = QPoint(r.height()/2.0, (r.height() - pix.height())/2); + + // draw pixmap at center of item + painter->drawPixmap(r.topLeft() + p, pix); + //painter->drawText(r.topLeft() + QPoint(r.height()+ f/2.0 + f/2.0,f*1.0), str); + + //cr.adjust(margin(), margin(), -margin(), -margin()); + + QRect mRectElision; + + r.adjust(pix.height()+f,(r.height()-f)/2.0,0,0); + + bool didElide = ElidedLabel::paintElidedLine(*painter,str,r,Qt::AlignLeft,false,false,mRectElision); + +} diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h index 8e7cccb3f..fa225856d 100644 --- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h +++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h @@ -24,10 +24,11 @@ #include #include #include -#include -#include +#include "retroshare/rsidentity.h" +#include "retroshare/rspeers.h" #include "gui/common/RSTreeWidgetItem.h" +#include "gui/common/ElidedLabel.h" #include "gui/gxs/GxsIdDetails.h" /***** @@ -88,96 +89,8 @@ public: mReloadPeriod = 0; } - QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override - { - RsGxsId id(index.data(Qt::UserRole).toString().toStdString()); - - if(id.isNull()) - return QStyledItemDelegate::sizeHint(option,index); - - QStyleOptionViewItemV4 opt = option; - initStyleOption(&opt, index); - - // disable default icon - opt.icon = QIcon(); - const QRect r = option.rect; - QString str; - QList icons; - QString comment; - - QFontMetricsF fm(option.font); - float f = fm.height(); - - QIcon icon ; - - if(!GxsIdDetails::MakeIdDesc(id, true, str, icons, comment,GxsIdDetails::ICON_TYPE_AVATAR)) - { - icon = GxsIdDetails::getLoadingIcon(id); - launchAsyncLoading(); - } - else - icon = *icons.begin(); - - QPixmap pix = icon.pixmap(r.size()); - - return QSize(1.2*(pix.width() + fm.width(str)),std::max(1.1*pix.height(),1.4*fm.height())); - } - - virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override - { - if(!index.isValid()) - { - std::cerr << "(EE) attempt to draw an invalid index." << std::endl; - return ; - } - - RsGxsId id(index.data(Qt::UserRole).toString().toStdString()); - - if(id.isNull()) - return QStyledItemDelegate::paint(painter,option,index); - - QStyleOptionViewItemV4 opt = option; - initStyleOption(&opt, index); - - // disable default icon - opt.icon = QIcon(); - // draw default item - QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, 0); - - const QRect r = option.rect; - - QString str; - QString comment; - - QFontMetricsF fm(painter->font()); - float f = fm.height(); - - QIcon icon ; - - if(id.isNull()) - { - str = tr("[Notification]"); - icon = QIcon(":/icons/logo_128.png"); - } - else if(! computeNameIconAndComment(id,str,icon,comment)) - if(mReloadPeriod > 3) - { - str = tr("[Unknown]"); - icon = QIcon(); - } - else - { - icon = GxsIdDetails::getLoadingIcon(id); - launchAsyncLoading(); - } - - QPixmap pix = icon.pixmap(r.size()); - const QPoint p = QPoint(r.height()/2.0, (r.height() - pix.height())/2); - - // draw pixmap at center of item - painter->drawPixmap(r.topLeft() + p, pix); - painter->drawText(r.topLeft() + QPoint(r.height()+ f/2.0 + f/2.0,f*1.0), str); - } + QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex& index) const override; void launchAsyncLoading() const {