From 9e231e4407588ffaf936233d362ebfb00da50702 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 27 May 2011 11:02:57 +0200 Subject: [PATCH] debugger: fix expansion of object in gdb tooltips on first click Change-Id: Ia157f8fb7f1b9ff8a8161c8a726d1d483b81e54f Reviewed-on: http://codereview.qt.nokia.com/179 Reviewed-by: hjk --- share/qtcreator/gdbmacros/dumper.py | 2 +- src/plugins/debugger/cdb/cdbengine.cpp | 2 +- .../debugger/debuggertooltipmanager.cpp | 424 ++++++++---------- src/plugins/debugger/debuggertooltipmanager.h | 187 +++----- src/plugins/debugger/gdb/gdbengine.cpp | 4 +- src/plugins/debugger/watchwindow.cpp | 2 +- 6 files changed, 267 insertions(+), 354 deletions(-) diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py index 98348da0932..d49b79e2b63 100644 --- a/share/qtcreator/gdbmacros/dumper.py +++ b/share/qtcreator/gdbmacros/dumper.py @@ -1254,7 +1254,7 @@ class Dumper: # Locals # fullUpdateNeeded = True - if self.partialUpdate and len(varList) == 1: + if self.partialUpdate and len(varList) == 1 and not self.tooltipOnly: #warn("PARTIAL: %s" % varList) parts = varList[0].split('.') #warn("PARTIAL PARTS: %s" % parts) diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index cfb6b1b2f87..7005b007b70 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -550,7 +550,7 @@ bool CdbEngine::setToolTipExpression(const QPoint &mousePos, if (!index.isValid()) return false; } - DebuggerTreeViewToolTipWidget *tw = new DebuggerTreeViewToolTipWidget; + DebuggerToolTipWidget *tw = new DebuggerToolTipWidget; tw->setContext(context); tw->setDebuggerModel(LocalsWatch); tw->setExpression(exp); diff --git a/src/plugins/debugger/debuggertooltipmanager.cpp b/src/plugins/debugger/debuggertooltipmanager.cpp index f326a355d37..692f2e9d94a 100644 --- a/src/plugins/debugger/debuggertooltipmanager.cpp +++ b/src/plugins/debugger/debuggertooltipmanager.cpp @@ -144,6 +144,64 @@ static void debugMode(const QAbstractItemModel *model) namespace Debugger { namespace Internal { +/* A Label that emits a signal when the user drags for moving the parent + * widget around. */ +class DraggableLabel : public QLabel +{ + Q_OBJECT +public: + explicit DraggableLabel(QWidget *parent = 0); + + bool isActive() const { return m_active; } + void setActive(bool v) { m_active = v; } + +signals: + void dragged(const QPoint &d); + +protected: + virtual void mousePressEvent(QMouseEvent * event); + virtual void mouseReleaseEvent(QMouseEvent * event); + virtual void mouseMoveEvent(QMouseEvent * event); + +private: + QPoint m_moveStartPos; + bool m_active; +}; + +DraggableLabel::DraggableLabel(QWidget *parent) : + QLabel(parent), m_moveStartPos(-1, -1), m_active(false) +{ +} + +void DraggableLabel::mousePressEvent(QMouseEvent * event) +{ + if (m_active && event->button() == Qt::LeftButton) { + m_moveStartPos = event->globalPos(); + event->accept(); + } + QLabel::mousePressEvent(event); +} + +void DraggableLabel::mouseReleaseEvent(QMouseEvent * event) +{ + if (m_active && event->button() == Qt::LeftButton) + m_moveStartPos = QPoint(-1, -1); + QLabel::mouseReleaseEvent(event); +} + +void DraggableLabel::mouseMoveEvent(QMouseEvent * event) +{ + if (m_active && (event->buttons() & Qt::LeftButton)) { + if (m_moveStartPos != QPoint(-1, -1)) { + const QPoint newPos = event->globalPos(); + emit dragged(event->globalPos() - m_moveStartPos); + m_moveStartPos = newPos; + } + event->accept(); + } + QLabel::mouseMoveEvent(event); +} + // A convenience struct to pass around all tooltip-relevant editor members // (TextEditor, Widget, File, etc), constructing from a Core::IEditor. @@ -441,133 +499,41 @@ private: StandardItemTreeModelBuilder m_builder; }; -/*! - \class Debugger::Internal::PinnableToolTipWidget - - A pinnable tooltip that goes from State 'Unpinned' (button showing - 'Pin') to 'Pinned' (button showing 'Close'). - It consists of a title toolbar and a vertical main layout. -*/ - -PinnableToolTipWidget::PinnableToolTipWidget(QWidget *parent) : - QWidget(parent), - m_pinState(Unpinned), - m_mainVBoxLayout(new QVBoxLayout), - m_toolBar(new QToolBar), - m_toolButton(new QToolButton) -{ - m_mainVBoxLayout->setSizeConstraint(QLayout::SetFixedSize); - m_mainVBoxLayout->setContentsMargins(0, 0, 0, 0); - - const QIcon pinIcon(QLatin1String(":/debugger/images/pin.xpm")); - const QList pinIconSizes = pinIcon.availableSizes(); - - m_toolButton->setIcon(pinIcon); - connect(m_toolButton, SIGNAL(clicked()), this, SLOT(toolButtonClicked())); - - m_toolBar->setProperty("_q_custom_style_disabled", QVariant(true)); - if (!pinIconSizes.isEmpty()) - m_toolBar->setIconSize(pinIconSizes.front()); - m_toolBar->addWidget(m_toolButton); - - m_mainVBoxLayout->addWidget(m_toolBar); - - setLayout(m_mainVBoxLayout); -} - -void PinnableToolTipWidget::addWidget(QWidget *w) +void DebuggerToolTipWidget::addWidget(QWidget *w) { w->setFocusPolicy(Qt::NoFocus); m_mainVBoxLayout->addWidget(w); } -void PinnableToolTipWidget::addToolBarWidget(QWidget *w) +void DebuggerToolTipWidget::addToolBarWidget(QWidget *w) { m_toolBar->addWidget(w); } -void PinnableToolTipWidget::pin() +void DebuggerToolTipWidget::pin() { - if (m_pinState == Unpinned) { - m_pinState = Pinned; - m_toolButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton)); - doPin(); - emit pinned(); + if (m_isPinned) + return; + m_isPinned = true; + m_toolButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton)); + + if (parentWidget()) { + // We are currently within a text editor tooltip: + // Rip out of parent widget and re-show as a tooltip + WidgetContent::pinToolTip(this); + } else { + // We have just be restored from session data. + setWindowFlags(Qt::ToolTip); } + m_titleLabel->setActive(true); // User can now drag } -void PinnableToolTipWidget::doPin() +void DebuggerToolTipWidget::toolButtonClicked() { -} - -void PinnableToolTipWidget::toolButtonClicked() -{ - switch (m_pinState) { - case Unpinned: - pin(); - break; - case Pinned: + if (m_isPinned) close(); - break; - } -} - -/* A Label that emits a signal when the user drags for moving the parent - * widget around. */ -class DraggableLabel : public QLabel -{ - Q_OBJECT -public: - explicit DraggableLabel(QWidget *parent = 0); - - bool isActive() const { return m_active; } - void setActive(bool v) { m_active = v; } - -signals: - void dragged(const QPoint &d); - -protected: - virtual void mousePressEvent(QMouseEvent * event); - virtual void mouseReleaseEvent(QMouseEvent * event); - virtual void mouseMoveEvent(QMouseEvent * event); - -private: - QPoint m_moveStartPos; - bool m_active; -}; - -DraggableLabel::DraggableLabel(QWidget *parent) : - QLabel(parent), m_moveStartPos(-1, -1), m_active(false) -{ -} - -void DraggableLabel::mousePressEvent(QMouseEvent * event) -{ - if (m_active && event->button() == Qt::LeftButton) { - m_moveStartPos = event->globalPos(); - event->accept(); - } - QLabel::mousePressEvent(event); -} - -void DraggableLabel::mouseReleaseEvent(QMouseEvent * event) -{ - if (m_active && event->button() == Qt::LeftButton) - m_moveStartPos = QPoint(-1, -1); - QLabel::mouseReleaseEvent(event); -} - -void DraggableLabel::mouseMoveEvent(QMouseEvent * event) -{ - if (m_active && (event->buttons() & Qt::LeftButton)) { - if (m_moveStartPos != QPoint(-1, -1)) { - const QPoint newPos = event->globalPos(); - emit dragged(event->globalPos() - m_moveStartPos); - m_moveStartPos = newPos; - } - event->accept(); - } - QLabel::mouseMoveEvent(event); + else + pin(); } /*! @@ -605,18 +571,24 @@ QDebug operator<<(QDebug d, const DebuggerToolTipContext &c) } /*! - \class Debugger::Internal::AbstractDebuggerToolTipWidget + \class Debugger::Internal::DebuggerToolTipWidget + + A debugger tooltip is pinnable. It goes from the unpinned state (button + showing 'Pin') to the pinned state (button showing 'Close'). + It consists of a title toolbar and a vertical main layout. + The widget has the ability to save/restore tree model contents to XML. + With the engine acquired, it sets a filter model (by expression) on + one of the engine's models (debuggerModel). + On release, it serializes and restores the data to a QStandardItemModel + (defaultModel) and displays that. + + It is associated with file name and position with functionality to + acquire and release the engine: When the debugger stops at a file, all + matching tooltips acquire the engine, that is, display the engine data. + When continuing or switching away from the frame, the tooltips release the + engine, that is, store the data internally and keep displaying them + marked as 'previous'. - Base class for a tool tip widget associated with file name - and position with functionality to - \list - \o Save and restore values (session data) in XML form - \o Acquire and release the engine: When the debugger stops at a file, all - matching tooltips acquire the engine, that is, display the engine data. - When continuing or switching away from the frame, the tooltips release the - engine, that is, store the data internally and keep displaying them - marked as 'previous'. - \endlist When restoring the data from a session, all tooltips start in 'released' mode. Stored tooltips expire after toolTipsExpiryDays while loading to prevent @@ -633,13 +605,39 @@ QDebug operator<<(QDebug d, const DebuggerToolTipContext &c) of them. On closing or session changes, the contents it saved. */ -static QString msgReleasedText() { return AbstractDebuggerToolTipWidget::tr("Previous"); } -AbstractDebuggerToolTipWidget::AbstractDebuggerToolTipWidget(QWidget *parent) : - PinnableToolTipWidget(parent), - m_titleLabel(new DraggableLabel), m_engineAcquired(false), - m_creationDate(QDate::currentDate()) +static QString msgReleasedText() { return DebuggerToolTipWidget::tr("Previous"); } + +DebuggerToolTipWidget::DebuggerToolTipWidget(QWidget *parent) : + QWidget(parent), + m_isPinned(false), + m_mainVBoxLayout(new QVBoxLayout), + m_toolBar(new QToolBar), + m_toolButton(new QToolButton), + m_titleLabel(new DraggableLabel), + m_engineAcquired(false), + m_creationDate(QDate::currentDate()), + m_debuggerModel(TooltipsWatch), + m_treeView(new DebuggerToolTipTreeView), + m_defaultModel(new QStandardItemModel(this)) { + m_mainVBoxLayout->setSizeConstraint(QLayout::SetFixedSize); + m_mainVBoxLayout->setContentsMargins(0, 0, 0, 0); + + const QIcon pinIcon(QLatin1String(":/debugger/images/pin.xpm")); + const QList pinIconSizes = pinIcon.availableSizes(); + + m_toolButton->setIcon(pinIcon); + connect(m_toolButton, SIGNAL(clicked()), this, SLOT(toolButtonClicked())); + + m_toolBar->setProperty("_q_custom_style_disabled", QVariant(true)); + if (!pinIconSizes.isEmpty()) + m_toolBar->setIconSize(pinIconSizes.front()); + m_toolBar->addWidget(m_toolButton); + + m_mainVBoxLayout->addWidget(m_toolBar); + + setLayout(m_mainVBoxLayout); QToolButton *copyButton = new QToolButton; copyButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_COPY))); connect(copyButton, SIGNAL(clicked()), this, SLOT(copy())); @@ -649,9 +647,10 @@ AbstractDebuggerToolTipWidget::AbstractDebuggerToolTipWidget(QWidget *parent) : m_titleLabel->setMinimumWidth(40); // Ensure a draggable area even if text is empty. connect(m_titleLabel, SIGNAL(dragged(QPoint)), this, SLOT(slotDragged(QPoint))); addToolBarWidget(m_titleLabel); + addWidget(m_treeView); } -bool AbstractDebuggerToolTipWidget::matches(const QString &fileName, +bool DebuggerToolTipWidget::matches(const QString &fileName, const QString &engineType, const QString &function) const { @@ -665,11 +664,10 @@ bool AbstractDebuggerToolTipWidget::matches(const QString &fileName, return function == m_context.function; } -void AbstractDebuggerToolTipWidget::acquireEngine(Debugger::DebuggerEngine *engine) +void DebuggerToolTipWidget::acquireEngine(Debugger::DebuggerEngine *engine) { QTC_ASSERT(engine, return); - if (debugToolTips) qDebug() << this << " acquiring" << engine << m_engineAcquired; if (m_engineAcquired) @@ -680,7 +678,7 @@ void AbstractDebuggerToolTipWidget::acquireEngine(Debugger::DebuggerEngine *engi m_titleLabel->setText(QString()); } -void AbstractDebuggerToolTipWidget::releaseEngine() +void DebuggerToolTipWidget::releaseEngine() { // Release engine of same type if (!m_engineAcquired) @@ -692,7 +690,7 @@ void AbstractDebuggerToolTipWidget::releaseEngine() m_engineAcquired = false; } -void AbstractDebuggerToolTipWidget::copy() +void DebuggerToolTipWidget::copy() { const QString clipboardText = clipboardContents(); QClipboard *clipboard = QApplication::clipboard(); @@ -702,13 +700,13 @@ void AbstractDebuggerToolTipWidget::copy() clipboard->setText(clipboardText, QClipboard::Clipboard); } -void AbstractDebuggerToolTipWidget::slotDragged(const QPoint &p) +void DebuggerToolTipWidget::slotDragged(const QPoint &p) { move(pos() + p); m_offset += p; } -bool AbstractDebuggerToolTipWidget::positionShow(const DebuggerToolTipEditor &te) +bool DebuggerToolTipWidget::positionShow(const DebuggerToolTipEditor &te) { // Figure out new position of tooltip using the text edit. // If the line changed too much, close this tip. @@ -748,19 +746,6 @@ bool AbstractDebuggerToolTipWidget::positionShow(const DebuggerToolTipEditor &te return true; } -void AbstractDebuggerToolTipWidget::doPin() -{ - if (parentWidget()) { - // We are currently within a text editor tooltip: - // Rip out of parent widget and re-show as a tooltip - WidgetContent::pinToolTip(this); - } else { - // We have just be restored from session data. - setWindowFlags(Qt::ToolTip); - } - m_titleLabel->setActive(true); // User can now drag -} - // Parse a 'yyyyMMdd' date static QDate dateFromString(const QString &date) { @@ -769,17 +754,17 @@ static QDate dateFromString(const QString &date) QDate(); } -AbstractDebuggerToolTipWidget *AbstractDebuggerToolTipWidget::loadSessionData(QXmlStreamReader &r) +DebuggerToolTipWidget *DebuggerToolTipWidget::loadSessionData(QXmlStreamReader &r) { if (debugToolTips) qDebug() << ">DebuggerToolTipWidget::loadSessionData" << r.tokenString() << r.name(); - AbstractDebuggerToolTipWidget *rc = AbstractDebuggerToolTipWidget::loadSessionDataI(r); + DebuggerToolTipWidget *rc = DebuggerToolTipWidget::loadSessionDataI(r); if (debugToolTips) qDebug() << "setContext(context); rc->setAttribute(Qt::WA_DeleteOnClose); @@ -828,7 +813,7 @@ AbstractDebuggerToolTipWidget *AbstractDebuggerToolTipWidget::loadSessionDataI(Q return rc; } -void AbstractDebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const +void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const { w.writeStartElement(QLatin1String(toolTipElementC)); QXmlStreamAttributes attributes; @@ -1006,28 +991,7 @@ void DebuggerToolTipTreeView::computeSize() setRootIsDecorated(rootDecorated); } -/*! - \class Debugger::Internal::DebuggerTreeViewToolTipWidget - - Tool tip widget for tree views with functionality to save/restore tree - model contents to XML. - With the engine acquired, it sets a filter model (by expression) on - one of the engine's models (debuggerModel). - On release, it serializes and restores the data to a QStandardItemModel - (defaultModel) and displays that. - -*/ - -DebuggerTreeViewToolTipWidget::DebuggerTreeViewToolTipWidget(QWidget *parent) : - AbstractDebuggerToolTipWidget(parent), - m_debuggerModel(TooltipsWatch), - m_treeView(new DebuggerToolTipTreeView), - m_defaultModel(new QStandardItemModel(this)) -{ - addWidget(m_treeView); -} - -void DebuggerTreeViewToolTipWidget::doAcquireEngine(Debugger::DebuggerEngine *engine) +void DebuggerToolTipWidget::doAcquireEngine(Debugger::DebuggerEngine *engine) { // Create a filter model on the debugger's model and switch to it. QAbstractItemModel *model = 0; @@ -1048,7 +1012,7 @@ void DebuggerTreeViewToolTipWidget::doAcquireEngine(Debugger::DebuggerEngine *en swapModel(filterModel); } -QAbstractItemModel *DebuggerTreeViewToolTipWidget::swapModel(QAbstractItemModel *newModel) +QAbstractItemModel *DebuggerToolTipWidget::swapModel(QAbstractItemModel *newModel) { QAbstractItemModel *oldModel = m_treeView->swapModel(newModel); // When looking at some 'this.m_foo.x', expand all items @@ -1062,7 +1026,7 @@ QAbstractItemModel *DebuggerTreeViewToolTipWidget::swapModel(QAbstractItemModel return oldModel; } -void DebuggerTreeViewToolTipWidget::doReleaseEngine() +void DebuggerToolTipWidget::doReleaseEngine() { // Save data to stream and restore to the m_defaultModel (QStandardItemModel) m_defaultModel->removeRows(0, m_defaultModel->rowCount()); @@ -1073,7 +1037,7 @@ void DebuggerTreeViewToolTipWidget::doReleaseEngine() delete swapModel(m_defaultModel); } -void DebuggerTreeViewToolTipWidget::restoreTreeModel(QXmlStreamReader &r, QStandardItemModel *m) +void DebuggerToolTipWidget::restoreTreeModel(QXmlStreamReader &r, QStandardItemModel *m) { StandardItemTreeModelBuilder builder(m); int columnCount = 1; @@ -1111,7 +1075,7 @@ void DebuggerTreeViewToolTipWidget::restoreTreeModel(QXmlStreamReader &r, QStand } // while } -void DebuggerTreeViewToolTipWidget::doSaveSessionData(QXmlStreamWriter &w) const +void DebuggerToolTipWidget::doSaveSessionData(QXmlStreamWriter &w) const { w.writeStartElement(QLatin1String(treeElementC)); QXmlStreamAttributes attributes; @@ -1125,7 +1089,7 @@ void DebuggerTreeViewToolTipWidget::doSaveSessionData(QXmlStreamWriter &w) const w.writeEndElement(); } -void DebuggerTreeViewToolTipWidget::doLoadSessionData(QXmlStreamReader &r) +void DebuggerToolTipWidget::doLoadSessionData(QXmlStreamReader &r) { if (!readStartElement(r, treeElementC)) return; @@ -1141,7 +1105,7 @@ void DebuggerTreeViewToolTipWidget::doLoadSessionData(QXmlStreamReader &r) m_treeView->swapModel(m_defaultModel); } -QString DebuggerTreeViewToolTipWidget::treeModelClipboardContents(const QAbstractItemModel *m) +QString DebuggerToolTipWidget::treeModelClipboardContents(const QAbstractItemModel *m) { QString rc; QTextStream str(&rc); @@ -1150,10 +1114,10 @@ QString DebuggerTreeViewToolTipWidget::treeModelClipboardContents(const QAbstrac return rc; } -QString DebuggerTreeViewToolTipWidget::clipboardContents() const +QString DebuggerToolTipWidget::clipboardContents() const { if (const QAbstractItemModel *model = m_treeView->model()) - return DebuggerTreeViewToolTipWidget::treeModelClipboardContents(model); + return DebuggerToolTipWidget::treeModelClipboardContents(model); return QString(); } @@ -1193,7 +1157,7 @@ void DebuggerToolTipManager::registerEngine(DebuggerEngine *engine) } void DebuggerToolTipManager::showToolTip(const QPoint &p, IEditor *editor, - AbstractDebuggerToolTipWidget *toolTipWidget) + DebuggerToolTipWidget *toolTipWidget) { QWidget *widget = editor->widget(); if (debugToolTipPositioning) @@ -1203,45 +1167,29 @@ void DebuggerToolTipManager::showToolTip(const QPoint &p, IEditor *editor, registerToolTip(toolTipWidget); } -void DebuggerToolTipManager::registerToolTip(AbstractDebuggerToolTipWidget *toolTipWidget) +void DebuggerToolTipManager::registerToolTip(DebuggerToolTipWidget *toolTipWidget) { QTC_ASSERT(toolTipWidget->context().isValid(), return); - switch (toolTipWidget->pinState()) { - case PinnableToolTipWidget::Pinned: - m_pinnedTooltips.push_back(toolTipWidget); - break; - case PinnableToolTipWidget::Unpinned: - // Catch the widget once it is pinned. - connect(toolTipWidget, SIGNAL(pinned()), this, SLOT(slotPinnedFirstTime())); - break; - } + m_tooltips.push_back(toolTipWidget); } -void DebuggerToolTipManager::slotPinnedFirstTime() +void DebuggerToolTipManager::purgeClosedToolTips() { - if (AbstractDebuggerToolTipWidget *tw = qobject_cast(sender())) - m_pinnedTooltips.push_back(tw); -} - -DebuggerToolTipManager::DebuggerToolTipWidgetList &DebuggerToolTipManager::purgeClosedToolTips() -{ - if (!m_pinnedTooltips.isEmpty()) { - for (DebuggerToolTipWidgetList::iterator it = m_pinnedTooltips.begin(); it != m_pinnedTooltips.end() ; ) { - if (it->isNull()) { - it = m_pinnedTooltips.erase(it); - } else { - ++it; - } + for (DebuggerToolTipWidgetList::iterator it = m_tooltips.begin(); it != m_tooltips.end() ; ) { + if (it->isNull()) { + it = m_tooltips.erase(it); + } else { + ++it; } } - return m_pinnedTooltips; } void DebuggerToolTipManager::moveToolTipsBy(const QPoint &distance) { - foreach (const QPointer &tw, purgeClosedToolTips()) + purgeClosedToolTips(); + foreach (const QPointer &tw, m_tooltips) if (tw->isVisible()) - tw->move (tw->pos() + distance); + tw->move(tw->pos() + distance); } bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e) @@ -1258,9 +1206,11 @@ bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e) const QWindowStateChangeEvent *se = static_cast(e); const bool wasMinimized = se->oldState() & Qt::WindowMinimized; const bool isMinimized = static_cast(o)->windowState() & Qt::WindowMinimized; - if (wasMinimized ^ isMinimized) - foreach (const QPointer &tw, purgeClosedToolTips()) + if (wasMinimized ^ isMinimized) { + purgeClosedToolTips(); + foreach (const QPointer &tw, m_tooltips) tw->setVisible(!isMinimized); + } } break; default: @@ -1285,28 +1235,30 @@ void DebuggerToolTipManager::loadSessionData() return; const double version = r.attributes().value(QLatin1String(sessionVersionAttributeC)).toString().toDouble(); while (!r.atEnd()) - if (AbstractDebuggerToolTipWidget *tw = AbstractDebuggerToolTipWidget::loadSessionData(r)) + if (DebuggerToolTipWidget *tw = DebuggerToolTipWidget::loadSessionData(r)) registerToolTip(tw); if (debugToolTips) - qDebug() << "DebuggerToolTipManager::loadSessionData version " << version << " restored " << m_pinnedTooltips.size(); + qDebug() << "DebuggerToolTipManager::loadSessionData version " << version << " restored " << m_tooltips.size(); slotUpdateVisibleToolTips(); } void DebuggerToolTipManager::saveSessionData() { QString data; - if (!purgeClosedToolTips().isEmpty()) { + purgeClosedToolTips(); + if (!m_tooltips.isEmpty()) { QXmlStreamWriter w(&data); w.writeStartDocument(); w.writeStartElement(QLatin1String(sessionDocumentC)); w.writeAttribute(QLatin1String(sessionVersionAttributeC), QLatin1String("1.0")); - foreach (const QPointer &tw, m_pinnedTooltips) - tw->saveSessionData(w); + foreach (const QPointer &tw, m_tooltips) + if (tw->isPinned()) + tw->saveSessionData(w); w.writeEndDocument(); } if (debugToolTips) - qDebug() << "DebuggerToolTipManager::saveSessionData" << m_pinnedTooltips.size() << data ; + qDebug() << "DebuggerToolTipManager::saveSessionData" << m_tooltips.size() << data ; debuggerCore()->setSessionValue(QLatin1String(sessionSettingsKeyC), QVariant(data)); } @@ -1315,20 +1267,23 @@ void DebuggerToolTipManager::closeAllToolTips() if (debugToolTips) qDebug() << "DebuggerToolTipManager::closeAllToolTips"; - foreach (const QPointer &tw, purgeClosedToolTips()) + purgeClosedToolTips(); + foreach (const QPointer &tw, m_tooltips) tw->close(); - m_pinnedTooltips.clear(); + m_tooltips.clear(); } void DebuggerToolTipManager::hide() { - foreach (const QPointer &tw, purgeClosedToolTips()) + purgeClosedToolTips(); + foreach (const QPointer &tw, m_tooltips) tw->hide(); } void DebuggerToolTipManager::slotUpdateVisibleToolTips() { - if (purgeClosedToolTips().isEmpty()) + purgeClosedToolTips(); + if (m_tooltips.isEmpty()) return; if (!m_debugModeActive) { hide(); @@ -1347,7 +1302,7 @@ void DebuggerToolTipManager::slotUpdateVisibleToolTips() // Reposition and show all tooltips of that file. const QString fileName = toolTipEditor.fileName(); - foreach (const QPointer &tw, m_pinnedTooltips) { + foreach (const QPointer &tw, m_tooltips) { if (tw->fileName() == fileName) { tw->positionShow(toolTipEditor); } else { @@ -1373,11 +1328,13 @@ void DebuggerToolTipManager::slotDebuggerStateChanged(Debugger::DebuggerState st case InferiorShutdownRequested: case EngineShutdownRequested: case DebuggerFinished: - case EngineShutdownOk: - foreach (const QPointer &tw, purgeClosedToolTips()) + case EngineShutdownOk: { + purgeClosedToolTips(); + foreach (const QPointer &tw, m_tooltips) if (tw->engineType() == name) tw->releaseEngine(); break; + } default: break; } @@ -1385,7 +1342,8 @@ void DebuggerToolTipManager::slotDebuggerStateChanged(Debugger::DebuggerState st void DebuggerToolTipManager::slotStackFrameCompleted() { - if (purgeClosedToolTips().isEmpty()) + purgeClosedToolTips(); + if (m_tooltips.isEmpty()) return; DebuggerEngine *engine = qobject_cast(sender()); QTC_ASSERT(engine, return); @@ -1411,7 +1369,7 @@ void DebuggerToolTipManager::slotStackFrameCompleted() qPrintable(engineName), qPrintable(fileName), lineNumber, qPrintable(function)); unsigned acquiredCount = 0; - foreach (const QPointer &tw, m_pinnedTooltips) { + foreach (const QPointer &tw, m_tooltips) { if (tw->matches(fileName, engineName, function)) { tw->acquireEngine(engine); acquiredCount++; @@ -1460,7 +1418,7 @@ void DebuggerToolTipManager::debugModeEntered() foreach (IEditor *e, em->openedEditors()) slotEditorOpened(e); // Position tooltips delayed once all the editor placeholder layouting is done. - if (!m_pinnedTooltips.isEmpty()) + if (!m_tooltips.isEmpty()) QTimer::singleShot(0, this, SLOT(slotUpdateVisibleToolTips())); } } @@ -1544,10 +1502,10 @@ QStringList DebuggerToolTipManager::treeWidgetExpressions(const QString &fileNam const QString &function) const { QStringList rc; - foreach (const QPointer &tw, m_pinnedTooltips) + foreach (const QPointer &tw, m_tooltips) { if (!tw.isNull() && tw->matches(fileName, engineType, function)) - if (const DebuggerTreeViewToolTipWidget *ttw = qobject_cast(tw.data())) - rc.push_back(ttw->expression()); + rc.push_back(tw->expression()); + } if (debugToolTips) qDebug() << "DebuggerToolTipManager::treeWidgetExpressions" << fileName << engineType << function << rc; diff --git a/src/plugins/debugger/debuggertooltipmanager.h b/src/plugins/debugger/debuggertooltipmanager.h index c71cb0b268a..b4bed300859 100644 --- a/src/plugins/debugger/debuggertooltipmanager.h +++ b/src/plugins/debugger/debuggertooltipmanager.h @@ -47,10 +47,7 @@ QT_BEGIN_NAMESPACE class QVBoxLayout; class QToolButton; -class QSortFilterProxyModel; class QStandardItemModel; -class QPlainTextEdit; -class QLabel; class QToolBar; class QDebug; QT_END_NAMESPACE @@ -71,42 +68,6 @@ namespace Internal { class DraggableLabel; class DebuggerToolTipEditor; -class PinnableToolTipWidget : public QWidget -{ - Q_OBJECT - -public: - enum PinState - { - Unpinned, - Pinned - }; - - explicit PinnableToolTipWidget(QWidget *parent = 0); - - PinState pinState() const { return m_pinState; } - - void addWidget(QWidget *w); - void addToolBarWidget(QWidget *w); - -public slots: - void pin(); - -signals: - void pinned(); - -private slots: - void toolButtonClicked(); - -private: - virtual void doPin(); - - PinState m_pinState; - QVBoxLayout *m_mainVBoxLayout; - QToolBar *m_toolBar; - QToolButton *m_toolButton; -}; - class DebuggerToolTipContext { public: @@ -123,12 +84,19 @@ public: QDebug operator<<(QDebug, const DebuggerToolTipContext &); -class AbstractDebuggerToolTipWidget : public PinnableToolTipWidget +class DebuggerToolTipTreeView; + +class DebuggerToolTipWidget : public QWidget { Q_OBJECT public: - explicit AbstractDebuggerToolTipWidget(QWidget *parent = 0); + bool isPinned() const { return m_isPinned; } + + void addWidget(QWidget *w); + void addToolBarWidget(QWidget *w); + + explicit DebuggerToolTipWidget(QWidget *parent = 0); bool engineAcquired() const { return m_engineAcquired; } QString fileName() const { return m_context.fileName; } @@ -151,66 +119,7 @@ public: QPoint offset() const { return m_offset; } void setOffset(const QPoint &o) { m_offset = o; } - static AbstractDebuggerToolTipWidget *loadSessionData(QXmlStreamReader &r); - -public slots: - void saveSessionData(QXmlStreamWriter &w) const; - - void acquireEngine(Debugger::DebuggerEngine *engine); - void releaseEngine(); - void copy(); - bool positionShow(const DebuggerToolTipEditor &pe); - -private slots: - virtual void doPin(); - void slotDragged(const QPoint &p); - -protected: - virtual void doAcquireEngine(Debugger::DebuggerEngine *engine) = 0; - virtual void doReleaseEngine() = 0; - virtual void doSaveSessionData(QXmlStreamWriter &w) const = 0; - virtual void doLoadSessionData(QXmlStreamReader &r) = 0; - // Return a string suitable for copying contents - virtual QString clipboardContents() const { return QString(); } - -private: - static AbstractDebuggerToolTipWidget *loadSessionDataI(QXmlStreamReader &r); - DraggableLabel *m_titleLabel; - bool m_engineAcquired; - QString m_engineType; - DebuggerToolTipContext m_context; - QDate m_creationDate; - QPoint m_offset; //!< Offset to text cursor position (user dragging). -}; - -class DebuggerToolTipTreeView : public QTreeView -{ - Q_OBJECT - -public: - explicit DebuggerToolTipTreeView(QWidget *parent = 0); - - QAbstractItemModel *swapModel(QAbstractItemModel *model); - - QSize sizeHint() const { return m_size; } - - int computeHeight(const QModelIndex &index) const; - -public slots: - void computeSize(); - -private: - void init(QAbstractItemModel *model); - - QSize m_size; -}; - -class DebuggerTreeViewToolTipWidget : public AbstractDebuggerToolTipWidget -{ - Q_OBJECT - -public: - explicit DebuggerTreeViewToolTipWidget(QWidget *parent = 0); + static DebuggerToolTipWidget *loadSessionData(QXmlStreamReader &r); int debuggerModel() const { return m_debuggerModel; } void setDebuggerModel(int m) { m_debuggerModel = m; } @@ -219,12 +128,39 @@ public: static QString treeModelClipboardContents(const QAbstractItemModel *m); -protected: - virtual void doAcquireEngine(Debugger::DebuggerEngine *engine); - virtual void doReleaseEngine(); - virtual void doSaveSessionData(QXmlStreamWriter &w) const; - virtual void doLoadSessionData(QXmlStreamReader &r); - virtual QString clipboardContents() const; +public slots: + void saveSessionData(QXmlStreamWriter &w) const; + + void acquireEngine(Debugger::DebuggerEngine *engine); + void releaseEngine(); + void copy(); + bool positionShow(const DebuggerToolTipEditor &pe); + void pin(); + +private slots: + void slotDragged(const QPoint &p); + void toolButtonClicked(); + +private: + bool m_isPinned; + QVBoxLayout *m_mainVBoxLayout; + QToolBar *m_toolBar; + QToolButton *m_toolButton; + +private: + static DebuggerToolTipWidget *loadSessionDataI(QXmlStreamReader &r); + void doAcquireEngine(Debugger::DebuggerEngine *engine); + void doReleaseEngine(); + void doSaveSessionData(QXmlStreamWriter &w) const; + void doLoadSessionData(QXmlStreamReader &r); + QString clipboardContents() const; + + DraggableLabel *m_titleLabel; + bool m_engineAcquired; + QString m_engineType; + DebuggerToolTipContext m_context; + QDate m_creationDate; + QPoint m_offset; //!< Offset to text cursor position (user dragging). private: QAbstractItemModel *swapModel(QAbstractItemModel *newModel); @@ -237,6 +173,26 @@ private: QStandardItemModel *m_defaultModel; }; +class DebuggerToolTipTreeView : public QTreeView +{ + Q_OBJECT + +public: + explicit DebuggerToolTipTreeView(QWidget *parent = 0); + + QAbstractItemModel *swapModel(QAbstractItemModel *model); + QSize sizeHint() const { return m_size; } + int computeHeight(const QModelIndex &index) const; + +public slots: + void computeSize(); + +private: + void init(QAbstractItemModel *model); + + QSize m_size; +}; + class DebuggerToolTipManager : public QObject { Q_OBJECT @@ -247,14 +203,14 @@ public: static DebuggerToolTipManager *instance() { return m_instance; } void registerEngine(DebuggerEngine *engine); - bool hasToolTips() const { return !m_pinnedTooltips.isEmpty(); } + bool hasToolTips() const { return !m_tooltips.isEmpty(); } // Collect all expressions of DebuggerTreeViewToolTipWidget QStringList treeWidgetExpressions(const QString &fileName, const QString &engineType = QString(), const QString &function= QString()) const; - void showToolTip(const QPoint &p, Core::IEditor *editor, AbstractDebuggerToolTipWidget *); + void showToolTip(const QPoint &p, Core::IEditor *editor, DebuggerToolTipWidget *); virtual bool eventFilter(QObject *, QEvent *); @@ -267,29 +223,28 @@ public slots: void loadSessionData(); void saveSessionData(); void closeAllToolTips(); - void hide() -; + void hide(); private slots: void slotUpdateVisibleToolTips(); void slotDebuggerStateChanged(Debugger::DebuggerState); void slotStackFrameCompleted(); void slotEditorOpened(Core::IEditor *); - void slotPinnedFirstTime(); void slotTooltipOverrideRequested(TextEditor::ITextEditor *editor, const QPoint &point, int pos, bool *handled); private: - typedef QList > DebuggerToolTipWidgetList; + typedef QList > DebuggerToolTipWidgetList; - void registerToolTip(AbstractDebuggerToolTipWidget *toolTipWidget); + void registerToolTip(DebuggerToolTipWidget *toolTipWidget); void moveToolTipsBy(const QPoint &distance); // Purge out closed (null) tooltips and return list for convenience - DebuggerToolTipWidgetList &purgeClosedToolTips(); + void purgeClosedToolTips(); static DebuggerToolTipManager *m_instance; - DebuggerToolTipWidgetList m_pinnedTooltips; + DebuggerToolTipWidgetList m_tooltips; + bool m_debugModeActive; QPoint m_lastToolTipPoint; Core::IEditor *m_lastToolTipEditor; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 18472b67630..58eed9bcfe2 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -3542,7 +3542,7 @@ bool GdbEngine::showToolTip() watchHandler()->removeData(iname); return false; } - DebuggerTreeViewToolTipWidget *tw = new DebuggerTreeViewToolTipWidget; + DebuggerToolTipWidget *tw = new DebuggerToolTipWidget; tw->setDebuggerModel(TooltipsWatch); tw->setExpression(expression); tw->setContext(*m_toolTipContext); @@ -3716,11 +3716,11 @@ void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &f // << (m_pendingBreakpointRequests == 0); UpdateParameters params; + params.tooltipOnly = data.iname.startsWith("tooltip"); params.tryPartial = flags.tryIncremental && hasPython() && m_pendingWatchRequests == 0 && m_pendingBreakpointRequests == 0; - params.tooltipOnly = false; params.varList = data.iname; updateLocalsPython(params); diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index 84adb5ec52a..f3510a198d9 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -910,7 +910,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev) } else if (act == actRemoveWatchExpression) { removeWatchExpression(exp); } else if (act == actCopy) { - copyToClipboard(DebuggerTreeViewToolTipWidget::treeModelClipboardContents(model())); + copyToClipboard(DebuggerToolTipWidget::treeModelClipboardContents(model())); } else if (act == actCopyValue) { copyToClipboard(mi1.data().toString()); } else if (act == actRemoveWatches) {