From 32a74e20e111f2aa88bb4c0dd9a0a3840bcc166b Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 21 Nov 2017 14:45:22 +0000 Subject: [PATCH] Extract out most code for text-with-ResourceId-links from RDTreeWidget * The RDTreeWidget items still use this code, but it can now be reused on other widgets like RDLabel. --- qrenderdoc/Code/QRDUtils.cpp | 271 +++++++++++++ qrenderdoc/Code/QRDUtils.h | 41 ++ qrenderdoc/Code/qrenderdoc.cpp | 2 + qrenderdoc/Widgets/Extended/RDTreeWidget.cpp | 382 +++---------------- 4 files changed, 368 insertions(+), 328 deletions(-) diff --git a/qrenderdoc/Code/QRDUtils.cpp b/qrenderdoc/Code/QRDUtils.cpp index e02ae5aab..90da2baf1 100644 --- a/qrenderdoc/Code/QRDUtils.cpp +++ b/qrenderdoc/Code/QRDUtils.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "QRDUtils.h" +#include #include #include #include @@ -34,11 +35,15 @@ #include #include #include +#include +#include #include #include #include #include #include +#include +#include #include #include "Widgets/Extended/RDTreeWidget.h" @@ -60,6 +65,272 @@ std::string DoStringise(const ResourceId &el) return lit("resourceid::%1").arg(num).toStdString(); } +struct RichResourceText +{ + QVector fragments; + + // cached formatted document. We use cacheId to check if it needs to be updated + QTextDocument doc; + int cacheId = 0; + + // a plain-text version of the document, suitable for e.g. copy-paste + QString text; + + // cache the context once we've obtained it. + ICaptureContext *ctxptr = NULL; + + void cacheDocument(QWidget *widget) + { + if(!ctxptr) + ctxptr = getCaptureContext(widget); + + if(!ctxptr) + return; + + ICaptureContext &ctx = *(ICaptureContext *)ctxptr; + + int refCache = ctx.ResourceNameCacheID(); + + if(cacheId == refCache) + return; + + cacheId = refCache; + + // use a table to ensure images don't screw up the baseline for text. DON'T JUDGE ME. + QString html = lit(""); + + int i = 0; + + QVector fragmentIndexFromBlockIndex; + + // there's an empty block at the start. + fragmentIndexFromBlockIndex.push_back(-1); + + text.clear(); + + for(const QVariant &v : fragments) + { + if(v.userType() == qMetaTypeId()) + { + QString resname = ctx.GetResourceName(v.value()); + html += lit("").arg(resname); + text += resname; + + // these generate two blocks (one for each cell) + fragmentIndexFromBlockIndex.push_back(i); + fragmentIndexFromBlockIndex.push_back(i); + } + else + { + html += lit("").arg(v.toString()); + text += v.toString(); + + // this only generates one block + fragmentIndexFromBlockIndex.push_back(i); + } + + i++; + } + + // there's another empty block at the end + fragmentIndexFromBlockIndex.push_back(-1); + + html += lit("
%1%1
"); + + doc.setDocumentMargin(0); + doc.setHtml(html); + + if(doc.blockCount() != fragmentIndexFromBlockIndex.count()) + { + qCritical() << "Block count is not what's expected!" << doc.blockCount() + << fragmentIndexFromBlockIndex.count(); + + for(i = 0; i < doc.blockCount(); i++) + doc.findBlockByNumber(i).setUserState(-1); + + return; + } + + for(i = 0; i < doc.blockCount(); i++) + doc.findBlockByNumber(i).setUserState(fragmentIndexFromBlockIndex[i]); + } +}; + +Q_DECLARE_METATYPE(RichResourceTextPtr); + +QString ResIdTextToString(RichResourceTextPtr ptr) +{ + return ptr->text; +} + +void RegisterMetatypeConversions() +{ + QMetaType::registerConverter(&ResIdTextToString); +} + +void RichResourceTextInitialise(QVariant &var) +{ + static QRegularExpression re(lit("(resourceid::)([0-9]*)")); + + if(var.userType() == qMetaTypeId() || re.match(var.toString()).hasMatch()) + { + QString text; + if(var.userType() == qMetaTypeId()) + text = ToQStr(var.value()); + else + text = var.toString(); + + RichResourceTextPtr linkedText(new RichResourceText); + + // use regexp to split up into fragments of text and resourceid. The resourceid is then + // formatted on the fly in RichResourceText::cacheDocument + QRegularExpressionMatch match = re.match(text); + while(match.hasMatch()) + { + qulonglong idnum = match.captured(2).toULongLong(); + ResourceId id; + memcpy(&id, &idnum, sizeof(id)); + + // push any text that preceeded the ResourceId. + if(match.capturedStart(1) > 0) + linkedText->fragments.push_back(text.left(match.capturedStart(1))); + + text.remove(0, match.capturedEnd(2)); + + linkedText->fragments.push_back(id); + + match = re.match(text); + } + + if(!text.isEmpty()) + linkedText->fragments.push_back(text); + + linkedText->doc.setHtml(text); + + var = QVariant::fromValue(linkedText); + } +} + +bool RichResourceTextCheck(const QVariant &var) +{ + return var.userType() == qMetaTypeId(); +} + +void RichResourceTextPaint(QWidget *owner, QPainter *painter, QRect rect, QFont font, + QPalette palette, bool mouseOver, QPoint mousePos, const QVariant &var) +{ + RichResourceTextPtr linkedText = var.value(); + + linkedText->cacheDocument(owner); + + painter->translate(rect.left(), rect.top()); + + linkedText->doc.setTextWidth(rect.width()); + linkedText->doc.setDefaultFont(font); + linkedText->doc.drawContents(painter); + + if(mouseOver) + { + painter->setPen(QPen(palette.brush(QPalette::WindowText), 1.0)); + + QAbstractTextDocumentLayout *layout = linkedText->doc.documentLayout(); + + QPoint p = mousePos - rect.topLeft(); + + int pos = layout->hitTest(p, Qt::FuzzyHit); + + if(pos >= 0) + { + QTextBlock block = linkedText->doc.findBlock(pos); + + int frag = block.userState(); + if(frag >= 0) + { + QVariant v = linkedText->fragments[frag]; + if(v.userType() == qMetaTypeId() && v.value() != ResourceId()) + { + layout->blockBoundingRect(block); + QRectF blockrect = layout->blockBoundingRect(block); + + if(block.previous().userState() == frag) + { + blockrect = blockrect.united(layout->blockBoundingRect(block.previous())); + } + + if(block.next().userState() == frag) + { + blockrect = blockrect.united(layout->blockBoundingRect(block.next())); + } + + blockrect.translate(0.0, -2.0); + + painter->drawLine(blockrect.bottomLeft(), blockrect.bottomRight()); + } + } + } + } +} + +int RichResourceTextWidthHint(QWidget *owner, const QVariant &var) +{ + RichResourceTextPtr linkedText = var.value(); + + linkedText->cacheDocument(owner); + + return linkedText->doc.idealWidth(); +} + +bool RichResourceTextMouseEvent(QWidget *owner, const QVariant &var, QRect rect, QMouseEvent *event) +{ + // only process clicks or moves + if(event->type() != QEvent::MouseButtonRelease && event->type() != QEvent::MouseMove) + return false; + + RichResourceTextPtr linkedText = var.value(); + + linkedText->cacheDocument(owner); + + QAbstractTextDocumentLayout *layout = linkedText->doc.documentLayout(); + + QPoint p = event->pos() - rect.topLeft(); + + int pos = layout->hitTest(p, Qt::FuzzyHit); + + if(pos >= 0) + { + QTextBlock block = linkedText->doc.findBlock(pos); + + int frag = block.userState(); + if(frag >= 0) + { + QVariant v = linkedText->fragments[frag]; + if(v.userType() == qMetaTypeId()) + { + // empty resource ids are not clickable or hover-highlighted. + ResourceId res = v.value(); + if(res == ResourceId()) + return false; + + if(event->type() == QEvent::MouseButtonRelease && linkedText->ctxptr) + { + ICaptureContext &ctx = *(ICaptureContext *)linkedText->ctxptr; + + if(!ctx.HasResourceInspector()) + ctx.ShowResourceInspector(); + + ctx.GetResourceInspector()->Inspect(v.value()); + + ctx.RaiseDockWindow(ctx.GetResourceInspector()->Widget()); + } + + return true; + } + } + } + + return false; +} + #include "renderdoc_tostr.inl" QString ToQStr(const ResourceUsage usage, const GraphicsAPI apitype) diff --git a/qrenderdoc/Code/QRDUtils.h b/qrenderdoc/Code/QRDUtils.h index 09053a5ba..f6ab19b6c 100644 --- a/qrenderdoc/Code/QRDUtils.h +++ b/qrenderdoc/Code/QRDUtils.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include "Code/Interface/QRDInterface.h" @@ -107,6 +108,46 @@ class RDTreeWidgetItem; void addStructuredObjects(RDTreeWidgetItem *parent, const StructuredObjectList &objs, bool parentIsArray); +// this is an opaque struct that contains the data to render, hit-test, etc for some text that +// contains links to resources. It will update and cache the names of the resources. +struct RichResourceText; + +// we use QSharedPointer to refer to the text since the lifetime management of these objects would +// get quite complicated. There's not necessarily an obvious QObject parent to assign to if the text +// is being initialised before being assigned to a widget and we want the most seamless interface we +// can get. +typedef QSharedPointer RichResourceTextPtr; + +// this will check the variant, and if it contains a ResourceId directly or text with ResourceId +// identifiers then it will be converted into a RichResourceTextPtr in-place. The new QVariant will +// still convert to QString so it doesn't have to be special-cased. However it must be processed +// through one of the functions below (generally painting) to cache the rendered text. +// If the variant doesn't match the above conditions, it's unchanged. So it's safe to apply this +// reasonably liberally. +// NOTE: It is not possible to move a RichResourceText instance from one ICaptureContext to another +// as the pointer is cached internally. Instead you should delete the old and re-initialise from +// scratch. +void RichResourceTextInitialise(QVariant &var); + +// checks if a variant is rich resource text +bool RichResourceTextCheck(const QVariant &var); + +// paint the given variant containing rich text with the given parameters. +void RichResourceTextPaint(QWidget *owner, QPainter *painter, QRect rect, QFont font, + QPalette palette, bool mouseOver, QPoint mousePos, const QVariant &var); + +// gives the width for a size hint for the rich text (since it might be larger than the original +// text) +int RichResourceTextWidthHint(QWidget *owner, const QVariant &var); + +// handle a mouse event on some rich resource text. +// returns true if the event is processed - for mouse move events, this means that the mouse is over +// a resource link (which can be used to change the cursor to a pointing hand, for example). +bool RichResourceTextMouseEvent(QWidget *owner, const QVariant &var, QRect rect, QMouseEvent *event); + +// register runtime conversions for custom Qt metatypes +void RegisterMetatypeConversions(); + struct Formatter { static void setParams(const PersistantConfig &config); diff --git a/qrenderdoc/Code/qrenderdoc.cpp b/qrenderdoc/Code/qrenderdoc.cpp index 15bbcd26d..8fa1d48b4 100644 --- a/qrenderdoc/Code/qrenderdoc.cpp +++ b/qrenderdoc/Code/qrenderdoc.cpp @@ -179,6 +179,8 @@ int main(int argc, char *argv[]) QApplication application(argc, argv); + RegisterMetatypeConversions(); + { PersistantConfig config; diff --git a/qrenderdoc/Widgets/Extended/RDTreeWidget.cpp b/qrenderdoc/Widgets/Extended/RDTreeWidget.cpp index 562f7d158..d4041f661 100644 --- a/qrenderdoc/Widgets/Extended/RDTreeWidget.cpp +++ b/qrenderdoc/Widgets/Extended/RDTreeWidget.cpp @@ -23,7 +23,6 @@ ******************************************************************************/ #include "RDTreeWidget.h" -#include #include #include #include @@ -33,116 +32,11 @@ #include #include #include -#include -#include -#include #include #include "Code/Interface/QRDInterface.h" +#include "Code/QRDUtils.h" #include "Code/Resources.h" -// this is used often, so cache it -QRegularExpression &ResourceIdRegexp() -{ - static QRegularExpression re(lit("(resourceid::)([0-9]*)")); - return re; -} - -struct ResourceIdLinkedText -{ - QVector fragments; - - // cached formatted document. We use cacheId to check if it needs to be updated - QTextDocument doc; - int cacheId = 0; - - // a plain-text version of the document, suitable for e.g. copy-paste - QString text; - - void cacheDocument(QWidget *widget) - { - ICaptureContext *ctxptr = getCaptureContext(widget); - - if(!ctxptr) - return; - - ICaptureContext &ctx = *(ICaptureContext *)ctxptr; - - int refCache = ctx.ResourceNameCacheID(); - - if(cacheId == refCache) - return; - - cacheId = refCache; - - // use a table to ensure images don't screw up the baseline for text. DON'T JUDGE ME. - QString html = lit(""); - - int i = 0; - - QVector fragmentIndexFromBlockIndex; - - // there's an empty block at the start. - fragmentIndexFromBlockIndex.push_back(-1); - - for(const QVariant &v : fragments) - { - if(v.userType() == qMetaTypeId()) - { - html += lit("") - .arg(ctx.GetResourceName(v.value())); - - // these generate two blocks (one for each cell) - fragmentIndexFromBlockIndex.push_back(i); - fragmentIndexFromBlockIndex.push_back(i); - } - else - { - html += lit("").arg(v.toString()); - - // this only generates one block - fragmentIndexFromBlockIndex.push_back(i); - } - - i++; - } - - // there's another empty block at the end - fragmentIndexFromBlockIndex.push_back(-1); - - html += lit("
%1%1
"); - - doc.setDocumentMargin(0); - doc.setHtml(html); - - if(doc.blockCount() != fragmentIndexFromBlockIndex.count()) - { - qCritical() << "Block count is not what's expected!" << doc.blockCount() - << fragmentIndexFromBlockIndex.count(); - - for(i = 0; i < doc.blockCount(); i++) - doc.findBlockByNumber(i).setUserState(-1); - - return; - } - - for(i = 0; i < doc.blockCount(); i++) - doc.findBlockByNumber(i).setUserState(fragmentIndexFromBlockIndex[i]); - - text = doc.toPlainText(); - // "Embedded objects, such as images, are represented by a Unicode value U+FFFC (OBJECT - // REPLACEMENT CHARACTER)." - text.remove(QChar(0xfffc)); - text = text.trimmed(); - } -}; - -// using QSharedPointer here since the lifetime management of these objects would get quite -// complicated, and there is no obvious QObject parent to assign to. The alternative would be to -// have the RDTreeWidgetItem track pointers in and out of the QVariant text -typedef QSharedPointer ResourceIdLinkedTextPtr; - -Q_DECLARE_METATYPE(ResourceIdLinkedTextPtr); - class RDTreeWidgetModel : public QAbstractItemModel { public: @@ -419,7 +313,7 @@ RDTreeWidgetItem::RDTreeWidgetItem(const QVariantList &values) m_icons.resize(m_text.size()); for(int i = 0; i < m_text.count(); i++) - checkForResourceId(i); + RichResourceTextInitialise(m_text[i]); } RDTreeWidgetItem::RDTreeWidgetItem(const std::initializer_list &values) @@ -428,52 +322,12 @@ RDTreeWidgetItem::RDTreeWidgetItem(const std::initializer_list &values m_icons.resize(m_text.size()); for(int i = 0; i < m_text.count(); i++) - checkForResourceId(i); + RichResourceTextInitialise(m_text[i]); } void RDTreeWidgetItem::checkForResourceId(int col) { - QRegularExpression &re = ResourceIdRegexp(); - - QVariant &v = m_text[col]; - - if(v.userType() == qMetaTypeId() || re.match(v.toString()).hasMatch()) - { - QString text; - if(v.userType() == qMetaTypeId()) - text = ToQStr(v.value()); - else - text = v.toString(); - - ResourceIdLinkedTextPtr linkedText(new ResourceIdLinkedText); - - // use regexp to split up into fragments of text and resourceid. The resourceid is then - // formatted on the fly in ResourceIdLinkedText::cacheDocument - QRegularExpressionMatch match = re.match(text); - while(match.hasMatch()) - { - qulonglong idnum = match.captured(2).toULongLong(); - ResourceId id; - memcpy(&id, &idnum, sizeof(id)); - - // push any text that preceeded the ResourceId. - if(match.capturedStart(1) > 0) - linkedText->fragments.push_back(text.left(match.capturedStart(1))); - - text.remove(0, match.capturedEnd(2)); - - linkedText->fragments.push_back(id); - - match = re.match(text); - } - - if(!text.isEmpty()) - linkedText->fragments.push_back(text); - - linkedText->doc.setHtml(text); - - v = QVariant::fromValue(linkedText); - } + RichResourceTextInitialise(m_text[col]); } RDTreeWidgetItem::~RDTreeWidgetItem() @@ -702,108 +556,54 @@ void RDTreeWidgetDelegate::paint(QPainter *painter, const QStyleOptionViewItem & const QModelIndex &index) const { RDTreeWidgetModel *model = m_widget->m_model; - if(model == index.model()) + if(index.isValid() && model == index.model()) { RDTreeWidgetItem *item = model->itemForIndex(index); - if(index.column() < item->m_text.count() && - item->m_text[index.column()].userType() == qMetaTypeId()) + if(index.column() < item->m_text.count()) { + QVariant v = item->m_text[index.column()]; + + if(RichResourceTextCheck(v)) { // draw the item without text, so we get the proper background/selection/etc. + // we'd like to be able to use ForwardingDelegate::paint here, but either it calls to + // QStyledItemDelegate which will re-fetch the text (bleh), or it calls to the manual + // delegate which could do anything. So for this case we just use the style and skip the + // delegate and hope it works out. QStyleOptionViewItem opt = option; + QStyledItemDelegate::initStyleOption(&opt, index); opt.text.clear(); + m_widget->style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter, m_widget); - ForwardingDelegate::paint(painter, opt, index); + painter->save(); + + RichResourceTextPaint(m_widget, painter, option.rect, option.font, option.palette, + option.state & QStyle::State_MouseOver, + m_widget->viewport()->mapFromGlobal(QCursor::pos()), v); + + painter->restore(); + return; } - - ResourceIdLinkedTextPtr linkedText = - item->m_text[index.column()].value(); - - painter->save(); - - painter->translate(option.rect.left(), option.rect.top()); - - linkedText->cacheDocument(m_widget); - linkedText->doc.setTextWidth(option.rect.width()); - linkedText->doc.drawContents(painter); - - if(option.state & QStyle::State_MouseOver) - { - painter->setPen(QPen(option.palette.brush(QPalette::WindowText), 1.0)); - - QAbstractTextDocumentLayout *layout = linkedText->doc.documentLayout(); - - QPoint p = m_widget->viewport()->mapFromGlobal(QCursor::pos()); - p -= option.rect.topLeft(); - - int pos = layout->hitTest(p, Qt::FuzzyHit); - - if(pos >= 0) - { - QTextBlock block = linkedText->doc.findBlock(pos); - - int frag = block.userState(); - if(frag >= 0) - { - QVariant v = linkedText->fragments[frag]; - if(v.userType() == qMetaTypeId() && v.value() != ResourceId()) - { - layout->blockBoundingRect(block); - QRectF rect = layout->blockBoundingRect(block); - - if(block.previous().userState() == frag) - { - rect = rect.united(layout->blockBoundingRect(block.previous())); - } - - if(block.next().userState() == frag) - { - rect = rect.united(layout->blockBoundingRect(block.next())); - } - - rect.translate(0.0, -2.0); - - painter->drawLine(rect.bottomLeft(), rect.bottomRight()); - } - } - } - } - - painter->restore(); - return; } } - else - { - qCritical() << "Unexpected model being passed to RDTreeWidgetDelegate!"; - } return ForwardingDelegate::paint(painter, option, index); } QSize RDTreeWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { - if(index.isValid()) + RDTreeWidgetModel *model = m_widget->m_model; + if(index.isValid() && model == index.model()) { - RDTreeWidgetModel *model = m_widget->m_model; - if(model == index.model()) - { - RDTreeWidgetItem *item = model->itemForIndex(index); + RDTreeWidgetItem *item = model->itemForIndex(index); - if(index.column() < item->m_text.count() && - item->m_text[index.column()].userType() == qMetaTypeId()) - { - ResourceIdLinkedTextPtr linkedText = - item->m_text[index.column()].value(); - - linkedText->cacheDocument(m_widget); - return QSize(linkedText->doc.idealWidth(), option.fontMetrics.height()); - } - } - else + if(index.column() < item->m_text.count()) { - qCritical() << "Unexpected model being passed to RDTreeWidgetDelegate!"; + QVariant v = item->m_text[index.column()]; + + if(RichResourceTextCheck(v)) + return QSize(RichResourceTextWidthHint(m_widget, v), option.fontMetrics.height()); } } @@ -813,62 +613,22 @@ QSize RDTreeWidgetDelegate::sizeHint(const QStyleOptionViewItem &option, const Q bool RDTreeWidgetDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { - if(event->type() == QEvent::MouseButtonRelease && index.isValid()) + RDTreeWidgetModel *rdmodel = m_widget->m_model; + if(event->type() == QEvent::MouseButtonRelease && index.isValid() && rdmodel == model) { - RDTreeWidgetModel *rdmodel = m_widget->m_model; - if(rdmodel == model) + RDTreeWidgetItem *item = rdmodel->itemForIndex(index); + + if(index.column() < item->m_text.count()) { - RDTreeWidgetItem *item = rdmodel->itemForIndex(index); + QVariant v = item->m_text[index.column()]; - if(index.column() < item->m_text.count() && - item->m_text[index.column()].userType() == qMetaTypeId()) + if(RichResourceTextCheck(v)) { - ResourceIdLinkedTextPtr linkedText = - item->m_text[index.column()].value(); - - linkedText->cacheDocument(m_widget); - - QAbstractTextDocumentLayout *layout = linkedText->doc.documentLayout(); - - QPoint p = ((QMouseEvent *)event)->pos(); - p -= option.rect.topLeft(); - - int pos = layout->hitTest(p, Qt::FuzzyHit); - - if(pos >= 0) - { - QTextBlock block = linkedText->doc.findBlock(pos); - - int frag = block.userState(); - if(frag >= 0) - { - QVariant v = linkedText->fragments[frag]; - if(v.userType() == qMetaTypeId() && v.value() != ResourceId()) - { - ICaptureContext *ctxptr = getCaptureContext(m_widget); - - if(ctxptr) - { - ICaptureContext &ctx = *(ICaptureContext *)ctxptr; - - if(!ctx.HasResourceInspector()) - ctx.ShowResourceInspector(); - - ctx.GetResourceInspector()->Inspect(v.value()); - - ctx.RaiseDockWindow(ctx.GetResourceInspector()->Widget()); - } - } - } - } - + // ignore the return value, we always consume clicks on this cell + RichResourceTextMouseEvent(m_widget, v, option.rect, (QMouseEvent *)event); return true; } } - else - { - qCritical() << "Unexpected model being passed to RDTreeWidgetDelegate!"; - } } return ForwardingDelegate::editorEvent(event, model, option, index); @@ -880,35 +640,12 @@ bool RDTreeWidgetDelegate::linkHover(QMouseEvent *e, const QModelIndex &index) { RDTreeWidgetItem *item = m_widget->m_model->itemForIndex(index); - if(index.column() < item->m_text.count() && - item->m_text[index.column()].userType() == qMetaTypeId()) + if(index.column() < item->m_text.count()) { - ResourceIdLinkedTextPtr linkedText = - item->m_text[index.column()].value(); + QVariant v = item->m_text[index.column()]; - linkedText->cacheDocument(m_widget); - - QAbstractTextDocumentLayout *layout = linkedText->doc.documentLayout(); - - QPoint p = e->pos(); - p -= m_widget->visualRect(index).topLeft(); - - int pos = layout->hitTest(p, Qt::FuzzyHit); - - if(pos >= 0) - { - QTextBlock block = linkedText->doc.findBlock(pos); - - int frag = block.userState(); - if(frag >= 0) - { - QVariant v = linkedText->fragments[frag]; - if(v.userType() == qMetaTypeId() && v.value() != ResourceId()) - { - return true; - } - } - } + if(RichResourceTextCheck(v)) + return RichResourceTextMouseEvent(m_widget, v, m_widget->visualRect(index), e); } } @@ -1013,7 +750,6 @@ QAbstractItemDelegate *RDTreeWidget::itemDelegate() const { return m_userDelegate; } - void RDTreeWidget::setColumns(const QStringList &columns) { m_headers = columns; @@ -1061,7 +797,6 @@ void RDTreeWidget::expandItem(RDTreeWidgetItem *item) { expand(m_model->indexForItem(item, 0)); } - void RDTreeWidget::expandAllItems(RDTreeWidgetItem *item) { expandItem(item); @@ -1145,7 +880,8 @@ void RDTreeWidget::mouseMoveEvent(QMouseEvent *e) // the documentation says: // // "If text is empty the tool tip is hidden. If the text is the same as the currently shown - // tooltip, the tip will not move. You can force moving by first hiding the tip with an empty + // tooltip, the tip will not move. You can force moving by first hiding the tip with an + // empty // text, and then showing the new tip at the new position." // // However the actual implementation has some kind of 'fading' check, so if you hide then @@ -1225,13 +961,6 @@ void RDTreeWidget::keyPressEvent(QKeyEvent *e) for(int i = 0; i < qMin(colCount, item->m_text.count()); i++) { QString text = item->m_text[i].toString(); - if(item->m_text[i].userType() == qMetaTypeId()) - { - ResourceIdLinkedTextPtr linkedText = item->m_text[i].value(); - linkedText->cacheDocument(this); - text = linkedText->text; - } - widths[i] = qMax(widths[i], text.count()); } } @@ -1248,14 +977,7 @@ void RDTreeWidget::keyPressEvent(QKeyEvent *e) for(int i = 0; i < qMin(colCount, item->m_text.count()); i++) { QString format = i == 0 ? QFormatStr("%1") : QFormatStr(" %1"); - QString text = item->m_text[i].toString(); - if(item->m_text[i].userType() == qMetaTypeId()) - { - ResourceIdLinkedTextPtr linkedText = item->m_text[i].value(); - linkedText->cacheDocument(this); - text = linkedText->text; - } clipData += format.arg(text, -widths[i]); } @@ -1278,7 +1000,8 @@ void RDTreeWidget::keyPressEvent(QKeyEvent *e) void RDTreeWidget::drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const { - // we do our own custom branch rendering to ensure the backgrounds for the +/- markers are filled + // we do our own custom branch rendering to ensure the backgrounds for the +/- markers are + // filled // (as otherwise they don't show up well over selection or background fills) as well as to draw // any vertical branch colors. @@ -1299,7 +1022,8 @@ void RDTreeWidget::drawBranches(QPainter *painter, const QRect &rect, const QMod parent = parent->parent(); } - // fill in the background behind the lines for the whole row, since by default it doesn't show up + // fill in the background behind the lines for the whole row, since by default it doesn't show + // up // behind the tree lines. QRect allLinesRect(rect.left(), rect.top(), (parents.count() + 1) * indentation(), rect.height()); @@ -1406,8 +1130,10 @@ void RDTreeWidget::beginAddChild(RDTreeWidgetItem *item) { m_queuedItem = item; // make an update of row 0. This will be a bit pessimistic if there are later data changes - // in a later row, but we're generally only changing data *or* adding children, not both, and - // in either case this is primarily about batching updates not providing a minimal update set + // in a later row, but we're generally only changing data *or* adding children, not both, + // and + // in either case this is primarily about batching updates not providing a minimal update + // set m_lowestIndex = qMakePair(0, 0); m_highestIndex = qMakePair(0, m_headers.count() - 1); }