Commit cae3037d authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

Debugger: Add functionality for copying watch data to clipboard.

in watch window and tooltips.
parent f08e42f9
......@@ -65,6 +65,7 @@
#include <QtGui/QLabel>
#include <QtGui/QMenu>
#include <QtGui/QAction>
#include <QtGui/QClipboard>
#include <QtCore/QVariant>
#include <QtCore/QStack>
......@@ -294,10 +295,15 @@ void XmlWriterTreeModelVisitor::handleItem(const QModelIndex &m)
}
}
// TreeModelVisitor for debugging models
// TreeModelVisitor for debugging/copying models
class DumpTreeModelVisitor : public TreeModelVisitor {
public:
explicit DumpTreeModelVisitor(const QAbstractItemModel *model, QTextStream &s);
enum Mode
{
DebugMode, // For debugging, "|'data'|"
ClipboardMode // Tab-delimited "\tdata" for clipboard (see stack window)
};
explicit DumpTreeModelVisitor(const QAbstractItemModel *model, Mode m, QTextStream &s);
protected:
virtual void rowStarted();
......@@ -305,31 +311,61 @@ protected:
virtual void rowEnded();
private:
const Mode m_mode;
QTextStream &m_stream;
int m_level;
unsigned m_itemsInRow;
};
DumpTreeModelVisitor::DumpTreeModelVisitor(const QAbstractItemModel *model, QTextStream &s) :
TreeModelVisitor(model), m_stream(s), m_level(0)
DumpTreeModelVisitor::DumpTreeModelVisitor(const QAbstractItemModel *model, Mode m, QTextStream &s) :
TreeModelVisitor(model), m_mode(m), m_stream(s), m_level(0), m_itemsInRow(0)
{
m_stream << model->metaObject()->className() << '/' << model->objectName();
if (m_mode == DebugMode)
m_stream << model->metaObject()->className() << '/' << model->objectName();
}
void DumpTreeModelVisitor::rowStarted()
{
m_level++;
m_stream << '\n' << QString(2 * m_level, QLatin1Char(' '));
if (m_itemsInRow) { // Nested row.
m_stream << '\n';
m_itemsInRow = 0;
}
switch (m_mode) {
case DebugMode:
m_stream << QString(2 * m_level, QLatin1Char(' '));
break;
case ClipboardMode:
m_stream << QString(m_level, QLatin1Char('\t'));
break;
}
}
void DumpTreeModelVisitor::handleItem(const QModelIndex &m)
{
if (m.column())
m_stream << '|';
m_stream << '\'' << m.data().toString() << '\'';
const QString data = m.data().toString();
switch (m_mode) {
case DebugMode:
if (m.column())
m_stream << '|';
m_stream << '\'' << data << '\'';
break;
case ClipboardMode:
if (m.column())
m_stream << '\t';
m_stream << data;
break;
}
m_itemsInRow++;
}
void DumpTreeModelVisitor::rowEnded()
{
if (m_itemsInRow) {
m_stream << '\n';
m_itemsInRow = 0;
}
m_level--;
}
......@@ -340,7 +376,7 @@ static inline QDebug operator<<(QDebug d, const QAbstractItemModel &model)
{
QString s;
QTextStream str(&s);
Debugger::Internal::DumpTreeModelVisitor v(&model, str);
Debugger::Internal::DumpTreeModelVisitor v(&model, Debugger::Internal::DumpTreeModelVisitor::DebugMode, str);
v.run();
qDebug().nospace() << s;
return d;
......@@ -390,7 +426,6 @@ PinnableToolTipWidget::PinnableToolTipWidget(QWidget *parent) :
const QList<QSize> pinIconSizes = pinIcon.availableSizes();
m_toolButton->setIcon(pinIcon);
m_menu->addAction(tr("Close All"), this, SIGNAL(closeAllRequested()));
m_toolButton->setMenu(m_menu);
m_toolButton->setPopupMode(QToolButton::MenuButtonPopup);
connect(m_toolButton, SIGNAL(clicked()), this, SLOT(toolButtonClicked()));
......@@ -405,6 +440,16 @@ PinnableToolTipWidget::PinnableToolTipWidget(QWidget *parent) :
setLayout(m_mainVBoxLayout);
}
void PinnableToolTipWidget::addMenuAction(QAction *a)
{
m_menu->addAction(a);
}
void PinnableToolTipWidget::addCloseAllMenuAction()
{
m_menu->addAction(tr("Close All"), this, SIGNAL(closeAllRequested()));
}
void PinnableToolTipWidget::addWidget(QWidget *w)
{
w->setFocusPolicy(Qt::NoFocus);
......@@ -510,6 +555,10 @@ AbstractDebuggerToolTipWidget::AbstractDebuggerToolTipWidget(QWidget *parent) :
{
m_titleLabel->setText(msgReleasedText());
addToolBarWidget(m_titleLabel);
QAction *copyAction = new QAction(tr("Copy"), this);
connect(copyAction, SIGNAL(triggered()), this, SLOT(copy()));
addMenuAction(copyAction);
addCloseAllMenuAction();
}
bool AbstractDebuggerToolTipWidget::matches(const QString &fileName,
......@@ -553,6 +602,16 @@ void AbstractDebuggerToolTipWidget::releaseEngine()
m_engineAcquired = false;
}
void AbstractDebuggerToolTipWidget::copy()
{
const QString clipboardText = clipboardContents();
QClipboard *clipboard = QApplication::clipboard();
#ifdef Q_WS_X11
clipboard->setText(clipboardText, QClipboard::Selection);
#endif
clipboard->setText(clipboardText, QClipboard::Clipboard);
}
bool AbstractDebuggerToolTipWidget::positionShow(const QPlainTextEdit *pe)
{
// Figure out new position of tooltip using the text edit.
......@@ -912,6 +971,22 @@ void DebuggerTreeViewToolTipWidget::doLoadSessionData(QXmlStreamReader &r)
m_treeView->swapModel(m_defaultModel);
}
QString DebuggerTreeViewToolTipWidget::treeModelClipboardContents(const QAbstractItemModel *m)
{
QString rc;
QTextStream str(&rc);
DumpTreeModelVisitor v(m, DumpTreeModelVisitor::ClipboardMode, str);
v.run();
return rc;
}
QString DebuggerTreeViewToolTipWidget::clipboardContents() const
{
if (const QAbstractItemModel *model = m_treeView->model())
return DebuggerTreeViewToolTipWidget::treeModelClipboardContents(model);
return QString();
}
/*!
\class DebuggerToolTipManager
......
......@@ -54,6 +54,7 @@ class QLabel;
class QToolBar;
class QMenu;
class QDebug;
class QAction;
QT_END_NAMESPACE
namespace Core {
......@@ -82,6 +83,9 @@ public:
void addWidget(QWidget *w);
void addToolBarWidget(QWidget *w);
void addMenuAction(QAction *a);
// Add an action to "close all". Call in constructor after populating the tool button menu.
void addCloseAllMenuAction();
public slots:
void pin();
......@@ -151,6 +155,7 @@ public slots:
void acquireEngine(Debugger::DebuggerEngine *engine);
void releaseEngine();
void copy();
bool positionShow(const QPlainTextEdit *pe);
protected:
......@@ -158,6 +163,8 @@ protected:
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);
......@@ -202,11 +209,14 @@ public:
QString expression() const { return m_expression; }
void setExpression(const QString &e) { m_expression = e; }
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;
private:
static void restoreTreeModel(QXmlStreamReader &r, QStandardItemModel *m);
......
......@@ -41,6 +41,7 @@
#include "debuggerengine.h"
#include "watchdelegatewidgets.h"
#include "watchhandler.h"
#include "debuggertooltipmanager.h"
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
......@@ -55,7 +56,8 @@
#include <QtGui/QItemDelegate>
#include <QtGui/QMenu>
#include <QtGui/QResizeEvent>
#include <QtGui/QClipboard>
#include <QtGui/QApplication>
/////////////////////////////////////////////////////////////////////
//
......@@ -421,6 +423,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
memoryMenu.setEnabled(false);
}
QAction *actCopy = new QAction(tr("Copy Contents to Clipboard"), &menu);
menu.addAction(actInsertNewWatchItem);
menu.addAction(actSelectWidgetToWatch);
menu.addMenu(&formatMenu);
......@@ -428,6 +432,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
menu.addAction(actSetWatchpointAtVariableAddress);
if (actSetWatchpointAtPointerValue)
menu.addAction(actSetWatchpointAtPointerValue);
menu.addAction(actCopy );
menu.addSeparator();
menu.addAction(debuggerCore()->action(UseDebuggingHelpers));
......@@ -485,6 +490,13 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
watchExpression(exp);
} else if (act == actRemoveWatchExpression) {
removeWatchExpression(exp);
} else if (act == actCopy ) {
const QString clipboardText = DebuggerTreeViewToolTipWidget::treeModelClipboardContents(model());
QClipboard *clipboard = QApplication::clipboard();
#ifdef Q_WS_X11
clipboard->setText(clipboardText, QClipboard::Selection);
#endif
clipboard->setText(clipboardText, QClipboard::Clipboard);
} else if (act == actRemoveWatches) {
currentEngine()->watchHandler()->clearWatches();
} else if (act == actClearCodeModelSnapshot) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment