From a053bedca2ee4a8dcbfd4b33f0ab60634b9c0914 Mon Sep 17 00:00:00 2001 From: csoler Date: Fri, 30 Oct 2020 23:22:52 +0100 Subject: [PATCH] partial attempt to fix selection in comments tree --- .../gui/Posted/PostedListWidgetWithModel.ui | 33 ++--- .../src/gui/gxs/GxsCommentTreeWidget.cpp | 128 ++++++++++++++++-- .../src/gui/gxs/GxsCommentTreeWidget.h | 2 + .../GxsChannelPostsWidgetWithModel.ui | 21 +-- 4 files changed, 148 insertions(+), 36 deletions(-) diff --git a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui index 2ddaa06eb..adcce3f23 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui +++ b/retroshare-gui/src/gui/Posted/PostedListWidgetWithModel.ui @@ -589,6 +589,23 @@ p, li { white-space: pre-wrap; } + + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
+
+ + RSTabWidget + QTabWidget +
gui/common/RSTabWidget.h
+ 1 +
+ + RSTreeView + QTreeView +
gui/common/RSTreeView.h
+ 1 +
GxsIdLabel QLabel @@ -599,27 +616,11 @@ p, li { white-space: pre-wrap; } QToolButton
gui/common/SubscribeToolButton.h
- - RSTreeView - QTreeView -
gui/common/RSTreeView.h
-
- - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
-
GxsIdChooser QComboBox
gui/gxs/GxsIdChooser.h
- - RSTabWidget - QTabWidget -
gui/common/RSTabWidget.h
- 1 -
diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp index ea65cfff7..9aaa742f8 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -84,7 +85,7 @@ public: { Q_ASSERT(index.isValid()); - QStyleOptionViewItemV4 opt = option; + QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // disable default icon opt.icon = QIcon(); @@ -136,11 +137,111 @@ private: QFontMetricsF qf; }; -GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) - :QTreeWidget(parent), mTokenQueue(NULL), mRsTokenService(NULL), mCommentService(NULL) +class GxsCommentDelegate: public QStyledItemDelegate { -// QTreeWidget* widget = this; +public: + GxsCommentDelegate(QFontMetricsF f) : qf(f){} + QSize sizeHint(const QStyleOptionViewItem &/*option*/, const QModelIndex &index) const override + { + return index.data(POST_CELL_SIZE_ROLE).toSize() ; + } + + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const override + { + editor->setGeometry(option.rect); + } + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override + { + if(index.column() == PCITEM_COLUMN_COMMENT) + { + QTextEdit *b = new QTextEdit(parent); + + b->setFixedSize(option.rect.size()); + b->setAcceptRichText(true); + b->setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::LinksAccessibleByMouse); + b->document()->setHtml(""+index.data(Qt::DisplayRole).toString()+""); + + std::cerr << "Creating QTextEdit of size " << option.rect.size().width() << " x " << option.rect.size().height() << std::endl; + return b; + } + else + return nullptr; + } + + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override + { + if((option.state & QStyle::State_Selected)) // Avoids double display. The selected widget is never exactly the size of the rendered one, + return; // so when selected, we only draw the selected one. + + Q_ASSERT(index.isValid()); + + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + // disable default icon + opt.icon = QIcon(); + opt.text = QString(); + + // draw default item background + if (option.state & QStyle::State_Selected) { + painter->fillRect(option.rect, option.palette.highlight()); + } else { + const QWidget *widget = opt.widget; + QStyle *style = widget ? widget->style() : QApplication::style(); + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, widget); + } + + const QRect r = option.rect.adjusted(0,0,-option.decorationSize.width(),0); + + QTextDocument td ; + td.setHtml(""+index.data(Qt::DisplayRole).toString()+""); + td.setTextWidth(r.width()); + QSizeF s = td.documentLayout()->documentSize(); + + int m = QFontMetricsF(QFont()).height(); + + QSize full_area(std::min(r.width(),(int)s.width())+m,std::min(r.height(),(int)s.height())+m); + + QPixmap px(full_area.width(),full_area.height()); + px.fill(QColor(0,0,0,0));//Transparent background as item background is already paint. + QPainter p(&px) ; + p.setRenderHint(QPainter::Antialiasing); + + QPainterPath path ; + path.addRoundedRect(QRectF(m/4.0,m/4.0,s.width()+m/2.0,s.height()+m/2.0),m,m) ; + QPen pen(Qt::gray,m/7.0f); + p.setPen(pen); + p.fillPath(path,QColor::fromHsv( index.data(POST_COLOR_ROLE).toInt()/255.0*360,40,220)); // varies the color according to the post author + p.drawPath(path); + + QAbstractTextDocumentLayout::PaintContext ctx; + ctx.clip = QRectF(0,0,s.width(),s.height()); + p.translate(QPointF(m/2.0,m/2.0)); + td.documentLayout()->draw( &p, ctx ); + + painter->drawPixmap(r.topLeft(),px); + + const_cast(index.model())->setData(index,px.size(),POST_CELL_SIZE_ROLE); + } + +private: + QFontMetricsF qf; +}; + +void GxsCommentTreeWidget::mouseMoveEvent(QMouseEvent *e) +{ + QModelIndex idx = indexAt(e->pos()); + + if(idx != selectionModel()->currentIndex()) + selectionModel()->setCurrentIndex(idx,QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows); + + QTreeView::mouseMoveEvent(e); +} + +GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) + :QTreeWidget(parent), mTokenQueue(NULL), mRsTokenService(NULL), mCommentService(NULL) +{ setVerticalScrollMode(ScrollPerPixel); setContextMenuPolicy(Qt::CustomContextMenu); RSElidedItemDelegate *itemDelegate = new RSElidedItemDelegate(this); @@ -148,11 +249,17 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent) setItemDelegate(itemDelegate); setWordWrap(true); - setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new MultiLinesCommentDelegate(QFontMetricsF(font()))) ; - + setMouseTracking(true); // for auto selection + setSelectionBehavior(QAbstractItemView::SelectRows); + + //setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new MultiLinesCommentDelegate(QFontMetricsF(font()))) ; + setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new GxsCommentDelegate(QFontMetricsF(font()))) ; + commentsRole = new RSTreeWidgetItemCompareRole; commentsRole->setRole(PCITEM_COLUMN_DATE, ROLE_SORT); + setEditTriggers(QAbstractItemView::CurrentChanged | QAbstractItemView::SelectedClicked); + mUseCache = false; // QFont font = QFont("ARIAL", 10); @@ -642,14 +749,14 @@ void GxsCommentTreeWidget::insertComments(const std::vector& comme } text = QString::fromUtf8(comment.mComment.c_str()); - item->setText(PCITEM_COLUMN_COMMENT, text); - item->setToolTip(PCITEM_COLUMN_COMMENT, text); + item->setText(PCITEM_COLUMN_COMMENT, text); + item->setToolTip(PCITEM_COLUMN_COMMENT, text); - RsGxsId authorId = comment.mMeta.mAuthorId; + RsGxsId authorId = comment.mMeta.mAuthorId; item->setId(authorId, PCITEM_COLUMN_AUTHOR, false); item->setData(PCITEM_COLUMN_COMMENT,POST_COLOR_ROLE,QVariant(authorId.toByteArray()[1])); - text = QString::number(comment.mScore); + text = QString::number(comment.mScore); item->setText(PCITEM_COLUMN_SCORE, text); text = QString::number(comment.mUpVotes); @@ -670,6 +777,7 @@ void GxsCommentTreeWidget::insertComments(const std::vector& comme text = QString::fromUtf8(comment.mMeta.mAuthorId.toStdString().c_str()); item->setText(PCITEM_COLUMN_AUTHORID, text); + item->setFlags(Qt::ItemIsEditable | item->flags());// allows to call createEditor() in the delegate addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item); } diff --git a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h index 7aef13337..014e529ee 100644 --- a/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h +++ b/retroshare-gui/src/gui/gxs/GxsCommentTreeWidget.h @@ -49,6 +49,8 @@ public: void setUseCache(bool b) { mUseCache = b ;} protected: + void mouseMoveEvent(QMouseEvent *e) override; + /* to be overloaded */ virtual void service_requestComments(const RsGxsGroupId &group_id, const std::set &msgIds); virtual void service_loadThread(const uint32_t &token); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui index a1daef1af..41e3d2a10 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidgetWithModel.ui @@ -612,6 +612,17 @@ p, li { white-space: pre-wrap; } + + LineEditClear + QLineEdit +
gui/common/LineEditClear.h
+
+ + RSTreeView + QTreeView +
gui/common/RSTreeView.h
+ 1 +
GxsIdLabel QLabel @@ -622,16 +633,6 @@ p, li { white-space: pre-wrap; } QToolButton
gui/common/SubscribeToolButton.h
- - RSTreeView - QTreeView -
gui/common/RSTreeView.h
-
- - LineEditClear - QLineEdit -
gui/common/LineEditClear.h
-
GxsCommentDialog QWidget