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 <qthjk@ovi.com>
This commit is contained in:
hjk
2011-05-27 11:02:57 +02:00
committed by hjk
parent 184b079557
commit 9e231e4407
6 changed files with 267 additions and 354 deletions

View File

@@ -1254,7 +1254,7 @@ class Dumper:
# Locals # Locals
# #
fullUpdateNeeded = True fullUpdateNeeded = True
if self.partialUpdate and len(varList) == 1: if self.partialUpdate and len(varList) == 1 and not self.tooltipOnly:
#warn("PARTIAL: %s" % varList) #warn("PARTIAL: %s" % varList)
parts = varList[0].split('.') parts = varList[0].split('.')
#warn("PARTIAL PARTS: %s" % parts) #warn("PARTIAL PARTS: %s" % parts)

View File

@@ -550,7 +550,7 @@ bool CdbEngine::setToolTipExpression(const QPoint &mousePos,
if (!index.isValid()) if (!index.isValid())
return false; return false;
} }
DebuggerTreeViewToolTipWidget *tw = new DebuggerTreeViewToolTipWidget; DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
tw->setContext(context); tw->setContext(context);
tw->setDebuggerModel(LocalsWatch); tw->setDebuggerModel(LocalsWatch);
tw->setExpression(exp); tw->setExpression(exp);

View File

@@ -144,6 +144,64 @@ static void debugMode(const QAbstractItemModel *model)
namespace Debugger { namespace Debugger {
namespace Internal { 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 // A convenience struct to pass around all tooltip-relevant editor members
// (TextEditor, Widget, File, etc), constructing from a Core::IEditor. // (TextEditor, Widget, File, etc), constructing from a Core::IEditor.
@@ -441,133 +499,41 @@ private:
StandardItemTreeModelBuilder m_builder; StandardItemTreeModelBuilder m_builder;
}; };
/*! void DebuggerToolTipWidget::addWidget(QWidget *w)
\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<QSize> 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)
{ {
w->setFocusPolicy(Qt::NoFocus); w->setFocusPolicy(Qt::NoFocus);
m_mainVBoxLayout->addWidget(w); m_mainVBoxLayout->addWidget(w);
} }
void PinnableToolTipWidget::addToolBarWidget(QWidget *w) void DebuggerToolTipWidget::addToolBarWidget(QWidget *w)
{ {
m_toolBar->addWidget(w); m_toolBar->addWidget(w);
} }
void PinnableToolTipWidget::pin() void DebuggerToolTipWidget::pin()
{ {
if (m_pinState == Unpinned) { if (m_isPinned)
m_pinState = Pinned; return;
m_toolButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton)); m_isPinned = true;
doPin(); m_toolButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton));
emit pinned();
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()
{ {
} if (m_isPinned)
void PinnableToolTipWidget::toolButtonClicked()
{
switch (m_pinState) {
case Unpinned:
pin();
break;
case Pinned:
close(); close();
break; else
} pin();
}
/* 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);
} }
/*! /*!
@@ -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. When restoring the data from a session, all tooltips start in 'released' mode.
Stored tooltips expire after toolTipsExpiryDays while loading to prevent 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. of them. On closing or session changes, the contents it saved.
*/ */
static QString msgReleasedText() { return AbstractDebuggerToolTipWidget::tr("Previous"); }
AbstractDebuggerToolTipWidget::AbstractDebuggerToolTipWidget(QWidget *parent) : static QString msgReleasedText() { return DebuggerToolTipWidget::tr("Previous"); }
PinnableToolTipWidget(parent),
m_titleLabel(new DraggableLabel), m_engineAcquired(false), DebuggerToolTipWidget::DebuggerToolTipWidget(QWidget *parent) :
m_creationDate(QDate::currentDate()) 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<QSize> 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; QToolButton *copyButton = new QToolButton;
copyButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_COPY))); copyButton->setIcon(QIcon(QLatin1String(Core::Constants::ICON_COPY)));
connect(copyButton, SIGNAL(clicked()), this, SLOT(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. m_titleLabel->setMinimumWidth(40); // Ensure a draggable area even if text is empty.
connect(m_titleLabel, SIGNAL(dragged(QPoint)), this, SLOT(slotDragged(QPoint))); connect(m_titleLabel, SIGNAL(dragged(QPoint)), this, SLOT(slotDragged(QPoint)));
addToolBarWidget(m_titleLabel); addToolBarWidget(m_titleLabel);
addWidget(m_treeView);
} }
bool AbstractDebuggerToolTipWidget::matches(const QString &fileName, bool DebuggerToolTipWidget::matches(const QString &fileName,
const QString &engineType, const QString &engineType,
const QString &function) const const QString &function) const
{ {
@@ -665,11 +664,10 @@ bool AbstractDebuggerToolTipWidget::matches(const QString &fileName,
return function == m_context.function; return function == m_context.function;
} }
void AbstractDebuggerToolTipWidget::acquireEngine(Debugger::DebuggerEngine *engine) void DebuggerToolTipWidget::acquireEngine(Debugger::DebuggerEngine *engine)
{ {
QTC_ASSERT(engine, return); QTC_ASSERT(engine, return);
if (debugToolTips) if (debugToolTips)
qDebug() << this << " acquiring" << engine << m_engineAcquired; qDebug() << this << " acquiring" << engine << m_engineAcquired;
if (m_engineAcquired) if (m_engineAcquired)
@@ -680,7 +678,7 @@ void AbstractDebuggerToolTipWidget::acquireEngine(Debugger::DebuggerEngine *engi
m_titleLabel->setText(QString()); m_titleLabel->setText(QString());
} }
void AbstractDebuggerToolTipWidget::releaseEngine() void DebuggerToolTipWidget::releaseEngine()
{ {
// Release engine of same type // Release engine of same type
if (!m_engineAcquired) if (!m_engineAcquired)
@@ -692,7 +690,7 @@ void AbstractDebuggerToolTipWidget::releaseEngine()
m_engineAcquired = false; m_engineAcquired = false;
} }
void AbstractDebuggerToolTipWidget::copy() void DebuggerToolTipWidget::copy()
{ {
const QString clipboardText = clipboardContents(); const QString clipboardText = clipboardContents();
QClipboard *clipboard = QApplication::clipboard(); QClipboard *clipboard = QApplication::clipboard();
@@ -702,13 +700,13 @@ void AbstractDebuggerToolTipWidget::copy()
clipboard->setText(clipboardText, QClipboard::Clipboard); clipboard->setText(clipboardText, QClipboard::Clipboard);
} }
void AbstractDebuggerToolTipWidget::slotDragged(const QPoint &p) void DebuggerToolTipWidget::slotDragged(const QPoint &p)
{ {
move(pos() + p); move(pos() + p);
m_offset += 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. // Figure out new position of tooltip using the text edit.
// If the line changed too much, close this tip. // If the line changed too much, close this tip.
@@ -748,19 +746,6 @@ bool AbstractDebuggerToolTipWidget::positionShow(const DebuggerToolTipEditor &te
return true; 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 // Parse a 'yyyyMMdd' date
static QDate dateFromString(const QString &date) static QDate dateFromString(const QString &date)
{ {
@@ -769,17 +754,17 @@ static QDate dateFromString(const QString &date)
QDate(); QDate();
} }
AbstractDebuggerToolTipWidget *AbstractDebuggerToolTipWidget::loadSessionData(QXmlStreamReader &r) DebuggerToolTipWidget *DebuggerToolTipWidget::loadSessionData(QXmlStreamReader &r)
{ {
if (debugToolTips) if (debugToolTips)
qDebug() << ">DebuggerToolTipWidget::loadSessionData" << r.tokenString() << r.name(); qDebug() << ">DebuggerToolTipWidget::loadSessionData" << r.tokenString() << r.name();
AbstractDebuggerToolTipWidget *rc = AbstractDebuggerToolTipWidget::loadSessionDataI(r); DebuggerToolTipWidget *rc = DebuggerToolTipWidget::loadSessionDataI(r);
if (debugToolTips) if (debugToolTips)
qDebug() << "<DebuggerToolTipWidget::loadSessionData" << r.tokenString() << r.name() << " returns " << rc; qDebug() << "<DebuggerToolTipWidget::loadSessionData" << r.tokenString() << r.name() << " returns " << rc;
return rc; return rc;
} }
AbstractDebuggerToolTipWidget *AbstractDebuggerToolTipWidget::loadSessionDataI(QXmlStreamReader &r) DebuggerToolTipWidget *DebuggerToolTipWidget::loadSessionDataI(QXmlStreamReader &r)
{ {
if (!readStartElement(r, toolTipElementC)) if (!readStartElement(r, toolTipElementC))
return 0; return 0;
@@ -809,9 +794,9 @@ AbstractDebuggerToolTipWidget *AbstractDebuggerToolTipWidget::loadSessionDataI(Q
} }
if (debugToolTips) if (debugToolTips)
qDebug() << "Creating tooltip " << context << " from " << creationDate << offset; qDebug() << "Creating tooltip " << context << " from " << creationDate << offset;
AbstractDebuggerToolTipWidget *rc = 0; DebuggerToolTipWidget *rc = 0;
if (className == "Debugger::Internal::DebuggerTreeViewToolTipWidget") if (className == "Debugger::Internal::DebuggerTreeViewToolTipWidget")
rc = new DebuggerTreeViewToolTipWidget; rc = new DebuggerToolTipWidget;
if (rc) { if (rc) {
rc->setContext(context); rc->setContext(context);
rc->setAttribute(Qt::WA_DeleteOnClose); rc->setAttribute(Qt::WA_DeleteOnClose);
@@ -828,7 +813,7 @@ AbstractDebuggerToolTipWidget *AbstractDebuggerToolTipWidget::loadSessionDataI(Q
return rc; return rc;
} }
void AbstractDebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const
{ {
w.writeStartElement(QLatin1String(toolTipElementC)); w.writeStartElement(QLatin1String(toolTipElementC));
QXmlStreamAttributes attributes; QXmlStreamAttributes attributes;
@@ -1006,28 +991,7 @@ void DebuggerToolTipTreeView::computeSize()
setRootIsDecorated(rootDecorated); setRootIsDecorated(rootDecorated);
} }
/*! void DebuggerToolTipWidget::doAcquireEngine(Debugger::DebuggerEngine *engine)
\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)
{ {
// Create a filter model on the debugger's model and switch to it. // Create a filter model on the debugger's model and switch to it.
QAbstractItemModel *model = 0; QAbstractItemModel *model = 0;
@@ -1048,7 +1012,7 @@ void DebuggerTreeViewToolTipWidget::doAcquireEngine(Debugger::DebuggerEngine *en
swapModel(filterModel); swapModel(filterModel);
} }
QAbstractItemModel *DebuggerTreeViewToolTipWidget::swapModel(QAbstractItemModel *newModel) QAbstractItemModel *DebuggerToolTipWidget::swapModel(QAbstractItemModel *newModel)
{ {
QAbstractItemModel *oldModel = m_treeView->swapModel(newModel); QAbstractItemModel *oldModel = m_treeView->swapModel(newModel);
// When looking at some 'this.m_foo.x', expand all items // When looking at some 'this.m_foo.x', expand all items
@@ -1062,7 +1026,7 @@ QAbstractItemModel *DebuggerTreeViewToolTipWidget::swapModel(QAbstractItemModel
return oldModel; return oldModel;
} }
void DebuggerTreeViewToolTipWidget::doReleaseEngine() void DebuggerToolTipWidget::doReleaseEngine()
{ {
// Save data to stream and restore to the m_defaultModel (QStandardItemModel) // Save data to stream and restore to the m_defaultModel (QStandardItemModel)
m_defaultModel->removeRows(0, m_defaultModel->rowCount()); m_defaultModel->removeRows(0, m_defaultModel->rowCount());
@@ -1073,7 +1037,7 @@ void DebuggerTreeViewToolTipWidget::doReleaseEngine()
delete swapModel(m_defaultModel); delete swapModel(m_defaultModel);
} }
void DebuggerTreeViewToolTipWidget::restoreTreeModel(QXmlStreamReader &r, QStandardItemModel *m) void DebuggerToolTipWidget::restoreTreeModel(QXmlStreamReader &r, QStandardItemModel *m)
{ {
StandardItemTreeModelBuilder builder(m); StandardItemTreeModelBuilder builder(m);
int columnCount = 1; int columnCount = 1;
@@ -1111,7 +1075,7 @@ void DebuggerTreeViewToolTipWidget::restoreTreeModel(QXmlStreamReader &r, QStand
} // while } // while
} }
void DebuggerTreeViewToolTipWidget::doSaveSessionData(QXmlStreamWriter &w) const void DebuggerToolTipWidget::doSaveSessionData(QXmlStreamWriter &w) const
{ {
w.writeStartElement(QLatin1String(treeElementC)); w.writeStartElement(QLatin1String(treeElementC));
QXmlStreamAttributes attributes; QXmlStreamAttributes attributes;
@@ -1125,7 +1089,7 @@ void DebuggerTreeViewToolTipWidget::doSaveSessionData(QXmlStreamWriter &w) const
w.writeEndElement(); w.writeEndElement();
} }
void DebuggerTreeViewToolTipWidget::doLoadSessionData(QXmlStreamReader &r) void DebuggerToolTipWidget::doLoadSessionData(QXmlStreamReader &r)
{ {
if (!readStartElement(r, treeElementC)) if (!readStartElement(r, treeElementC))
return; return;
@@ -1141,7 +1105,7 @@ void DebuggerTreeViewToolTipWidget::doLoadSessionData(QXmlStreamReader &r)
m_treeView->swapModel(m_defaultModel); m_treeView->swapModel(m_defaultModel);
} }
QString DebuggerTreeViewToolTipWidget::treeModelClipboardContents(const QAbstractItemModel *m) QString DebuggerToolTipWidget::treeModelClipboardContents(const QAbstractItemModel *m)
{ {
QString rc; QString rc;
QTextStream str(&rc); QTextStream str(&rc);
@@ -1150,10 +1114,10 @@ QString DebuggerTreeViewToolTipWidget::treeModelClipboardContents(const QAbstrac
return rc; return rc;
} }
QString DebuggerTreeViewToolTipWidget::clipboardContents() const QString DebuggerToolTipWidget::clipboardContents() const
{ {
if (const QAbstractItemModel *model = m_treeView->model()) if (const QAbstractItemModel *model = m_treeView->model())
return DebuggerTreeViewToolTipWidget::treeModelClipboardContents(model); return DebuggerToolTipWidget::treeModelClipboardContents(model);
return QString(); return QString();
} }
@@ -1193,7 +1157,7 @@ void DebuggerToolTipManager::registerEngine(DebuggerEngine *engine)
} }
void DebuggerToolTipManager::showToolTip(const QPoint &p, IEditor *editor, void DebuggerToolTipManager::showToolTip(const QPoint &p, IEditor *editor,
AbstractDebuggerToolTipWidget *toolTipWidget) DebuggerToolTipWidget *toolTipWidget)
{ {
QWidget *widget = editor->widget(); QWidget *widget = editor->widget();
if (debugToolTipPositioning) if (debugToolTipPositioning)
@@ -1203,45 +1167,29 @@ void DebuggerToolTipManager::showToolTip(const QPoint &p, IEditor *editor,
registerToolTip(toolTipWidget); registerToolTip(toolTipWidget);
} }
void DebuggerToolTipManager::registerToolTip(AbstractDebuggerToolTipWidget *toolTipWidget) void DebuggerToolTipManager::registerToolTip(DebuggerToolTipWidget *toolTipWidget)
{ {
QTC_ASSERT(toolTipWidget->context().isValid(), return); QTC_ASSERT(toolTipWidget->context().isValid(), return);
switch (toolTipWidget->pinState()) { m_tooltips.push_back(toolTipWidget);
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;
}
} }
void DebuggerToolTipManager::slotPinnedFirstTime() void DebuggerToolTipManager::purgeClosedToolTips()
{ {
if (AbstractDebuggerToolTipWidget *tw = qobject_cast<AbstractDebuggerToolTipWidget *>(sender())) for (DebuggerToolTipWidgetList::iterator it = m_tooltips.begin(); it != m_tooltips.end() ; ) {
m_pinnedTooltips.push_back(tw); if (it->isNull()) {
} it = m_tooltips.erase(it);
} else {
DebuggerToolTipManager::DebuggerToolTipWidgetList &DebuggerToolTipManager::purgeClosedToolTips() ++it;
{
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;
}
} }
} }
return m_pinnedTooltips;
} }
void DebuggerToolTipManager::moveToolTipsBy(const QPoint &distance) void DebuggerToolTipManager::moveToolTipsBy(const QPoint &distance)
{ {
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, purgeClosedToolTips()) purgeClosedToolTips();
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
if (tw->isVisible()) if (tw->isVisible())
tw->move (tw->pos() + distance); tw->move(tw->pos() + distance);
} }
bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e) bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e)
@@ -1258,9 +1206,11 @@ bool DebuggerToolTipManager::eventFilter(QObject *o, QEvent *e)
const QWindowStateChangeEvent *se = static_cast<const QWindowStateChangeEvent *>(e); const QWindowStateChangeEvent *se = static_cast<const QWindowStateChangeEvent *>(e);
const bool wasMinimized = se->oldState() & Qt::WindowMinimized; const bool wasMinimized = se->oldState() & Qt::WindowMinimized;
const bool isMinimized = static_cast<const QWidget *>(o)->windowState() & Qt::WindowMinimized; const bool isMinimized = static_cast<const QWidget *>(o)->windowState() & Qt::WindowMinimized;
if (wasMinimized ^ isMinimized) if (wasMinimized ^ isMinimized) {
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, purgeClosedToolTips()) purgeClosedToolTips();
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
tw->setVisible(!isMinimized); tw->setVisible(!isMinimized);
}
} }
break; break;
default: default:
@@ -1285,28 +1235,30 @@ void DebuggerToolTipManager::loadSessionData()
return; return;
const double version = r.attributes().value(QLatin1String(sessionVersionAttributeC)).toString().toDouble(); const double version = r.attributes().value(QLatin1String(sessionVersionAttributeC)).toString().toDouble();
while (!r.atEnd()) while (!r.atEnd())
if (AbstractDebuggerToolTipWidget *tw = AbstractDebuggerToolTipWidget::loadSessionData(r)) if (DebuggerToolTipWidget *tw = DebuggerToolTipWidget::loadSessionData(r))
registerToolTip(tw); registerToolTip(tw);
if (debugToolTips) if (debugToolTips)
qDebug() << "DebuggerToolTipManager::loadSessionData version " << version << " restored " << m_pinnedTooltips.size(); qDebug() << "DebuggerToolTipManager::loadSessionData version " << version << " restored " << m_tooltips.size();
slotUpdateVisibleToolTips(); slotUpdateVisibleToolTips();
} }
void DebuggerToolTipManager::saveSessionData() void DebuggerToolTipManager::saveSessionData()
{ {
QString data; QString data;
if (!purgeClosedToolTips().isEmpty()) { purgeClosedToolTips();
if (!m_tooltips.isEmpty()) {
QXmlStreamWriter w(&data); QXmlStreamWriter w(&data);
w.writeStartDocument(); w.writeStartDocument();
w.writeStartElement(QLatin1String(sessionDocumentC)); w.writeStartElement(QLatin1String(sessionDocumentC));
w.writeAttribute(QLatin1String(sessionVersionAttributeC), QLatin1String("1.0")); w.writeAttribute(QLatin1String(sessionVersionAttributeC), QLatin1String("1.0"));
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, m_pinnedTooltips) foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
tw->saveSessionData(w); if (tw->isPinned())
tw->saveSessionData(w);
w.writeEndDocument(); w.writeEndDocument();
} }
if (debugToolTips) if (debugToolTips)
qDebug() << "DebuggerToolTipManager::saveSessionData" << m_pinnedTooltips.size() << data ; qDebug() << "DebuggerToolTipManager::saveSessionData" << m_tooltips.size() << data ;
debuggerCore()->setSessionValue(QLatin1String(sessionSettingsKeyC), QVariant(data)); debuggerCore()->setSessionValue(QLatin1String(sessionSettingsKeyC), QVariant(data));
} }
@@ -1315,20 +1267,23 @@ void DebuggerToolTipManager::closeAllToolTips()
if (debugToolTips) if (debugToolTips)
qDebug() << "DebuggerToolTipManager::closeAllToolTips"; qDebug() << "DebuggerToolTipManager::closeAllToolTips";
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, purgeClosedToolTips()) purgeClosedToolTips();
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
tw->close(); tw->close();
m_pinnedTooltips.clear(); m_tooltips.clear();
} }
void DebuggerToolTipManager::hide() void DebuggerToolTipManager::hide()
{ {
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, purgeClosedToolTips()) purgeClosedToolTips();
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
tw->hide(); tw->hide();
} }
void DebuggerToolTipManager::slotUpdateVisibleToolTips() void DebuggerToolTipManager::slotUpdateVisibleToolTips()
{ {
if (purgeClosedToolTips().isEmpty()) purgeClosedToolTips();
if (m_tooltips.isEmpty())
return; return;
if (!m_debugModeActive) { if (!m_debugModeActive) {
hide(); hide();
@@ -1347,7 +1302,7 @@ void DebuggerToolTipManager::slotUpdateVisibleToolTips()
// Reposition and show all tooltips of that file. // Reposition and show all tooltips of that file.
const QString fileName = toolTipEditor.fileName(); const QString fileName = toolTipEditor.fileName();
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, m_pinnedTooltips) { foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips) {
if (tw->fileName() == fileName) { if (tw->fileName() == fileName) {
tw->positionShow(toolTipEditor); tw->positionShow(toolTipEditor);
} else { } else {
@@ -1373,11 +1328,13 @@ void DebuggerToolTipManager::slotDebuggerStateChanged(Debugger::DebuggerState st
case InferiorShutdownRequested: case InferiorShutdownRequested:
case EngineShutdownRequested: case EngineShutdownRequested:
case DebuggerFinished: case DebuggerFinished:
case EngineShutdownOk: case EngineShutdownOk: {
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, purgeClosedToolTips()) purgeClosedToolTips();
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips)
if (tw->engineType() == name) if (tw->engineType() == name)
tw->releaseEngine(); tw->releaseEngine();
break; break;
}
default: default:
break; break;
} }
@@ -1385,7 +1342,8 @@ void DebuggerToolTipManager::slotDebuggerStateChanged(Debugger::DebuggerState st
void DebuggerToolTipManager::slotStackFrameCompleted() void DebuggerToolTipManager::slotStackFrameCompleted()
{ {
if (purgeClosedToolTips().isEmpty()) purgeClosedToolTips();
if (m_tooltips.isEmpty())
return; return;
DebuggerEngine *engine = qobject_cast<DebuggerEngine *>(sender()); DebuggerEngine *engine = qobject_cast<DebuggerEngine *>(sender());
QTC_ASSERT(engine, return); QTC_ASSERT(engine, return);
@@ -1411,7 +1369,7 @@ void DebuggerToolTipManager::slotStackFrameCompleted()
qPrintable(engineName), qPrintable(fileName), lineNumber, qPrintable(engineName), qPrintable(fileName), lineNumber,
qPrintable(function)); qPrintable(function));
unsigned acquiredCount = 0; unsigned acquiredCount = 0;
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, m_pinnedTooltips) { foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips) {
if (tw->matches(fileName, engineName, function)) { if (tw->matches(fileName, engineName, function)) {
tw->acquireEngine(engine); tw->acquireEngine(engine);
acquiredCount++; acquiredCount++;
@@ -1460,7 +1418,7 @@ void DebuggerToolTipManager::debugModeEntered()
foreach (IEditor *e, em->openedEditors()) foreach (IEditor *e, em->openedEditors())
slotEditorOpened(e); slotEditorOpened(e);
// Position tooltips delayed once all the editor placeholder layouting is done. // 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())); QTimer::singleShot(0, this, SLOT(slotUpdateVisibleToolTips()));
} }
} }
@@ -1544,10 +1502,10 @@ QStringList DebuggerToolTipManager::treeWidgetExpressions(const QString &fileNam
const QString &function) const const QString &function) const
{ {
QStringList rc; QStringList rc;
foreach (const QPointer<AbstractDebuggerToolTipWidget> &tw, m_pinnedTooltips) foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips) {
if (!tw.isNull() && tw->matches(fileName, engineType, function)) if (!tw.isNull() && tw->matches(fileName, engineType, function))
if (const DebuggerTreeViewToolTipWidget *ttw = qobject_cast<const DebuggerTreeViewToolTipWidget *>(tw.data())) rc.push_back(tw->expression());
rc.push_back(ttw->expression()); }
if (debugToolTips) if (debugToolTips)
qDebug() << "DebuggerToolTipManager::treeWidgetExpressions" qDebug() << "DebuggerToolTipManager::treeWidgetExpressions"
<< fileName << engineType << function << rc; << fileName << engineType << function << rc;

View File

@@ -47,10 +47,7 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QVBoxLayout; class QVBoxLayout;
class QToolButton; class QToolButton;
class QSortFilterProxyModel;
class QStandardItemModel; class QStandardItemModel;
class QPlainTextEdit;
class QLabel;
class QToolBar; class QToolBar;
class QDebug; class QDebug;
QT_END_NAMESPACE QT_END_NAMESPACE
@@ -71,42 +68,6 @@ namespace Internal {
class DraggableLabel; class DraggableLabel;
class DebuggerToolTipEditor; 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 class DebuggerToolTipContext
{ {
public: public:
@@ -123,12 +84,19 @@ public:
QDebug operator<<(QDebug, const DebuggerToolTipContext &); QDebug operator<<(QDebug, const DebuggerToolTipContext &);
class AbstractDebuggerToolTipWidget : public PinnableToolTipWidget class DebuggerToolTipTreeView;
class DebuggerToolTipWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: 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; } bool engineAcquired() const { return m_engineAcquired; }
QString fileName() const { return m_context.fileName; } QString fileName() const { return m_context.fileName; }
@@ -151,66 +119,7 @@ public:
QPoint offset() const { return m_offset; } QPoint offset() const { return m_offset; }
void setOffset(const QPoint &o) { m_offset = o; } void setOffset(const QPoint &o) { m_offset = o; }
static AbstractDebuggerToolTipWidget *loadSessionData(QXmlStreamReader &r); static DebuggerToolTipWidget *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);
int debuggerModel() const { return m_debuggerModel; } int debuggerModel() const { return m_debuggerModel; }
void setDebuggerModel(int m) { m_debuggerModel = m; } void setDebuggerModel(int m) { m_debuggerModel = m; }
@@ -219,12 +128,39 @@ public:
static QString treeModelClipboardContents(const QAbstractItemModel *m); static QString treeModelClipboardContents(const QAbstractItemModel *m);
protected: public slots:
virtual void doAcquireEngine(Debugger::DebuggerEngine *engine); void saveSessionData(QXmlStreamWriter &w) const;
virtual void doReleaseEngine();
virtual void doSaveSessionData(QXmlStreamWriter &w) const; void acquireEngine(Debugger::DebuggerEngine *engine);
virtual void doLoadSessionData(QXmlStreamReader &r); void releaseEngine();
virtual QString clipboardContents() const; 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: private:
QAbstractItemModel *swapModel(QAbstractItemModel *newModel); QAbstractItemModel *swapModel(QAbstractItemModel *newModel);
@@ -237,6 +173,26 @@ private:
QStandardItemModel *m_defaultModel; 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 class DebuggerToolTipManager : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -247,14 +203,14 @@ public:
static DebuggerToolTipManager *instance() { return m_instance; } static DebuggerToolTipManager *instance() { return m_instance; }
void registerEngine(DebuggerEngine *engine); void registerEngine(DebuggerEngine *engine);
bool hasToolTips() const { return !m_pinnedTooltips.isEmpty(); } bool hasToolTips() const { return !m_tooltips.isEmpty(); }
// Collect all expressions of DebuggerTreeViewToolTipWidget // Collect all expressions of DebuggerTreeViewToolTipWidget
QStringList treeWidgetExpressions(const QString &fileName, QStringList treeWidgetExpressions(const QString &fileName,
const QString &engineType = QString(), const QString &engineType = QString(),
const QString &function= QString()) const; 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 *); virtual bool eventFilter(QObject *, QEvent *);
@@ -267,29 +223,28 @@ public slots:
void loadSessionData(); void loadSessionData();
void saveSessionData(); void saveSessionData();
void closeAllToolTips(); void closeAllToolTips();
void hide() void hide();
;
private slots: private slots:
void slotUpdateVisibleToolTips(); void slotUpdateVisibleToolTips();
void slotDebuggerStateChanged(Debugger::DebuggerState); void slotDebuggerStateChanged(Debugger::DebuggerState);
void slotStackFrameCompleted(); void slotStackFrameCompleted();
void slotEditorOpened(Core::IEditor *); void slotEditorOpened(Core::IEditor *);
void slotPinnedFirstTime();
void slotTooltipOverrideRequested(TextEditor::ITextEditor *editor, void slotTooltipOverrideRequested(TextEditor::ITextEditor *editor,
const QPoint &point, int pos, bool *handled); const QPoint &point, int pos, bool *handled);
private: private:
typedef QList<QPointer<AbstractDebuggerToolTipWidget> > DebuggerToolTipWidgetList; typedef QList<QPointer<DebuggerToolTipWidget> > DebuggerToolTipWidgetList;
void registerToolTip(AbstractDebuggerToolTipWidget *toolTipWidget); void registerToolTip(DebuggerToolTipWidget *toolTipWidget);
void moveToolTipsBy(const QPoint &distance); void moveToolTipsBy(const QPoint &distance);
// Purge out closed (null) tooltips and return list for convenience // Purge out closed (null) tooltips and return list for convenience
DebuggerToolTipWidgetList &purgeClosedToolTips(); void purgeClosedToolTips();
static DebuggerToolTipManager *m_instance; static DebuggerToolTipManager *m_instance;
DebuggerToolTipWidgetList m_pinnedTooltips; DebuggerToolTipWidgetList m_tooltips;
bool m_debugModeActive; bool m_debugModeActive;
QPoint m_lastToolTipPoint; QPoint m_lastToolTipPoint;
Core::IEditor *m_lastToolTipEditor; Core::IEditor *m_lastToolTipEditor;

View File

@@ -3542,7 +3542,7 @@ bool GdbEngine::showToolTip()
watchHandler()->removeData(iname); watchHandler()->removeData(iname);
return false; return false;
} }
DebuggerTreeViewToolTipWidget *tw = new DebuggerTreeViewToolTipWidget; DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
tw->setDebuggerModel(TooltipsWatch); tw->setDebuggerModel(TooltipsWatch);
tw->setExpression(expression); tw->setExpression(expression);
tw->setContext(*m_toolTipContext); tw->setContext(*m_toolTipContext);
@@ -3716,11 +3716,11 @@ void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &f
// << (m_pendingBreakpointRequests == 0); // << (m_pendingBreakpointRequests == 0);
UpdateParameters params; UpdateParameters params;
params.tooltipOnly = data.iname.startsWith("tooltip");
params.tryPartial = flags.tryIncremental params.tryPartial = flags.tryIncremental
&& hasPython() && hasPython()
&& m_pendingWatchRequests == 0 && m_pendingWatchRequests == 0
&& m_pendingBreakpointRequests == 0; && m_pendingBreakpointRequests == 0;
params.tooltipOnly = false;
params.varList = data.iname; params.varList = data.iname;
updateLocalsPython(params); updateLocalsPython(params);

View File

@@ -910,7 +910,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
} else if (act == actRemoveWatchExpression) { } else if (act == actRemoveWatchExpression) {
removeWatchExpression(exp); removeWatchExpression(exp);
} else if (act == actCopy) { } else if (act == actCopy) {
copyToClipboard(DebuggerTreeViewToolTipWidget::treeModelClipboardContents(model())); copyToClipboard(DebuggerToolTipWidget::treeModelClipboardContents(model()));
} else if (act == actCopyValue) { } else if (act == actCopyValue) {
copyToClipboard(mi1.data().toString()); copyToClipboard(mi1.data().toString());
} else if (act == actRemoveWatches) { } else if (act == actRemoveWatches) {