Merge remote-tracking branch 'origin/2.6'

This commit is contained in:
Eike Ziller
2012-09-03 09:08:49 +02:00
27 changed files with 249 additions and 142 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -47,7 +47,8 @@
either a password or an SSH key. If you do not have an SSH key, you can either a password or an SSH key. If you do not have an SSH key, you can
create it in \QC. For more information, see \l {Generating SSH Keys}. create it in \QC. For more information, see \l {Generating SSH Keys}.
To configure connections between \QC and embedded Linux devices: To configure connections between \QC and an embedded Linux device and to
specify build and run settings for the device:
\list 1 \list 1
@@ -90,6 +91,10 @@
\endlist \endlist
\o Select \gui Tools > \gui Options > \gui {Build & Run} > \gui Targets
> \gui Add to add a target for building for the device. Select the
Qt version, compiler, and device that you added above.
\o To specify build settings: \o To specify build settings:
\list 1 \list 1
@@ -97,26 +102,17 @@
\o Open a project for an application you want to develop for the \o Open a project for an application you want to develop for the
device. device.
\o Select \gui {Projects > Desktop > Build}. \o Select \gui {Projects > Targets > Add}.
\o Select the Qt version and tool chain for the embedded Linux \o Select the target that you added above.
device.
\endlist \endlist
\o To specify run settings: \o To specify run settings, select \gui Run.
\list 1
\o Select \gui {Run > Add > Deploy to Remote Linux Host}
to add a new deploy configuration.
\image qtcreator-run-settings-linux-devices.png "Run settings for embedded Linux devices" \image qtcreator-run-settings-linux-devices.png "Run settings for embedded Linux devices"
\o In the \gui {Device configuration} field, select the device Usually, you can use the default settings.
connection.
\endlist
When you run the project, \QC deploys the application as specified by the When you run the project, \QC deploys the application as specified by the
deploy steps. By default, \QC copies the application files to the device. deploy steps. By default, \QC copies the application files to the device.

View File

@@ -47,7 +47,7 @@
\image qtcreator-open-project-targets.png "Configure Project tab" \image qtcreator-open-project-targets.png "Configure Project tab"
Even if you do not intend to build the project, the C++ and QML code models Even if you do not intend to build the project, the C++ and QML code models
need a Qt version and tool chain to offer code completion. To specify them, need a Qt version and compiler to offer code completion. To specify them,
select the \gui Options link, or select \gui {Tools > Options > Build & Run select the \gui Options link, or select \gui {Tools > Options > Build & Run
> Targets}. > Targets}.

View File

@@ -33,7 +33,7 @@
\QC groups platform specific settings as \e targets to make cross-platform \QC groups platform specific settings as \e targets to make cross-platform
development easier. Each target consists of a set of values that define one development easier. Each target consists of a set of values that define one
environment, such as a device, tool chain, Qt version, and debugger command environment, such as a device, compiler, Qt version, and debugger command
to use, and some metadata, such as an icon and a name for the target. Once to use, and some metadata, such as an icon and a name for the target. Once
you have defined targets, you can select them to build and run projects. you have defined targets, you can select them to build and run projects.
@@ -85,8 +85,8 @@
image is located. If you are not cross-compiling, leave this field image is located. If you are not cross-compiling, leave this field
empty. empty.
\o In the \gui {Tool chain} field, select the tool chain required \o In the \gui {Compiler} field, select the compiler required
to build the project. You can add tool chains to the list to build the project. You can add compilers to the list
if they are installed on the development PC, but were not detected if they are installed on the development PC, but were not detected
automatically. For more information, see \l{Adding Compilers}. automatically. For more information, see \l{Adding Compilers}.

View File

@@ -745,26 +745,6 @@
typedef long long int64_t; typedef long long int64_t;
typedef unsigned long long uint64_t; typedef unsigned long long uint64_t;
#endif #endif
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
#if (( !defined( _MSC_VER ) || TARGET_OS_WINDOWS_CE ) && !defined( _WIN32 ) ) #if (( !defined( _MSC_VER ) || TARGET_OS_WINDOWS_CE ) && !defined( _WIN32 ) )
typedef long int intptr_t; typedef long int intptr_t;

View File

@@ -79,9 +79,33 @@ namespace ZeroConf { namespace embeddedLib {
DWORD err = WSAGetLastError(); DWORD err = WSAGetLastError();
(void) priority; (void) priority;
va_start( args, message ); va_start( args, message );
#ifdef _MSC_VER
len = _vscprintf( message, args ) + 1; len = _vscprintf( message, args ) + 1;
buffer = reinterpret_cast<char*>(malloc( len * sizeof(char) )); buffer = reinterpret_cast<char*>(malloc( len * sizeof(char) ));
if ( buffer ) { vsprintf( buffer, message, args ); OutputDebugStringA( buffer ); free( buffer ); } if ( buffer ) {
vsprintf(buffer, message, args);
OutputDebugStringA(buffer);
free(buffer);
}
#else // MinGW 4.4, no longer required for 4.6
len = vsnprintf(NULL, 0, message, args);
va_end(args);
if (len == -1) // encoding error
return;
buffer = reinterpret_cast<char*>(malloc((len + 1) * sizeof(char)));
if (buffer == NULL) // no memory allocation possible
return;
va_start(args, message);
len = vsnprintf(buffer, (len + 1) * sizeof(char), message, args);
va_end(args);
if (len == -1) { // encoding error
free(buffer);
return;
} else {
OutputDebugStringA(buffer);
free(buffer);
}
#endif
WSASetLastError( err ); WSASetLastError( err );
} }
}} }}

View File

@@ -423,8 +423,14 @@ void CMakeRunPage::initializePage()
if (hasCodeBlocksGenerator && (cachedGenerator.isEmpty() || cachedGenerator == "NMake Makefiles")) if (hasCodeBlocksGenerator && (cachedGenerator.isEmpty() || cachedGenerator == "NMake Makefiles"))
m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(p->displayName()), profileVariant); m_generatorComboBox->addItem(tr("NMake Generator (%1)").arg(p->displayName()), profileVariant);
} else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) { } else if (targetAbi.osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) {
#ifdef Q_OS_WIN
if (cachedGenerator.isEmpty() || cachedGenerator == "MinGW Makefiles") if (cachedGenerator.isEmpty() || cachedGenerator == "MinGW Makefiles")
m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(p->displayName()), profileVariant); m_generatorComboBox->addItem(tr("MinGW Generator (%1)").arg(p->displayName()), profileVariant);
#else
if (cachedGenerator.isEmpty() || cachedGenerator == "Unix Makefiles")
m_generatorComboBox->addItem(tr("Unix Generator (%1)").arg(p->displayName()), profileVariant);
#endif
} }
} else { } else {
// Non windows // Non windows
@@ -460,7 +466,11 @@ void CMakeRunPage::runCMake()
QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles"); QString generator = QLatin1String("-GCodeBlocks - Unix Makefiles");
if (tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS) { if (tc->targetAbi().os() == ProjectExplorer::Abi::WindowsOS) {
if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor) if (tc->targetAbi().osFlavor() == ProjectExplorer::Abi::WindowsMSysFlavor)
#ifdef Q_OS_WIN
generator = QLatin1String("-GCodeBlocks - MinGW Makefiles"); generator = QLatin1String("-GCodeBlocks - MinGW Makefiles");
#else
generator = QLatin1String("-GCodeBlocks - Unix Makefiles");
#endif
else else
generator = QLatin1String("-GCodeBlocks - NMake Makefiles"); generator = QLatin1String("-GCodeBlocks - NMake Makefiles");
} }

View File

@@ -404,6 +404,7 @@ void CdbEngine::init()
m_sourceStepInto = false; m_sourceStepInto = false;
m_watchPointX = m_watchPointY = 0; m_watchPointX = m_watchPointY = 0;
m_ignoreCdbOutput = false; m_ignoreCdbOutput = false;
m_watchInameToName.clear();
m_outputBuffer.clear(); m_outputBuffer.clear();
m_builtinCommandQueue.clear(); m_builtinCommandQueue.clear();
@@ -470,23 +471,13 @@ bool CdbEngine::setToolTipExpression(const QPoint &mousePos,
// Are we in the current stack frame // Are we in the current stack frame
if (context.function.isEmpty() || exp.isEmpty() || context.function != stackHandler()->currentFrame().function) if (context.function.isEmpty() || exp.isEmpty() || context.function != stackHandler()->currentFrame().function)
return false; return false;
// No numerical or any other expressions [yet] // Show tooltips of local variables only. Anything else can slow debugging down.
if (!(exp.at(0).isLetter() || exp.at(0) == QLatin1Char('_'))) const WatchData *localVariable = watchHandler()->findCppLocalVariable(exp);
if (!localVariable)
return false; return false;
// Can this be found as a local variable?
const QByteArray localsPrefix(localsPrefixC);
QByteArray iname = localsPrefix + exp.toAscii();
if (!watchHandler()->hasItem(iname)) {
// Nope, try a 'local.this.m_foo'.
exp.prepend(QLatin1String("this."));
iname.insert(localsPrefix.size(), "this.");
if (!watchHandler()->hasItem(iname))
return false;
}
DebuggerToolTipWidget *tw = new DebuggerToolTipWidget; DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
tw->setContext(context); tw->setContext(context);
tw->setDebuggerModel(LocalsType); tw->setIname(localVariable->iname);
tw->setExpression(exp);
tw->acquireEngine(this); tw->acquireEngine(this);
DebuggerToolTipManager::instance()->showToolTip(mousePos, editor, tw); DebuggerToolTipManager::instance()->showToolTip(mousePos, editor, tw);
return true; return true;
@@ -995,6 +986,10 @@ void CdbEngine::updateWatchData(const WatchData &dataIn,
QByteArray args; QByteArray args;
ByteArrayInputStream str(args); ByteArrayInputStream str(args);
str << dataIn.iname << " \"" << dataIn.exp << '"'; str << dataIn.iname << " \"" << dataIn.exp << '"';
// Store the name since the CDB extension library
// does not maintain the names of watches.
if (!dataIn.name.isEmpty() && dataIn.name != QLatin1String(dataIn.exp))
m_watchInameToName.insert(dataIn.iname, dataIn.name);
postExtensionCommand("addwatch", args, 0, postExtensionCommand("addwatch", args, 0,
&CdbEngine::handleAddWatch, 0, &CdbEngine::handleAddWatch, 0,
qVariantFromValue(dataIn)); qVariantFromValue(dataIn));
@@ -1916,6 +1911,15 @@ void CdbEngine::handleLocals(const CdbExtensionCommandPtr &reply)
dummy.name = QLatin1String(child.findChild("name").data()); dummy.name = QLatin1String(child.findChild("name").data());
parseWatchData(watchHandler()->expandedINames(), dummy, child, &watchData); parseWatchData(watchHandler()->expandedINames(), dummy, child, &watchData);
} }
// Fix the names of watch data.
for (int i =0; i < watchData.size(); ++i) {
if (watchData.at(i).iname.startsWith('w')) {
const QHash<QByteArray, QString>::const_iterator it
= m_watchInameToName.find(watchData.at(i).iname);
if (it != m_watchInameToName.constEnd())
watchData[i].name = it.value();
}
}
watchHandler()->insertData(watchData); watchHandler()->insertData(watchData);
if (debugLocals) { if (debugLocals) {
QDebug nsp = qDebug().nospace(); QDebug nsp = qDebug().nospace();

View File

@@ -275,6 +275,7 @@ private:
PendingBreakPointMap m_pendingBreakpointMap; PendingBreakPointMap m_pendingBreakpointMap;
QHash<QString, QString> m_fileNameModuleHash; QHash<QString, QString> m_fileNameModuleHash;
QMultiHash<QString, quint64> m_symbolAddressCache; QMultiHash<QString, quint64> m_symbolAddressCache;
QHash<QByteArray, QString> m_watchInameToName;
bool m_ignoreCdbOutput; bool m_ignoreCdbOutput;
QVariantList m_customSpecialStopData; QVariantList m_customSpecialStopData;
QList<SourcePathMapping> m_sourcePathMappings; QList<SourcePathMapping> m_sourcePathMappings;

View File

@@ -1144,7 +1144,12 @@ public slots:
exp = fixCppExpression(exp); exp = fixCppExpression(exp);
if (exp.isEmpty()) if (exp.isEmpty())
return; return;
currentEngine()->watchHandler()->watchExpression(exp); const QString name = exp;
// Prefer to watch an existing local variable by its expression (address) if it can be found.
WatchHandler *watchHandler = currentEngine()->watchHandler();
if (const WatchData *localVariable = watchHandler->findCppLocalVariable(exp))
exp = QLatin1String(localVariable->exp);
watchHandler->watchExpression(exp, name);
} }
void handleExecExit() void handleExecExit()

View File

@@ -98,8 +98,8 @@ static const char offsetYAttributeC[] = "offset_y";
static const char engineTypeAttributeC[] = "engine"; static const char engineTypeAttributeC[] = "engine";
static const char dateAttributeC[] = "date"; static const char dateAttributeC[] = "date";
static const char treeElementC[] = "tree"; static const char treeElementC[] = "tree";
static const char treeModelAttributeC[] = "model"; // Locals/Watches static const char treeExpressionAttributeC[] = "expression";
static const char treeExpressionAttributeC[] = "expression"; // Locals/Watches static const char treeInameAttributeC[] = "iname";
static const char modelElementC[] = "model"; static const char modelElementC[] = "model";
static const char modelColumnCountAttributeC[] = "columncount"; static const char modelColumnCountAttributeC[] = "columncount";
static const char modelRowElementC[] = "row"; static const char modelRowElementC[] = "row";
@@ -615,7 +615,6 @@ DebuggerToolTipWidget::DebuggerToolTipWidget(QWidget *parent) :
m_titleLabel(new DraggableLabel), m_titleLabel(new DraggableLabel),
m_engineAcquired(false), m_engineAcquired(false),
m_creationDate(QDate::currentDate()), m_creationDate(QDate::currentDate()),
m_debuggerModel(TooltipType),
m_treeView(new DebuggerToolTipTreeView), m_treeView(new DebuggerToolTipTreeView),
m_defaultModel(new QStandardItemModel(this)) m_defaultModel(new QStandardItemModel(this))
{ {
@@ -836,11 +835,7 @@ void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const
/*! /*!
\class Debugger::Internal::TooltipFilterModel \class Debugger::Internal::TooltipFilterModel
\brief Model for tooltips filtering a local variable using the locals or tooltip model, \brief Model for tooltips filtering an item on the watchhandler matching its tree on the iname.
matching on the name.
Expressions/names can either be flat ('foo' will match at the root level)
or nested ('this.m_foo' will match 'this' at root level and 'm_foo' at level 1).
In addition, suppress the model's tooltip data to avoid a tooltip on a tooltip. In addition, suppress the model's tooltip data to avoid a tooltip on a tooltip.
*/ */
@@ -848,9 +843,8 @@ void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const
class TooltipFilterModel : public QSortFilterProxyModel class TooltipFilterModel : public QSortFilterProxyModel
{ {
public: public:
TooltipFilterModel(QAbstractItemModel *model, const QString &exp, int debuggerModel) : TooltipFilterModel(QAbstractItemModel *model, const QByteArray &iname)
m_expressions(exp.split(QLatin1Char('.'))), : m_iname(iname)
m_debuggerModel(debuggerModel)
{ {
setSourceModel(model); setSourceModel(model);
} }
@@ -864,27 +858,21 @@ public:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
private: private:
const QStringList m_expressions; const QByteArray m_iname;
int m_debuggerModel;
}; };
static bool isSubIname(const QByteArray &haystack, const QByteArray &needle)
{
return haystack.size() > needle.size()
&& haystack.startsWith(needle)
&& haystack.at(needle.size()) == '.';
}
bool TooltipFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const bool TooltipFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{ {
const QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent); const QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent);
QByteArray iname = nameIndex.data(LocalsINameRole).toByteArray(); const QByteArray iname = nameIndex.data(LocalsINameRole).toByteArray();
if (m_debuggerModel == LocalsType && !iname.startsWith("local")) return iname == m_iname || isSubIname(iname, m_iname) || isSubIname(m_iname, iname);
return false;
if (m_debuggerModel == TooltipType && !iname.startsWith("tooltip"))
return false;
// Match on expression for top level, else pass through.
const int depth = iname.count('.');
if (depth == 0)
return true;
if (depth > m_expressions.size())
return true;
const QString name = nameIndex.data().toString();
//const QString exp = nameIndex.data(LocalsExpressionRole).toString();
return name == m_expressions.at(depth - 1);
} }
/*! /*!
@@ -991,7 +979,7 @@ void DebuggerToolTipWidget::doAcquireEngine(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 = engine->watchModel(); QAbstractItemModel *model = engine->watchModel();
TooltipFilterModel *filterModel = TooltipFilterModel *filterModel =
new TooltipFilterModel(model, m_expression, m_debuggerModel); new TooltipFilterModel(model, m_iname);
swapModel(filterModel); swapModel(filterModel);
} }
@@ -1000,7 +988,7 @@ QAbstractItemModel *DebuggerToolTipWidget::swapModel(QAbstractItemModel *newMode
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
if (newModel) { if (newModel) {
if (const int level = m_expression.count(QLatin1Char('.')) + 1) { if (const int level = m_iname.count('.')) {
QModelIndex index = newModel->index(0, 0); QModelIndex index = newModel->index(0, 0);
for (int i = 0; i < level && index.isValid(); i++, index = index.child(0, 0)) for (int i = 0; i < level && index.isValid(); i++, index = index.child(0, 0))
m_treeView->setExpanded(index, true); m_treeView->setExpanded(index, true);
@@ -1062,8 +1050,9 @@ void DebuggerToolTipWidget::doSaveSessionData(QXmlStreamWriter &w) const
{ {
w.writeStartElement(QLatin1String(treeElementC)); w.writeStartElement(QLatin1String(treeElementC));
QXmlStreamAttributes attributes; QXmlStreamAttributes attributes;
attributes.append(QLatin1String(treeModelAttributeC), QString::number(m_debuggerModel)); if (!m_expression.isEmpty())
attributes.append(QLatin1String(treeExpressionAttributeC), m_expression); attributes.append(QLatin1String(treeExpressionAttributeC), m_expression);
attributes.append(QLatin1String(treeInameAttributeC), QLatin1String(m_iname));
w.writeAttributes(attributes); w.writeAttributes(attributes);
if (QAbstractItemModel *model = m_treeView->model()) { if (QAbstractItemModel *model = m_treeView->model()) {
XmlWriterTreeModelVisitor v(model, w); XmlWriterTreeModelVisitor v(model, w);
@@ -1078,11 +1067,11 @@ void DebuggerToolTipWidget::doLoadSessionData(QXmlStreamReader &r)
return; return;
// Restore data to default model and show that. // Restore data to default model and show that.
const QXmlStreamAttributes attributes = r.attributes(); const QXmlStreamAttributes attributes = r.attributes();
m_debuggerModel = attributes.value(QLatin1String(treeModelAttributeC)).toString().toInt(); m_iname = attributes.value(QLatin1String(treeInameAttributeC)).toString().toLatin1();
m_expression = attributes.value(QLatin1String(treeExpressionAttributeC)).toString(); m_expression = attributes.value(QLatin1String(treeExpressionAttributeC)).toString();
if (debugToolTips) if (debugToolTips)
qDebug() << "DebuggerTreeViewToolTipWidget::doLoadSessionData() " << m_debuggerModel << m_expression; qDebug() << "DebuggerTreeViewToolTipWidget::doLoadSessionData() " << m_debuggerModel << m_iname;
setObjectName(QLatin1String("DebuggerTreeViewToolTipWidget: ") + m_expression); setObjectName(QLatin1String("DebuggerTreeViewToolTipWidget: ") + QLatin1String(m_iname));
restoreTreeModel(r, m_defaultModel); restoreTreeModel(r, m_defaultModel);
r.readNext(); // Skip </tree> r.readNext(); // Skip </tree>
m_treeView->swapModel(m_defaultModel); m_treeView->swapModel(m_defaultModel);
@@ -1480,14 +1469,16 @@ void DebuggerToolTipManager::slotTooltipOverrideRequested(ITextEditor *editor,
qDebug() << "<slotTooltipOverrideRequested() " << currentEngine << *handled; qDebug() << "<slotTooltipOverrideRequested() " << currentEngine << *handled;
} }
QStringList DebuggerToolTipManager::treeWidgetExpressions(const QString &fileName,
const QString &engineType, DebuggerToolTipManager::ExpressionInamePairs
const QString &function) const DebuggerToolTipManager::treeWidgetExpressions(const QString &fileName,
const QString &engineType,
const QString &function) const
{ {
QStringList rc; ExpressionInamePairs rc;
foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips) { foreach (const QPointer<DebuggerToolTipWidget> &tw, m_tooltips) {
if (!tw.isNull() && tw->matches(fileName, engineType, function)) if (!tw.isNull() && tw->matches(fileName, engineType, function))
rc.push_back(tw->expression()); rc.push_back(ExpressionInamePair(tw->expression(), tw->iname()));
} }
if (debugToolTips) if (debugToolTips)
qDebug() << "DebuggerToolTipManager::treeWidgetExpressions" qDebug() << "DebuggerToolTipManager::treeWidgetExpressions"

View File

@@ -119,8 +119,9 @@ public:
static DebuggerToolTipWidget *loadSessionData(QXmlStreamReader &r); static DebuggerToolTipWidget *loadSessionData(QXmlStreamReader &r);
int debuggerModel() const { return m_debuggerModel; } QByteArray iname() const { return m_iname; }
void setDebuggerModel(int m) { m_debuggerModel = m; } void setIname(const QByteArray &e) { m_iname = e; }
QString expression() const { return m_expression; } QString expression() const { return m_expression; }
void setExpression(const QString &e) { m_expression = e; } void setExpression(const QString &e) { m_expression = e; }
@@ -166,6 +167,7 @@ private:
int m_debuggerModel; int m_debuggerModel;
QString m_expression; QString m_expression;
QByteArray m_iname;
DebuggerToolTipTreeView *m_treeView; DebuggerToolTipTreeView *m_treeView;
QStandardItemModel *m_defaultModel; QStandardItemModel *m_defaultModel;
@@ -196,6 +198,9 @@ class DebuggerToolTipManager : public QObject
Q_OBJECT Q_OBJECT
public: public:
typedef QPair<QString, QByteArray> ExpressionInamePair;
typedef QList<ExpressionInamePair> ExpressionInamePairs;
explicit DebuggerToolTipManager(QObject *parent = 0); explicit DebuggerToolTipManager(QObject *parent = 0);
virtual ~DebuggerToolTipManager(); virtual ~DebuggerToolTipManager();
@@ -204,9 +209,9 @@ public:
bool hasToolTips() const { return !m_tooltips.isEmpty(); } bool hasToolTips() const { return !m_tooltips.isEmpty(); }
// Collect all expressions of DebuggerTreeViewToolTipWidget // Collect all expressions of DebuggerTreeViewToolTipWidget
QStringList treeWidgetExpressions(const QString &fileName, ExpressionInamePairs 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, DebuggerToolTipWidget *); void showToolTip(const QPoint &p, Core::IEditor *editor, DebuggerToolTipWidget *);

View File

@@ -1022,7 +1022,8 @@ void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response)
parseWatchData(watchHandler()->expandedINames(), data, contents, &list); parseWatchData(watchHandler()->expandedINames(), data, contents, &list);
//for (int i = 0; i != list.size(); ++i) //for (int i = 0; i != list.size(); ++i)
// qDebug() << "READ: " << list.at(i).toString(); // qDebug() << "READ: " << list.at(i).toString();
watchHandler()->insertData(list); foreach (const WatchData &data, list)
insertData(data);
} }
void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response) void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
@@ -1238,6 +1239,9 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
frame.function, frame.file, frame.line, frame.function, frame.file, frame.line,
&uninitializedVariables); &uninitializedVariables);
} }
WatchHandler *handler = watchHandler();
insertData(*handler->findData("local"));
foreach (const GdbMi &item, locals) { foreach (const GdbMi &item, locals) {
const WatchData data = localVariable(item, uninitializedVariables, &seen); const WatchData data = localVariable(item, uninitializedVariables, &seen);
if (data.isValid()) if (data.isValid())
@@ -1252,7 +1256,7 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
insertData(rd); insertData(rd);
} }
watchHandler()->updateWatchers(); handler->updateWatchers();
} }
static void showQtDumperLibraryWarning(const QString &details) static void showQtDumperLibraryWarning(const QString &details)

View File

@@ -118,6 +118,7 @@ public:
QPoint mousePosition; QPoint mousePosition;
QString expression; QString expression;
QByteArray iname;
Core::IEditor *editor; Core::IEditor *editor;
}; };
@@ -3845,22 +3846,19 @@ void GdbEngine::showToolTip()
if (m_toolTipContext.isNull()) if (m_toolTipContext.isNull())
return; return;
const QString expression = m_toolTipContext->expression; const QString expression = m_toolTipContext->expression;
const QByteArray iname = tooltipIName(m_toolTipContext->expression);
if (DebuggerToolTipManager::debug()) if (DebuggerToolTipManager::debug())
qDebug() << "GdbEngine::showToolTip " << expression << iname << (*m_toolTipContext); qDebug() << "GdbEngine::showToolTip " << expression << m_toolTipContext->iname << (*m_toolTipContext);
if (!debuggerCore()->boolSetting(UseToolTipsInMainEditor)) { if (m_toolTipContext->iname.startsWith("tooltip")
watchHandler()->removeData(iname); && (!debuggerCore()->boolSetting(UseToolTipsInMainEditor)
|| !watchHandler()->isValidToolTip(m_toolTipContext->iname))) {
watchHandler()->removeData(m_toolTipContext->iname);
return; return;
} }
if (!watchHandler()->isValidToolTip(iname)) {
watchHandler()->removeData(iname);
return;
}
DebuggerToolTipWidget *tw = new DebuggerToolTipWidget; DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
tw->setDebuggerModel(TooltipType); tw->setIname(m_toolTipContext->iname);
tw->setExpression(expression); tw->setExpression(m_toolTipContext->expression);
tw->setContext(*m_toolTipContext); tw->setContext(*m_toolTipContext);
tw->acquireEngine(this); tw->acquireEngine(this);
DebuggerToolTipManager::instance()->showToolTip(m_toolTipContext->mousePosition, DebuggerToolTipManager::instance()->showToolTip(m_toolTipContext->mousePosition,
@@ -3891,12 +3889,22 @@ bool GdbEngine::setToolTipExpression(const QPoint &mousePos,
DebuggerToolTipContext context = contextIn; DebuggerToolTipContext context = contextIn;
int line, column; int line, column;
const QString exp = fixCppExpression(cppExpressionAt(editor, context.position, &line, &column, &context.function)); QString exp = fixCppExpression(cppExpressionAt(editor, context.position, &line, &column, &context.function));
if (DebuggerToolTipManager::debug())
qDebug() << "GdbEngine::setToolTipExpression1 " << exp << context;
if (exp.isEmpty()) if (exp.isEmpty())
return false; return false;
// Prefer a filter on an existing local variable if it can be found.
QByteArray iname;
if (const WatchData *localVariable = watchHandler()->findCppLocalVariable(exp)) {
exp = QLatin1String(localVariable->exp);
iname = localVariable->iname;
} else {
iname = tooltipIName(exp);
}
if (DebuggerToolTipManager::debug())
qDebug() << "GdbEngine::setToolTipExpression1 " << exp << iname << context;
// Same expression: Display synchronously.
if (!m_toolTipContext.isNull() && m_toolTipContext->expression == exp) { if (!m_toolTipContext.isNull() && m_toolTipContext->expression == exp) {
showToolTip(); showToolTip();
return true; return true;
@@ -3905,7 +3913,14 @@ bool GdbEngine::setToolTipExpression(const QPoint &mousePos,
m_toolTipContext.reset(new GdbToolTipContext(context)); m_toolTipContext.reset(new GdbToolTipContext(context));
m_toolTipContext->mousePosition = mousePos; m_toolTipContext->mousePosition = mousePos;
m_toolTipContext->expression = exp; m_toolTipContext->expression = exp;
m_toolTipContext->iname = iname;
m_toolTipContext->editor = editor; m_toolTipContext->editor = editor;
// Local variable: Display synchronously.
if (iname.startsWith("local")) {
showToolTip();
return true;
}
if (DebuggerToolTipManager::debug()) if (DebuggerToolTipManager::debug())
qDebug() << "GdbEngine::setToolTipExpression2 " << exp << (*m_toolTipContext); qDebug() << "GdbEngine::setToolTipExpression2 " << exp << (*m_toolTipContext);
@@ -3913,13 +3928,13 @@ bool GdbEngine::setToolTipExpression(const QPoint &mousePos,
UpdateParameters params; UpdateParameters params;
params.tryPartial = true; params.tryPartial = true;
params.tooltipOnly = true; params.tooltipOnly = true;
params.varList = tooltipIName(exp); params.varList = iname;
updateLocalsPython(params); updateLocalsPython(params);
} else { } else {
WatchData toolTip; WatchData toolTip;
toolTip.exp = exp.toLatin1(); toolTip.exp = exp.toLatin1();
toolTip.name = exp; toolTip.name = exp;
toolTip.iname = tooltipIName(exp); toolTip.iname = iname;
watchHandler()->insertData(toolTip); watchHandler()->insertData(toolTip);
} }
return true; return true;

View File

@@ -64,17 +64,35 @@ void GdbEngine::updateLocalsPython(const UpdateParameters &params)
const QString fileName = stackHandler()->currentFrame().file; const QString fileName = stackHandler()->currentFrame().file;
const QString function = stackHandler()->currentFrame().function; const QString function = stackHandler()->currentFrame().function;
if (!fileName.isEmpty()) { if (!fileName.isEmpty()) {
QStringList expressions = DebuggerToolTipManager::instance() typedef DebuggerToolTipManager::ExpressionInamePair ExpressionInamePair;
typedef DebuggerToolTipManager::ExpressionInamePairs ExpressionInamePairs;
// Re-create tooltip items that are not filters on existing local variables in
// the tooltip model.
ExpressionInamePairs toolTips = DebuggerToolTipManager::instance()
->treeWidgetExpressions(fileName, objectName(), function); ->treeWidgetExpressions(fileName, objectName(), function);
const QString currentExpression = tooltipExpression(); const QString currentExpression = tooltipExpression();
if (!currentExpression.isEmpty() && !expressions.contains(currentExpression)) if (!currentExpression.isEmpty()) {
expressions.push_back(currentExpression); int currentIndex = -1;
foreach (const QString &te, expressions) { for (int i = 0; i < toolTips.size(); ++i) {
if (!watchers.isEmpty()) if (toolTips.at(i).first == currentExpression) {
watchers += "##"; currentIndex = i;
watchers += te.toLatin1(); break;
watchers += '#'; }
watchers += tooltipIName(te); }
if (currentIndex < 0)
toolTips.push_back(ExpressionInamePair(currentExpression, tooltipIName(currentExpression)));
}
foreach (const ExpressionInamePair &p, toolTips) {
if (p.second.startsWith("tooltip")) {
if (!watchers.isEmpty())
watchers += "##";
watchers += p.first.toLatin1();
watchers += '#';
watchers += p.second;
}
} }
} }

View File

@@ -1550,7 +1550,7 @@ QByteArray WatchHandler::watcherName(const QByteArray &exp)
return "watch." + QByteArray::number(theWatcherNames[exp]); return "watch." + QByteArray::number(theWatcherNames[exp]);
} }
void WatchHandler::watchExpression(const QString &exp) void WatchHandler::watchExpression(const QString &exp, const QString &name)
{ {
QTC_ASSERT(m_engine, return); QTC_ASSERT(m_engine, return);
// Do not insert the same entry more then once. // Do not insert the same entry more then once.
@@ -1560,7 +1560,7 @@ void WatchHandler::watchExpression(const QString &exp)
// FIXME: 'exp' can contain illegal characters // FIXME: 'exp' can contain illegal characters
WatchData data; WatchData data;
data.exp = exp.toLatin1(); data.exp = exp.toLatin1();
data.name = exp; data.name = name.isEmpty() ? exp : name;
theWatcherNames[data.exp] = m_watcherCounter++; theWatcherNames[data.exp] = m_watcherCounter++;
saveWatchers(); saveWatchers();
@@ -1794,6 +1794,20 @@ const WatchData *WatchHandler::findData(const QByteArray &iname) const
return m_model->findItem(iname); return m_model->findItem(iname);
} }
const WatchData *WatchHandler::findCppLocalVariable(const QString &name) const
{
// Can this be found as a local variable?
const QByteArray localsPrefix("local.");
QByteArray iname = localsPrefix + name.toLatin1();
if (const WatchData *wd = findData(iname))
return wd;
// Nope, try a 'local.this.m_foo'.
iname.insert(localsPrefix.size(), "this.");
if (const WatchData *wd = findData(iname))
return wd;
return 0;
}
QString WatchHandler::displayForAutoTest(const QByteArray &iname) const QString WatchHandler::displayForAutoTest(const QByteArray &iname) const
{ {
return m_model->displayForAutoTest(iname); return m_model->displayForAutoTest(iname);

View File

@@ -58,15 +58,6 @@ public:
typedef QHash<QString, QStringList> TypeFormats; typedef QHash<QString, QStringList> TypeFormats;
enum WatchType
{
LocalsType,
InspectType,
WatchersType,
ReturnType,
TooltipType
};
enum IntegerFormat enum IntegerFormat
{ {
DecimalFormat = 0, // Keep that at 0 as default. DecimalFormat = 0, // Keep that at 0 as default.
@@ -86,7 +77,7 @@ public:
QAbstractItemModel *model() const; QAbstractItemModel *model() const;
void cleanup(); void cleanup();
void watchExpression(const QString &exp); void watchExpression(const QString &exp, const QString &name = QString());
Q_SLOT void clearWatches(); Q_SLOT void clearWatches();
void updateWatchers(); // Called after locals are fetched void updateWatchers(); // Called after locals are fetched
@@ -95,6 +86,7 @@ public:
const WatchData *watchData(const QModelIndex &) const; const WatchData *watchData(const QModelIndex &) const;
const WatchData *findData(const QByteArray &iname) const; const WatchData *findData(const QByteArray &iname) const;
const WatchData *findCppLocalVariable(const QString &name) const;
QString displayForAutoTest(const QByteArray &iname) const; QString displayForAutoTest(const QByteArray &iname) const;
bool hasItem(const QByteArray &iname) const; bool hasItem(const QByteArray &iname) const;

View File

@@ -920,7 +920,7 @@ void WatchTreeView::contextMenuEvent(QContextMenuEvent *ev)
grabMouse(Qt::CrossCursor); grabMouse(Qt::CrossCursor);
m_grabbing = true; m_grabbing = true;
} else if (act == actWatchExpression) { } else if (act == actWatchExpression) {
watchExpression(exp); watchExpression(exp, name);
} else if (act == actRemoveWatchExpression) { } else if (act == actRemoveWatchExpression) {
handler->removeData(p.data(LocalsINameRole).toByteArray()); handler->removeData(p.data(LocalsINameRole).toByteArray());
} else if (act == actCopy) { } else if (act == actCopy) {
@@ -1036,7 +1036,12 @@ void WatchTreeView::reset()
void WatchTreeView::watchExpression(const QString &exp) void WatchTreeView::watchExpression(const QString &exp)
{ {
currentEngine()->watchHandler()->watchExpression(exp); watchExpression(exp, QString());
}
void WatchTreeView::watchExpression(const QString &exp, const QString &name)
{
currentEngine()->watchHandler()->watchExpression(exp, name);
} }
void WatchTreeView::setModelData void WatchTreeView::setModelData

View File

@@ -56,6 +56,7 @@ public:
public slots: public slots:
void watchExpression(const QString &exp); void watchExpression(const QString &exp);
void watchExpression(const QString &exp, const QString &name);
void handleItemIsExpanded(const QModelIndex &idx); void handleItemIsExpanded(const QModelIndex &idx);
private: private:

View File

@@ -32,6 +32,7 @@
#define QMLPROJECTITEM_H #define QMLPROJECTITEM_H
#include <QObject> #include <QObject>
#include <QSet>
#include <QStringList> #include <QStringList>
#include <qdeclarative.h> #include <qdeclarative.h>

View File

@@ -622,6 +622,11 @@ static QString filterForQmakeFileDialog()
// work around QTBUG-7739 that prohibits filters that don't start with * // work around QTBUG-7739 that prohibits filters that don't start with *
filter += QLatin1Char('*'); filter += QLatin1Char('*');
filter += commands.at(i); filter += commands.at(i);
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
// kde bug, we need at least one wildcard character
// see QTCREATORBUG-7771
filter += QLatin1Char('*');
#endif
} }
filter += QLatin1Char(')'); filter += QLatin1Char(')');
return filter; return filter;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProfiles> <!DOCTYPE QtCreatorProfiles>
<!-- Written by Qt Creator 2.5.81, 2012-07-17T17:54:08. --> <!-- Written by Qt Creator 2.5.81, 2012-08-28T18:44:22. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>Profile.0</variable> <variable>Profile.0</variable>
@@ -20,9 +20,27 @@
<value type="QString" key="PE.Profile.Name">Desktop</value> <value type="QString" key="PE.Profile.Name">Desktop</value>
</valuemap> </valuemap>
</data> </data>
<data>
<variable>Profile.1</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<valuemap type="QVariantMap" key="PE.Profile.Data">
<value type="QString" key="Debugger.Information">/usr/bin/gdb</value>
<value type="QByteArray" key="PE.Profile.Device">Desktop Device</value>
<value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
<value type="QString" key="PE.Profile.SysRoot"></value>
<value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Gcc:{c3f59b87-6997-4bd8-8067-ee04dc536371}</value>
<value type="QString" key="QtPM4.mkSpecInformation"></value>
<value type="int" key="QtSupport.QtInformation">5</value>
</valuemap>
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
<value type="QString" key="PE.Profile.Id">{68d379f6-357c-42a6-83c6-7743840db4ea}</value>
<value type="QString" key="PE.Profile.Name">Qt Simulator</value>
</valuemap>
</data>
<data> <data>
<variable>Profile.Count</variable> <variable>Profile.Count</variable>
<value type="int">1</value> <value type="int">2</value>
</data> </data>
<data> <data>
<variable>Profile.Default</variable> <variable>Profile.Default</variable>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProfiles> <!DOCTYPE QtCreatorProfiles>
<!-- Written by Qt Creator 2.5.81, 2012-07-17T18:31:05. --> <!-- Written by Qt Creator 2.5.81, 2012-08-28T18:13:09. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>Profile.0</variable> <variable>Profile.0</variable>
@@ -20,9 +20,27 @@
<value type="QString" key="PE.Profile.Name">Desktop</value> <value type="QString" key="PE.Profile.Name">Desktop</value>
</valuemap> </valuemap>
</data> </data>
<data>
<variable>Profile.1</variable>
<valuemap type="QVariantMap">
<value type="bool" key="PE.Profile.AutoDetected">false</value>
<valuemap type="QVariantMap" key="PE.Profile.Data">
<value type="QString" key="Debugger.Information">C:/QtSDK/pythongdb/python_2.7based/gdb-i686-pc-mingw32.exe</value>
<value type="QByteArray" key="PE.Profile.Device">Desktop Device</value>
<value type="QByteArray" key="PE.Profile.DeviceType">Desktop</value>
<value type="QString" key="PE.Profile.SysRoot"></value>
<value type="QString" key="PE.Profile.ToolChain">ProjectExplorer.ToolChain.Mingw:{2729dd3e-84f5-42e1-aed1-6a27163346ce}</value>
<value type="QString" key="QtPM4.mkSpecInformation"></value>
<value type="int" key="QtSupport.QtInformation">9</value>
</valuemap>
<value type="QString" key="PE.Profile.Icon">:///DESKTOP///</value>
<value type="QString" key="PE.Profile.Id">{0ce9f69f-0f60-4b04-8691-c328ee5bfe14}</value>
<value type="QString" key="PE.Profile.Name">Qt Simulator</value>
</valuemap>
</data>
<data> <data>
<variable>Profile.Count</variable> <variable>Profile.Count</variable>
<value type="int">1</value> <value type="int">2</value>
</data> </data>
<data> <data>
<variable>Profile.Default</variable> <variable>Profile.Default</variable>