mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-12-17 09:34:10 -05:00
best version so far to allow copy of data using a QTextEdit in comments (needs to enable the USE_NEW_DELEGATE #ifdef)
This commit is contained in:
parent
a053bedca2
commit
d868ee3e42
3 changed files with 82 additions and 54 deletions
|
|
@ -146,7 +146,7 @@ void PostedPostDelegate::paint(QPainter * painter, const QStyleOptionViewItem &
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize PostedPostDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
|
QSize PostedPostDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
// This is the only place where we actually set the size of cells
|
// This is the only place where we actually set the size of cells
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
|
#include <QHeaderView>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
@ -69,6 +70,8 @@
|
||||||
std::map<RsGxsMessageId, std::vector<RsGxsComment> > GxsCommentTreeWidget::mCommentsCache;
|
std::map<RsGxsMessageId, std::vector<RsGxsComment> > GxsCommentTreeWidget::mCommentsCache;
|
||||||
QMutex GxsCommentTreeWidget::mCacheMutex;
|
QMutex GxsCommentTreeWidget::mCacheMutex;
|
||||||
|
|
||||||
|
//#define USE_NEW_DELEGATE 1
|
||||||
|
|
||||||
// This class allows to draw the item using an appropriate size
|
// This class allows to draw the item using an appropriate size
|
||||||
|
|
||||||
class MultiLinesCommentDelegate: public QStyledItemDelegate
|
class MultiLinesCommentDelegate: public QStyledItemDelegate
|
||||||
|
|
@ -78,6 +81,7 @@ public:
|
||||||
|
|
||||||
QSize sizeHint(const QStyleOptionViewItem &/*option*/, const QModelIndex &index) const
|
QSize sizeHint(const QStyleOptionViewItem &/*option*/, const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
|
std::cerr << "SizeHint called with size=" << index.data(POST_CELL_SIZE_ROLE).toSize().width() << " x " <<index.data(POST_CELL_SIZE_ROLE).toSize().height() << std::endl;
|
||||||
return index.data(POST_CELL_SIZE_ROLE).toSize() ;
|
return index.data(POST_CELL_SIZE_ROLE).toSize() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +112,6 @@ public:
|
||||||
QSizeF s = td.documentLayout()->documentSize();
|
QSizeF s = td.documentLayout()->documentSize();
|
||||||
|
|
||||||
int m = QFontMetricsF(QFont()).height();
|
int m = QFontMetricsF(QFont()).height();
|
||||||
|
|
||||||
QSize full_area(std::min(r.width(),(int)s.width())+m,std::min(r.height(),(int)s.height())+m);
|
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());
|
QPixmap px(full_area.width(),full_area.height());
|
||||||
|
|
@ -116,17 +119,19 @@ public:
|
||||||
QPainter p(&px) ;
|
QPainter p(&px) ;
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
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) ;
|
QPainterPath path ;
|
||||||
QPen pen(Qt::gray,m/7.0f);
|
path.addRoundedRect(QRectF(m/4.0,m/4.0,s.width()+m/2.0,s.height()+m/2.0),m,m) ;
|
||||||
p.setPen(pen);
|
QPen pen(Qt::gray,m/7.0f);
|
||||||
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.setPen(pen);
|
||||||
p.drawPath(path);
|
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;
|
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||||
ctx.clip = QRectF(0,0,s.width(),s.height());
|
ctx.clip = QRectF(0,0,s.width(),s.height());
|
||||||
p.translate(QPointF(m/2.0,m/2.0));
|
p.translate(QPointF(m/2.0,m/2.0));
|
||||||
td.documentLayout()->draw( &p, ctx );
|
td.documentLayout()->draw( &p, ctx );
|
||||||
|
}
|
||||||
|
|
||||||
painter->drawPixmap(r.topLeft(),px);
|
painter->drawPixmap(r.topLeft(),px);
|
||||||
|
|
||||||
|
|
@ -137,19 +142,33 @@ private:
|
||||||
QFontMetricsF qf;
|
QFontMetricsF qf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NoEditDelegate: public QStyledItemDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NoEditDelegate(QObject* parent=0): QStyledItemDelegate(parent) {}
|
||||||
|
virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class GxsCommentDelegate: public QStyledItemDelegate
|
class GxsCommentDelegate: public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GxsCommentDelegate(QFontMetricsF f) : qf(f){}
|
GxsCommentDelegate(QFontMetricsF f) : qf(f){}
|
||||||
|
|
||||||
QSize sizeHint(const QStyleOptionViewItem &/*option*/, const QModelIndex &index) const override
|
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
|
QSize s = QStyledItemDelegate::sizeHint(option,index);
|
||||||
|
|
||||||
|
std::cerr << "SizeHint called with size=" << index.data(POST_CELL_SIZE_ROLE).toSize().width() << " x " <<index.data(POST_CELL_SIZE_ROLE).toSize().height() << std::endl;
|
||||||
return index.data(POST_CELL_SIZE_ROLE).toSize() ;
|
return index.data(POST_CELL_SIZE_ROLE).toSize() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const override
|
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex& index) const override
|
||||||
{
|
{
|
||||||
editor->setGeometry(option.rect);
|
if(index.column() == PCITEM_COLUMN_COMMENT)
|
||||||
|
editor->setGeometry(option.rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
|
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
|
||||||
|
|
@ -158,12 +177,13 @@ public:
|
||||||
{
|
{
|
||||||
QTextEdit *b = new QTextEdit(parent);
|
QTextEdit *b = new QTextEdit(parent);
|
||||||
|
|
||||||
|
b->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
b->setFixedSize(option.rect.size());
|
b->setFixedSize(option.rect.size());
|
||||||
b->setAcceptRichText(true);
|
b->setAcceptRichText(true);
|
||||||
b->setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::LinksAccessibleByMouse);
|
b->setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::LinksAccessibleByMouse);
|
||||||
b->document()->setHtml("<html>"+index.data(Qt::DisplayRole).toString()+"</html>");
|
b->document()->setHtml("<html>"+index.data(Qt::DisplayRole).toString()+"</html>");
|
||||||
|
b->adjustSize();
|
||||||
|
|
||||||
std::cerr << "Creating QTextEdit of size " << option.rect.size().width() << " x " << option.rect.size().height() << std::endl;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -183,15 +203,6 @@ public:
|
||||||
opt.icon = QIcon();
|
opt.icon = QIcon();
|
||||||
opt.text = QString();
|
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);
|
const QRect r = option.rect.adjusted(0,0,-option.decorationSize.width(),0);
|
||||||
|
|
||||||
QTextDocument td ;
|
QTextDocument td ;
|
||||||
|
|
@ -199,7 +210,8 @@ public:
|
||||||
td.setTextWidth(r.width());
|
td.setTextWidth(r.width());
|
||||||
QSizeF s = td.documentLayout()->documentSize();
|
QSizeF s = td.documentLayout()->documentSize();
|
||||||
|
|
||||||
int m = QFontMetricsF(QFont()).height();
|
int m = QFontMetricsF(QFont()).height() ;
|
||||||
|
//int m = 2;
|
||||||
|
|
||||||
QSize full_area(std::min(r.width(),(int)s.width())+m,std::min(r.height(),(int)s.height())+m);
|
QSize full_area(std::min(r.width(),(int)s.width())+m,std::min(r.height(),(int)s.height())+m);
|
||||||
|
|
||||||
|
|
@ -208,19 +220,18 @@ public:
|
||||||
QPainter p(&px) ;
|
QPainter p(&px) ;
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
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) ;
|
QTextEdit b;
|
||||||
QPen pen(Qt::gray,m/7.0f);
|
b.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
p.setPen(pen);
|
b.setFixedSize(full_area);
|
||||||
p.fillPath(path,QColor::fromHsv( index.data(POST_COLOR_ROLE).toInt()/255.0*360,40,220)); // varies the color according to the post author
|
b.setAcceptRichText(true);
|
||||||
p.drawPath(path);
|
b.setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::LinksAccessibleByMouse);
|
||||||
|
b.document()->setHtml("<html>"+index.data(Qt::DisplayRole).toString()+"</html>");
|
||||||
|
b.adjustSize();
|
||||||
|
b.render(&p,QPoint(),QRegion(),QWidget::DrawChildren );// draw the widgets, not the background
|
||||||
|
}
|
||||||
|
|
||||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
painter->drawPixmap(opt.rect.topLeft(),px);
|
||||||
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<QAbstractItemModel*>(index.model())->setData(index,px.size(),POST_CELL_SIZE_ROLE);
|
const_cast<QAbstractItemModel*>(index.model())->setData(index,px.size(),POST_CELL_SIZE_ROLE);
|
||||||
}
|
}
|
||||||
|
|
@ -252,9 +263,22 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent)
|
||||||
setMouseTracking(true); // for auto selection
|
setMouseTracking(true); // for auto selection
|
||||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
|
||||||
//setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new MultiLinesCommentDelegate(QFontMetricsF(font()))) ;
|
#ifdef USE_NEW_DELEGATE
|
||||||
setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new GxsCommentDelegate(QFontMetricsF(font()))) ;
|
setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new GxsCommentDelegate(QFontMetricsF(font()))) ;
|
||||||
|
|
||||||
|
// Apparently the following below is needed, since there is no way to set item flags for a single column
|
||||||
|
// so after setting flags Qt will believe that all columns are editable.
|
||||||
|
|
||||||
|
setItemDelegateForColumn(PCITEM_COLUMN_AUTHOR, new NoEditDelegate(this));
|
||||||
|
setItemDelegateForColumn(PCITEM_COLUMN_DATE, new NoEditDelegate(this));
|
||||||
|
setItemDelegateForColumn(PCITEM_COLUMN_SCORE, new NoEditDelegate(this));
|
||||||
|
setItemDelegateForColumn(PCITEM_COLUMN_UPVOTES, new NoEditDelegate(this));
|
||||||
|
setItemDelegateForColumn(PCITEM_COLUMN_DOWNVOTES,new NoEditDelegate(this));
|
||||||
|
setItemDelegateForColumn(PCITEM_COLUMN_OWNVOTE, new NoEditDelegate(this));
|
||||||
|
#else
|
||||||
|
setItemDelegateForColumn(PCITEM_COLUMN_COMMENT,new MultiLinesCommentDelegate(QFontMetricsF(font()))) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
commentsRole = new RSTreeWidgetItemCompareRole;
|
commentsRole = new RSTreeWidgetItemCompareRole;
|
||||||
commentsRole->setRole(PCITEM_COLUMN_DATE, ROLE_SORT);
|
commentsRole->setRole(PCITEM_COLUMN_DATE, ROLE_SORT);
|
||||||
|
|
||||||
|
|
@ -262,22 +286,19 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent)
|
||||||
|
|
||||||
mUseCache = false;
|
mUseCache = false;
|
||||||
|
|
||||||
// QFont font = QFont("ARIAL", 10);
|
QObject::connect(header(),SIGNAL(geometriesChanged()),this,SLOT(updateContent()));
|
||||||
// font.setBold(true);
|
QObject::connect(header(),SIGNAL(sectionResized(int,int,int)),this,SLOT(updateContent()));
|
||||||
|
|
||||||
// QString name("test");
|
//header()->setSectionResizeMode(PCITEM_COLUMN_COMMENT,QHeaderView::ResizeToContents);
|
||||||
// QTreeWidgetItem *item = new QTreeWidgetItem();
|
return;
|
||||||
// item->setText(0, name);
|
|
||||||
// item->setFont(0, font);
|
|
||||||
// item->setSizeHint(0, QSize(18, 18));
|
|
||||||
// item->setForeground(0, QBrush(QColor(79, 79, 79)));
|
|
||||||
|
|
||||||
// addTopLevelItem(item);
|
|
||||||
// item->setExpanded(true);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsCommentTreeWidget::updateContent()
|
||||||
|
{
|
||||||
|
model()->dataChanged(QModelIndex(),QModelIndex());
|
||||||
|
|
||||||
|
std::cerr << "Updating content" << std::endl;
|
||||||
|
}
|
||||||
GxsCommentTreeWidget::~GxsCommentTreeWidget()
|
GxsCommentTreeWidget::~GxsCommentTreeWidget()
|
||||||
{
|
{
|
||||||
if (mTokenQueue) {
|
if (mTokenQueue) {
|
||||||
|
|
@ -777,7 +798,11 @@ void GxsCommentTreeWidget::insertComments(const std::vector<RsGxsComment>& comme
|
||||||
text = QString::fromUtf8(comment.mMeta.mAuthorId.toStdString().c_str());
|
text = QString::fromUtf8(comment.mMeta.mAuthorId.toStdString().c_str());
|
||||||
item->setText(PCITEM_COLUMN_AUTHORID, text);
|
item->setText(PCITEM_COLUMN_AUTHORID, text);
|
||||||
|
|
||||||
item->setFlags(Qt::ItemIsEditable | item->flags());// allows to call createEditor() in the delegate
|
#ifdef USE_NEW_DELEGATE
|
||||||
|
// Allows to call createEditor() in the delegate. Without this, createEditor() is never called in
|
||||||
|
// the styled item delegate.
|
||||||
|
item->setFlags(Qt::ItemIsEditable | item->flags());
|
||||||
|
#endif
|
||||||
|
|
||||||
addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item);
|
addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,11 @@ public:
|
||||||
void setVoteId(const RsGxsId &voterId);
|
void setVoteId(const RsGxsId &voterId);
|
||||||
|
|
||||||
void setUseCache(bool b) { mUseCache = b ;}
|
void setUseCache(bool b) { mUseCache = b ;}
|
||||||
protected:
|
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void updateContent();
|
||||||
|
|
||||||
|
protected:
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
|
|
||||||
/* to be overloaded */
|
/* to be overloaded */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue