Merge branch 'master' of ../mainline into dui-editor

This commit is contained in:
Roberto Raggi
2009-05-06 12:26:47 +02:00
32 changed files with 643 additions and 191 deletions

View File

@@ -32,7 +32,7 @@
// this relies on contents copied from qobject_p.h // this relies on contents copied from qobject_p.h
#define PRIVATE_OBJECT_ALLOWED 1 #define PRIVATE_OBJECT_ALLOWED 1
#ifdef HAS_QOBJECT_P_H #ifdef HAS_QOBJECT_P_H // Detected by qmake
# include <QtCore/private/qobject_p.h> # include <QtCore/private/qobject_p.h>
#endif #endif
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
@@ -94,10 +94,10 @@ int qtGhVersion = QT_VERSION;
\c{qDumpObjectData440()}. \c{qDumpObjectData440()}.
In any case, dumper processesing should end up in In any case, dumper processesing should end up in
\c{handleProtocolVersion2and3()} and needs an entry in the bis switch there. \c{handleProtocolVersion2and3()} and needs an entry in the big switch there.
Next step is to create a suitable \c{static void qDumpFoo(QDumper &d)} Next step is to create a suitable \c{static void qDumpFoo(QDumper &d)}
function. At the bare minimum it should contain something like: function. At the bare minimum it should contain something like this:
\c{ \c{
@@ -127,7 +127,7 @@ int qtGhVersion = QT_VERSION;
\endlist \endlist
If the current item has children, it might be queried to produce information If the current item has children, it might be queried to produce information
about thes children. In this case the dumper should use something like about these children. In this case the dumper should use something like this:
\c{ \c{
if (d.dumpChildren) { if (d.dumpChildren) {
@@ -149,7 +149,7 @@ int qtGhVersion = QT_VERSION;
# define NSY "" # define NSY ""
#endif #endif
#if PRIVATE_OBJECT_ALLOWED && !HAS_QOBJECT_P_H #if PRIVATE_OBJECT_ALLOWED && !defined(HAS_QOBJECT_P_H)
#if defined(QT_BEGIN_NAMESPACE) #if defined(QT_BEGIN_NAMESPACE)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -221,16 +221,19 @@ Q_DECL_EXPORT char qDumpOutBuffer[100000];
namespace { namespace {
static QByteArray strPtrConst = "* const";
static bool isPointerType(const QByteArray &type) static bool isPointerType(const QByteArray &type)
{ {
return type.endsWith("*") || type.endsWith("* const"); return type.endsWith('*') || type.endsWith(strPtrConst);
} }
static QByteArray stripPointerType(QByteArray type) static QByteArray stripPointerType(const QByteArray &_type)
{ {
if (type.endsWith("*")) QByteArray type = _type;
if (type.endsWith('*'))
type.chop(1); type.chop(1);
if (type.endsWith("* const")) if (type.endsWith(strPtrConst))
type.chop(7); type.chop(7);
if (type.endsWith(' ')) if (type.endsWith(' '))
type.chop(1); type.chop(1);
@@ -279,25 +282,35 @@ static bool isEqual(const char *s, const char *t)
static bool startsWith(const char *s, const char *t) static bool startsWith(const char *s, const char *t)
{ {
return qstrncmp(s, t, qstrlen(t)) == 0; while (char c = *t++)
if (c != *s++)
return false;
return true;
} }
// Check memory for read access and provoke segfault if nothing else helps. // Check memory for read access and provoke segfault if nothing else helps.
// On Windows, try to be less crash-prone by checking memory using WinAPI // On Windows, try to be less crash-prone by checking memory using WinAPI
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
# define qCheckAccess(d) if (IsBadReadPtr(d, 1)) return; do { qProvokeSegFaultHelper = *(char*)d; } while (0) # define qCheckAccess(d) do { if (IsBadReadPtr(d, 1)) return; qProvokeSegFaultHelper = *(char*)d; } while (0)
# define qCheckPointer(d) if (d && IsBadReadPtr(d, 1)) return; do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) # define qCheckPointer(d) do { if (d && IsBadReadPtr(d, 1)) return; if (d) qProvokeSegFaultHelper = *(char*)d; } while (0)
#else #else
# define qCheckAccess(d) do { qProvokeSegFaultHelper = *(char*)d; } while (0) # define qCheckAccess(d) do { qProvokeSegFaultHelper = *(char*)d; } while (0)
# define qCheckPointer(d) do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) # define qCheckPointer(d) do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0)
#endif #endif
#ifdef QT_NAMESPACE
const char *stripNamespace(const char *type) const char *stripNamespace(const char *type)
{ {
static const size_t nslen = qstrlen(NS); static const size_t nslen = strlen(NS);
return startsWith(type, NS) ? type + nslen : type; return startsWith(type, NS) ? type + nslen : type;
} }
#else
inline const char *stripNamespace(const char *type)
{
return type;
}
#endif
static bool isSimpleType(const char *type) static bool isSimpleType(const char *type)
{ {
@@ -1168,7 +1181,7 @@ static void qDumpQHashNode(QDumper &d)
P(d, "numchild", 2); P(d, "numchild", 2);
if (d.dumpChildren) { if (d.dumpChildren) {
// there is a hash specialization in cast the key are integers or shorts // there is a hash specialization in case the keys are integers or shorts
d << ",children=["; d << ",children=[";
d.beginHash(); d.beginHash();
P(d, "name", "key"); P(d, "name", "key");
@@ -2239,7 +2252,14 @@ static void qDumpQWeakPointer(QDumper &d)
static void qDumpStdList(QDumper &d) static void qDumpStdList(QDumper &d)
{ {
const std::list<int> &list = *reinterpret_cast<const std::list<int> *>(d.data); const std::list<int> &list = *reinterpret_cast<const std::list<int> *>(d.data);
const void *p = d.data; #ifdef Q_CC_MSVC
const int size = static_cast<int>(list.size());
if (size < 0)
return;
if (size)
qCheckAccess(list.begin().operator ->());
#else
const void *p = d.data;
qCheckAccess(p); qCheckAccess(p);
p = deref(p); p = deref(p);
qCheckAccess(p); qCheckAccess(p);
@@ -2251,7 +2271,7 @@ static void qDumpStdList(QDumper &d)
qCheckAccess(p); qCheckAccess(p);
p = deref(addOffset(p, sizeof(void*))); p = deref(addOffset(p, sizeof(void*)));
qCheckAccess(p); qCheckAccess(p);
#endif
int nn = 0; int nn = 0;
std::list<int>::const_iterator it = list.begin(); std::list<int>::const_iterator it = list.begin();
for (; nn < 101 && it != list.end(); ++nn, ++it) for (; nn < 101 && it != list.end(); ++nn, ++it)
@@ -2434,7 +2454,7 @@ static void qDumpStdWString(QDumper &d)
} }
static void qDumpStdVector(QDumper &d) static void qDumpStdVector(QDumper &d)
{ {
// Correct type would be something like: // Correct type would be something like:
// std::_Vector_base<int,std::allocator<int, std::allocator<int> >>::_Vector_impl // std::_Vector_base<int,std::allocator<int, std::allocator<int> >>::_Vector_impl
struct VectorImpl { struct VectorImpl {
@@ -2442,8 +2462,13 @@ static void qDumpStdVector(QDumper &d)
char *finish; char *finish;
char *end_of_storage; char *end_of_storage;
}; };
#ifdef Q_CC_MSVC
// Pointers are at end of the structure
const char * vcp = static_cast<const char *>(d.data);
const VectorImpl *v = reinterpret_cast<const VectorImpl *>(vcp + sizeof(std::vector<int>) - sizeof(VectorImpl));
#else
const VectorImpl *v = static_cast<const VectorImpl *>(d.data); const VectorImpl *v = static_cast<const VectorImpl *>(d.data);
#endif
// Try to provoke segfaults early to prevent the frontend // Try to provoke segfaults early to prevent the frontend
// from asking for unavailable child details // from asking for unavailable child details
int nn = (v->finish - v->start) / d.extraInt[0]; int nn = (v->finish - v->start) / d.extraInt[0];
@@ -2679,7 +2704,7 @@ void *qDumpObjectData440(
// This is a list of all available dumpers. Note that some templates // This is a list of all available dumpers. Note that some templates
// currently require special hardcoded handling in the debugger plugin. // currently require special hardcoded handling in the debugger plugin.
// They are mentioned here nevertheless. For types that not listed // They are mentioned here nevertheless. For types that are not listed
// here, dumpers won't be used. // here, dumpers won't be used.
d << "dumpers=[" d << "dumpers=["
"\""NS"QByteArray\"," "\""NS"QByteArray\","

View File

@@ -30,11 +30,11 @@
#include <QtCore/QStringList> #include <QtCore/QStringList>
#include <QtCore/QVector> #include <QtCore/QVector>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <QtCore/private/qobject_p.h>
#include <string> #include <string>
#include <list> #include <list>
#include <vector> #include <vector>
#include <set>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -204,19 +204,36 @@ static int dumpStdStringVector()
return 0; return 0;
} }
static int dumpStdIntSet()
{
std::set<int> test;
test.insert(1);
test.insert(2);
prepareInBuffer("std::set", "local.intset", "local.intset", "int");
qDumpObjectData440(2, 42, &test, 1, sizeof(int), sizeof(std::list<int>::allocator_type), 0, 0);
fputs(qDumpOutBuffer, stdout);
fputc('\n', stdout);
return 0;
}
static int dumpStdStringSet()
{
std::set<std::string> test;
test.insert("item1");
test.insert("item2");
prepareInBuffer("std::set", "local.stringset", "local.stringset", "std::string");
qDumpObjectData440(2, 42, &test, 1, sizeof(std::string), sizeof(std::list<int>::allocator_type), 0, 0);
fputs(qDumpOutBuffer, stdout);
fputc('\n', stdout);
return 0;
}
static int dumpQObject() static int dumpQObject()
{ {
// Requires the childOffset to be know, but that is not critical
QTimer t; QTimer t;
QObjectPrivate *tp = reinterpret_cast<QObjectPrivate *>(&t);
#ifdef KNOWS_OFFSET
const int childOffset = (char*)&tp->children - (char*)tp;
#else
const int childOffset = 0;
#endif
printf("Qt version %s Child offset: %d\n", QT_VERSION_STR, childOffset);
prepareInBuffer("QObject", "local.qobject", "local.qobject", ""); prepareInBuffer("QObject", "local.qobject", "local.qobject", "");
qDumpObjectData440(2, 42, &t, 1, childOffset, 0, 0, 0); qDumpObjectData440(2, 42, &t, 1, 0, 0, 0, 0);
fputs(qDumpOutBuffer, stdout); fputs(qDumpOutBuffer, stdout);
fputc('\n', stdout); fputc('\n', stdout);
return 0; return 0;
@@ -256,6 +273,10 @@ int main(int argc, char *argv[])
dumpStdIntVector(); dumpStdIntVector();
if (!qstrcmp(arg, "vector<string>")) if (!qstrcmp(arg, "vector<string>"))
dumpStdStringVector(); dumpStdStringVector();
if (!qstrcmp(arg, "set<int>"))
dumpStdIntSet();
if (!qstrcmp(arg, "set<string>"))
dumpStdStringSet();
if (!qstrcmp(arg, "QObject")) if (!qstrcmp(arg, "QObject"))
dumpQObject(); dumpQObject();
} }

View File

@@ -9,8 +9,8 @@ defineReplace(prependAll) {
return($$result) return($$result)
} }
LUPDATE = $$targetPath($$[QT_INSTALL_PREFIX]/bin/lupdate) -locations relative -no-ui-lines LUPDATE = $$targetPath($$[QT_INSTALL_BINS]/lupdate) -locations relative -no-ui-lines
LRELEASE = $$targetPath($$[QT_INSTALL_PREFIX]/bin/lrelease) LRELEASE = $$targetPath($$[QT_INSTALL_BINS]/lrelease)
TS_FILES = $$prependAll(TRANSLATIONS, $$PWD/qtcreator_,.ts) TS_FILES = $$prependAll(TRANSLATIONS, $$PWD/qtcreator_,.ts)

View File

@@ -55,6 +55,8 @@ SaveItemsDialog::SaveItemsDialog(QWidget *parent,
m_ui.buttonBox->button(QDialogButtonBox::Save)->setFocus(Qt::TabFocusReason); m_ui.buttonBox->button(QDialogButtonBox::Save)->setFocus(Qt::TabFocusReason);
m_ui.buttonBox->button(QDialogButtonBox::Save)->setMinimumWidth(130); // bad magic number to avoid resizing of button m_ui.buttonBox->button(QDialogButtonBox::Save)->setMinimumWidth(130); // bad magic number to avoid resizing of button
m_ui.saveBeforeBuildCheckBox->setVisible(false);
foreach (IFile *file, items) { foreach (IFile *file, items) {
QString visibleName; QString visibleName;
QString directory; QString directory;
@@ -121,3 +123,14 @@ QList<IFile*> SaveItemsDialog::itemsToSave() const
{ {
return m_itemsToSave; return m_itemsToSave;
} }
void SaveItemsDialog::setAlwaysSaveMessage(const QString &msg)
{
m_ui.saveBeforeBuildCheckBox->setText(msg);
m_ui.saveBeforeBuildCheckBox->setVisible(true);
}
bool SaveItemsDialog::alwaysSaveChecked()
{
return m_ui.saveBeforeBuildCheckBox->isChecked();
}

View File

@@ -57,7 +57,8 @@ public:
QList<Core::IFile *> items); QList<Core::IFile *> items);
void setMessage(const QString &msg); void setMessage(const QString &msg);
void setAlwaysSaveMessage(const QString &msg);
bool alwaysSaveChecked();
QList<Core::IFile *> itemsToSave() const; QList<Core::IFile *> itemsToSave() const;
private slots: private slots:

View File

@@ -56,6 +56,13 @@
</column> </column>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="saveBeforeBuildCheckBox">
<property name="text">
<string>Automatically save all Files before building</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">

View File

@@ -292,9 +292,11 @@ QList<IFile *> FileManager::saveModifiedFilesSilently(const QList<IFile *> &file
Asks the user whether to save the files listed in \a files . Returns the files that have not been saved. Asks the user whether to save the files listed in \a files . Returns the files that have not been saved.
*/ */
QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files, QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files,
bool *cancelled, const QString &message) bool *cancelled, const QString &message,
const QString &alwaysSaveMessage,
bool *alwaysSave)
{ {
return saveModifiedFiles(files, cancelled, false, message); return saveModifiedFiles(files, cancelled, false, message, alwaysSaveMessage, alwaysSave);
} }
static QMessageBox::StandardButton skipFailedPrompt(QWidget *parent, const QString &fileName) static QMessageBox::StandardButton skipFailedPrompt(QWidget *parent, const QString &fileName)
@@ -307,7 +309,11 @@ static QMessageBox::StandardButton skipFailedPrompt(QWidget *parent, const QStri
} }
QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files, QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files,
bool *cancelled, bool silently, const QString &message) bool *cancelled,
bool silently,
const QString &message,
const QString &alwaysSaveMessage,
bool *alwaysSave)
{ {
if (cancelled) if (cancelled)
(*cancelled) = false; (*cancelled) = false;
@@ -338,12 +344,18 @@ QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files,
SaveItemsDialog dia(m_mainWindow, modifiedFiles); SaveItemsDialog dia(m_mainWindow, modifiedFiles);
if (!message.isEmpty()) if (!message.isEmpty())
dia.setMessage(message); dia.setMessage(message);
if (!alwaysSaveMessage.isNull())
dia.setAlwaysSaveMessage(alwaysSaveMessage);
if (dia.exec() != QDialog::Accepted) { if (dia.exec() != QDialog::Accepted) {
if (cancelled) if (cancelled)
(*cancelled) = true; (*cancelled) = true;
if (alwaysSave)
*alwaysSave = dia.alwaysSaveChecked();
notSaved = modifiedFiles; notSaved = modifiedFiles;
return notSaved; return notSaved;
} }
if (alwaysSave)
*alwaysSave = dia.alwaysSaveChecked();
filesToSave = dia.itemsToSave(); filesToSave = dia.itemsToSave();
} }

View File

@@ -97,7 +97,9 @@ public:
QList<IFile *> saveModifiedFilesSilently(const QList<IFile *> &files); QList<IFile *> saveModifiedFilesSilently(const QList<IFile *> &files);
QList<IFile *> saveModifiedFiles(const QList<IFile *> &files, QList<IFile *> saveModifiedFiles(const QList<IFile *> &files,
bool *cancelled = 0, bool *cancelled = 0,
const QString &message = QString()); const QString &message = QString(),
const QString &alwaysSaveMessage = QString::null,
bool *alwaysSave = 0);
signals: signals:
void currentFileChanged(const QString &filePath); void currentFileChanged(const QString &filePath);
@@ -116,7 +118,10 @@ private:
void updateFileInfo(IFile *file); void updateFileInfo(IFile *file);
QList<IFile *> saveModifiedFiles(const QList<IFile *> &files, QList<IFile *> saveModifiedFiles(const QList<IFile *> &files,
bool *cancelled, bool silently, const QString &message); bool *cancelled, bool silently,
const QString &message,
const QString &alwaysSaveMessage = QString::null,
bool *alwaysSave = 0);
QMap<IFile*, FileInfo> m_managedFiles; QMap<IFile*, FileInfo> m_managedFiles;

View File

@@ -1186,14 +1186,6 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
errorMessage); errorMessage);
} }
void CdbDebugEngine::loadSessionData()
{
}
void CdbDebugEngine::saveSessionData()
{
}
void CdbDebugEngine::reloadDisassembler() void CdbDebugEngine::reloadDisassembler()
{ {
enum { ContextLines = 40 }; enum { ContextLines = 40 };

View File

@@ -85,9 +85,6 @@ public:
virtual void attemptBreakpointSynchronization(); virtual void attemptBreakpointSynchronization();
virtual void loadSessionData();
virtual void saveSessionData();
virtual void reloadDisassembler(); virtual void reloadDisassembler();
virtual void reloadModules(); virtual void reloadModules();
@@ -97,6 +94,7 @@ public:
virtual void reloadRegisters(); virtual void reloadRegisters();
virtual void reloadSourceFiles(); virtual void reloadSourceFiles();
virtual void reloadFullStack() {}
protected: protected:
void timerEvent(QTimerEvent*); void timerEvent(QTimerEvent*);

View File

@@ -571,7 +571,7 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool
if (der == DumpExecuteSizeFailed) if (der == DumpExecuteSizeFailed)
m_failedTypes.push_back(wd.type); m_failedTypes.push_back(wd.type);
// log error // log error
*errorMessage = *errorMessage = msgDumpFailed(wd, errorMessage); *errorMessage = msgDumpFailed(wd, errorMessage);
m_access->showDebuggerOutput(m_messagePrefix, *errorMessage); m_access->showDebuggerOutput(m_messagePrefix, *errorMessage);
return DumpError; return DumpError;
} }

View File

@@ -206,6 +206,10 @@ void DebuggerManager::init()
stackView->setModel(m_stackHandler->stackModel()); stackView->setModel(m_stackHandler->stackModel());
connect(stackView, SIGNAL(frameActivated(int)), connect(stackView, SIGNAL(frameActivated(int)),
this, SLOT(activateFrame(int))); this, SLOT(activateFrame(int)));
connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
this, SLOT(reloadFullStack()));
connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
this, SLOT(reloadFullStack()));
// Threads // Threads
m_threadsHandler = new ThreadsHandler; m_threadsHandler = new ThreadsHandler;
@@ -273,9 +277,8 @@ void DebuggerManager::init()
m_registerHandler = new RegisterHandler; m_registerHandler = new RegisterHandler;
registerView->setModel(m_registerHandler->model()); registerView->setModel(m_registerHandler->model());
m_watchHandler = new WatchHandler;
// Locals // Locals
m_watchHandler = new WatchHandler;
QTreeView *localsView = qobject_cast<QTreeView *>(m_localsWindow); QTreeView *localsView = qobject_cast<QTreeView *>(m_localsWindow);
localsView->setModel(m_watchHandler->model()); localsView->setModel(m_watchHandler->model());
@@ -427,7 +430,7 @@ QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(const QStringList
const bool cdbDisabled = arguments.contains(_("-disable-cdb")); const bool cdbDisabled = arguments.contains(_("-disable-cdb"));
winEngine = createWinEngine(this, cdbDisabled, &rc); winEngine = createWinEngine(this, cdbDisabled, &rc);
scriptEngine = createScriptEngine(this, &rc); scriptEngine = createScriptEngine(this, &rc);
setDebuggerType(GdbDebugger); setDebuggerType(NoDebugger);
if (Debugger::Constants::Internal::debug) if (Debugger::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << gdbEngine << winEngine << scriptEngine << rc.size(); qDebug() << Q_FUNC_INFO << gdbEngine << winEngine << scriptEngine << rc.size();
return rc; return rc;
@@ -445,6 +448,8 @@ void DebuggerManager::setDebuggerType(DebuggerType type)
case WinDebugger: case WinDebugger:
m_engine = winEngine; m_engine = winEngine;
break; break;
case NoDebugger:
m_engine = 0;
} }
} }
@@ -697,7 +702,6 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber)
if (Debugger::Constants::Internal::debug) if (Debugger::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << fileName << lineNumber; qDebug() << Q_FUNC_INFO << fileName << lineNumber;
QTC_ASSERT(m_engine, return);
QTC_ASSERT(m_breakHandler, return); QTC_ASSERT(m_breakHandler, return);
if (status() != DebuggerInferiorRunning if (status() != DebuggerInferiorRunning
&& status() != DebuggerInferiorStopped && status() != DebuggerInferiorStopped
@@ -712,7 +716,8 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber)
m_breakHandler->setBreakpoint(fileName, lineNumber); m_breakHandler->setBreakpoint(fileName, lineNumber);
else else
m_breakHandler->removeBreakpoint(index); m_breakHandler->removeBreakpoint(index);
m_engine->attemptBreakpointSynchronization();
attemptBreakpointSynchronization();
} }
void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineNumber) void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineNumber)
@@ -720,7 +725,6 @@ void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineN
if (Debugger::Constants::Internal::debug) if (Debugger::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << fileName << lineNumber; qDebug() << Q_FUNC_INFO << fileName << lineNumber;
QTC_ASSERT(m_engine, return);
QTC_ASSERT(m_breakHandler, return); QTC_ASSERT(m_breakHandler, return);
if (status() != DebuggerInferiorRunning if (status() != DebuggerInferiorRunning
&& status() != DebuggerInferiorStopped && status() != DebuggerInferiorStopped
@@ -731,24 +735,26 @@ void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineN
} }
m_breakHandler->toggleBreakpointEnabled(fileName, lineNumber); m_breakHandler->toggleBreakpointEnabled(fileName, lineNumber);
m_engine->attemptBreakpointSynchronization();
attemptBreakpointSynchronization();
} }
void DebuggerManager::attemptBreakpointSynchronization() void DebuggerManager::attemptBreakpointSynchronization()
{ {
m_engine->attemptBreakpointSynchronization(); if (m_engine)
m_engine->attemptBreakpointSynchronization();
} }
void DebuggerManager::setToolTipExpression(const QPoint &pos, const QString &exp) void DebuggerManager::setToolTipExpression(const QPoint &pos, const QString &exp)
{ {
QTC_ASSERT(m_engine, return); if (m_engine)
m_engine->setToolTipExpression(pos, exp); m_engine->setToolTipExpression(pos, exp);
} }
void DebuggerManager::updateWatchModel() void DebuggerManager::updateWatchModel()
{ {
QTC_ASSERT(m_engine, return); if (m_engine)
m_engine->updateWatchModel(); m_engine->updateWatchModel();
} }
QVariant DebuggerManager::sessionValue(const QString &name) QVariant DebuggerManager::sessionValue(const QString &name)
@@ -946,9 +952,9 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
DebuggerType type; DebuggerType type;
QString errorMessage; QString errorMessage;
const bool hasDebugger = startMode() == AttachExternal ? const bool hasDebugger = startMode() == AttachExternal
determineDebuggerType(m_attachedPID, &type, &errorMessage) : ? determineDebuggerType(m_attachedPID, &type, &errorMessage)
determineDebuggerType(m_executable, &type, &errorMessage); : determineDebuggerType(m_executable, &type, &errorMessage);
if (!hasDebugger) { if (!hasDebugger) {
QMessageBox::warning(mainWindow(), tr("Warning"), QMessageBox::warning(mainWindow(), tr("Warning"),
tr("Cannot debug '%1': %2").arg(m_executable, errorMessage)); tr("Cannot debug '%1': %2").arg(m_executable, errorMessage));
@@ -1117,18 +1123,14 @@ void DebuggerManager::aboutToSaveSession()
void DebuggerManager::loadSessionData() void DebuggerManager::loadSessionData()
{ {
QTC_ASSERT(m_engine, return);
m_breakHandler->loadSessionData(); m_breakHandler->loadSessionData();
m_watchHandler->loadSessionData(); m_watchHandler->loadSessionData();
m_engine->loadSessionData();
} }
void DebuggerManager::saveSessionData() void DebuggerManager::saveSessionData()
{ {
QTC_ASSERT(m_engine, return);
m_breakHandler->saveSessionData(); m_breakHandler->saveSessionData();
m_watchHandler->saveSessionData(); m_watchHandler->saveSessionData();
m_engine->saveSessionData();
} }
void DebuggerManager::dumpLog() void DebuggerManager::dumpLog()
@@ -1164,17 +1166,15 @@ void DebuggerManager::setBreakpoint(const QString &fileName, int lineNumber)
qDebug() << Q_FUNC_INFO << fileName << lineNumber; qDebug() << Q_FUNC_INFO << fileName << lineNumber;
QTC_ASSERT(m_breakHandler, return); QTC_ASSERT(m_breakHandler, return);
QTC_ASSERT(m_engine, return);
m_breakHandler->setBreakpoint(fileName, lineNumber); m_breakHandler->setBreakpoint(fileName, lineNumber);
m_engine->attemptBreakpointSynchronization(); attemptBreakpointSynchronization();
} }
void DebuggerManager::breakByFunction(const QString &functionName) void DebuggerManager::breakByFunction(const QString &functionName)
{ {
QTC_ASSERT(m_breakHandler, return); QTC_ASSERT(m_breakHandler, return);
QTC_ASSERT(m_engine, return);
m_breakHandler->breakByFunction(functionName); m_breakHandler->breakByFunction(functionName);
m_engine->attemptBreakpointSynchronization(); attemptBreakpointSynchronization();
} }
void DebuggerManager::breakByFunction() void DebuggerManager::breakByFunction()
@@ -1300,14 +1300,16 @@ void DebuggerManager::queryCurrentTextEditor(QString *fileName, int *lineNumber,
void DebuggerManager::continueExec() void DebuggerManager::continueExec()
{ {
m_engine->continueInferior(); if (m_engine)
m_engine->continueInferior();
} }
void DebuggerManager::interruptDebuggingRequest() void DebuggerManager::interruptDebuggingRequest()
{ {
if (Debugger::Constants::Internal::debug) if (Debugger::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << status(); qDebug() << Q_FUNC_INFO << status();
QTC_ASSERT(m_engine, return); if (!m_engine)
return;
bool interruptIsExit = (status() != DebuggerInferiorRunning); bool interruptIsExit = (status() != DebuggerInferiorRunning);
if (interruptIsExit) if (interruptIsExit)
exitDebugger(); exitDebugger();
@@ -1319,11 +1321,10 @@ void DebuggerManager::interruptDebuggingRequest()
void DebuggerManager::runToLineExec() void DebuggerManager::runToLineExec()
{ {
QTC_ASSERT(m_engine, return);
QString fileName; QString fileName;
int lineNumber = -1; int lineNumber = -1;
emit currentTextEditorRequested(&fileName, &lineNumber, 0); emit currentTextEditorRequested(&fileName, &lineNumber, 0);
if (!fileName.isEmpty()) { if (m_engine && !fileName.isEmpty()) {
if (Debugger::Constants::Internal::debug) if (Debugger::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << fileName << lineNumber; qDebug() << Q_FUNC_INFO << fileName << lineNumber;
m_engine->runToLineExec(fileName, lineNumber); m_engine->runToLineExec(fileName, lineNumber);
@@ -1360,7 +1361,7 @@ void DebuggerManager::runToFunctionExec()
if (Debugger::Constants::Internal::debug) if (Debugger::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << functionName; qDebug() << Q_FUNC_INFO << functionName;
if (!functionName.isEmpty()) if (m_engine && !functionName.isEmpty())
m_engine->runToFunctionExec(functionName); m_engine->runToFunctionExec(functionName);
} }
@@ -1369,7 +1370,7 @@ void DebuggerManager::jumpToLineExec()
QString fileName; QString fileName;
int lineNumber = -1; int lineNumber = -1;
emit currentTextEditorRequested(&fileName, &lineNumber, 0); emit currentTextEditorRequested(&fileName, &lineNumber, 0);
if (!fileName.isEmpty()) { if (m_engine && !fileName.isEmpty()) {
if (Debugger::Constants::Internal::debug) if (Debugger::Constants::Internal::debug)
qDebug() << Q_FUNC_INFO << fileName << lineNumber; qDebug() << Q_FUNC_INFO << fileName << lineNumber;
m_engine->jumpToLineExec(fileName, lineNumber); m_engine->jumpToLineExec(fileName, lineNumber);
@@ -1404,10 +1405,8 @@ void DebuggerManager::fileOpen(const QString &fileName)
void DebuggerManager::reloadDisassembler() void DebuggerManager::reloadDisassembler()
{ {
QTC_ASSERT(m_engine, return); if (m_engine && m_disassemblerDock && m_disassemblerDock->isVisible())
if (!m_disassemblerDock || !m_disassemblerDock->isVisible()) m_engine->reloadDisassembler();
return;
m_engine->reloadDisassembler();
} }
void DebuggerManager::disassemblerDockToggled(bool on) void DebuggerManager::disassemblerDockToggled(bool on)
@@ -1425,9 +1424,8 @@ void DebuggerManager::disassemblerDockToggled(bool on)
void DebuggerManager::reloadSourceFiles() void DebuggerManager::reloadSourceFiles()
{ {
if (!m_sourceFilesDock || !m_sourceFilesDock->isVisible()) if (m_engine && m_sourceFilesDock && m_sourceFilesDock->isVisible())
return; m_engine->reloadSourceFiles();
m_engine->reloadSourceFiles();
} }
void DebuggerManager::sourceFilesDockToggled(bool on) void DebuggerManager::sourceFilesDockToggled(bool on)
@@ -1445,9 +1443,8 @@ void DebuggerManager::sourceFilesDockToggled(bool on)
void DebuggerManager::reloadModules() void DebuggerManager::reloadModules()
{ {
if (!m_modulesDock || !m_modulesDock->isVisible()) if (m_engine && m_modulesDock && m_modulesDock->isVisible())
return; m_engine->reloadModules();
m_engine->reloadModules();
} }
void DebuggerManager::modulesDockToggled(bool on) void DebuggerManager::modulesDockToggled(bool on)
@@ -1490,9 +1487,8 @@ void DebuggerManager::registerDockToggled(bool on)
void DebuggerManager::reloadRegisters() void DebuggerManager::reloadRegisters()
{ {
if (!m_registerDock || !m_registerDock->isVisible()) if (m_engine && m_registerDock && m_registerDock->isVisible())
return; m_engine->reloadRegisters();
m_engine->reloadRegisters();
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
@@ -1546,6 +1542,12 @@ DebuggerStartMode DebuggerManager::startMode() const
return m_runControl->startMode(); return m_runControl->startMode();
} }
void DebuggerManager::reloadFullStack()
{
if (m_engine)
m_engine->reloadFullStack();
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// //

View File

@@ -202,7 +202,7 @@ public:
QMainWindow *mainWindow() const { return m_mainWindow; } QMainWindow *mainWindow() const { return m_mainWindow; }
QLabel *statusLabel() const { return m_statusLabel; } QLabel *statusLabel() const { return m_statusLabel; }
enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger }; enum DebuggerType { NoDebugger, GdbDebugger, ScriptDebugger, WinDebugger };
public slots: public slots:
void startNewDebugger(DebuggerRunControl *runControl); void startNewDebugger(DebuggerRunControl *runControl);
@@ -279,6 +279,7 @@ private slots:
void setStatus(int status); void setStatus(int status);
void clearStatusMessage(); void clearStatusMessage();
void attemptBreakpointSynchronization(); void attemptBreakpointSynchronization();
void reloadFullStack();
private: private:
// //

View File

@@ -368,6 +368,7 @@ QWidget *DebuggingHelperOptionPage::createPage(QWidget *parent)
mdebug->addAction(cmd); mdebug->addAction(cmd);
#endif #endif
#endif #endif
updateState();
return w; return w;
} }
@@ -376,9 +377,10 @@ void DebuggingHelperOptionPage::updateState()
{ {
m_ui.checkBoxUseCustomDebuggingHelperLocation->setEnabled( m_ui.checkBoxUseCustomDebuggingHelperLocation->setEnabled(
m_ui.checkBoxUseDebuggingHelpers->isChecked()); m_ui.checkBoxUseDebuggingHelpers->isChecked());
m_ui.dumperLocationChooser->setEnabled( bool locationEnabled = m_ui.checkBoxUseDebuggingHelpers->isChecked()
m_ui.checkBoxUseDebuggingHelpers->isChecked() && m_ui.checkBoxUseCustomDebuggingHelperLocation->isChecked();
&& m_ui.checkBoxUseCustomDebuggingHelperLocation->isChecked()); m_ui.dumperLocationChooser->setEnabled(locationEnabled);
m_ui.dumperLocationLabel->setEnabled(locationEnabled);
} }
} // namespace Internal } // namespace Internal

View File

@@ -73,7 +73,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QLabel" name="labelDebuggingHelperLocation"> <widget class="QLabel" name="dumperLocationLabel">
<property name="text"> <property name="text">
<string>Location: </string> <string>Location: </string>
</property> </property>

View File

@@ -158,17 +158,13 @@ void GdbEngine::initializeConnections()
q, SLOT(showApplicationOutput(QString)), q, SLOT(showApplicationOutput(QString)),
Qt::QueuedConnection); Qt::QueuedConnection);
// FIXME: These trigger even if the engine is not active
connect(theDebuggerAction(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)), connect(theDebuggerAction(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
this, SLOT(setUseDebuggingHelpers(QVariant))); this, SLOT(setUseDebuggingHelpers(QVariant)));
connect(theDebuggerAction(DebugDebuggingHelpers), SIGNAL(valueChanged(QVariant)), connect(theDebuggerAction(DebugDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
this, SLOT(setDebugDebuggingHelpers(QVariant))); this, SLOT(setDebugDebuggingHelpers(QVariant)));
connect(theDebuggerAction(RecheckDebuggingHelpers), SIGNAL(triggered()), connect(theDebuggerAction(RecheckDebuggingHelpers), SIGNAL(triggered()),
this, SLOT(recheckDebuggingHelperAvailability())); this, SLOT(recheckDebuggingHelperAvailability()));
connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()),
this, SLOT(reloadFullStack()));
connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()),
this, SLOT(reloadFullStack()));
} }
void GdbEngine::initializeVariables() void GdbEngine::initializeVariables()
@@ -532,12 +528,18 @@ void GdbEngine::readGdbStandardOutput()
void GdbEngine::interruptInferior() void GdbEngine::interruptInferior()
{ {
qq->notifyInferiorStopRequested(); qq->notifyInferiorStopRequested();
if (m_gdbProc.state() == QProcess::NotRunning) { if (m_gdbProc.state() == QProcess::NotRunning) {
debugMessage(_("TRYING TO INTERRUPT INFERIOR WITHOUT RUNNING GDB")); debugMessage(_("TRYING TO INTERRUPT INFERIOR WITHOUT RUNNING GDB"));
qq->notifyInferiorExited(); qq->notifyInferiorExited();
return; return;
} }
if (q->startMode() == AttachRemote) {
execCommand(_("-exec-interrupt"));
return;
}
if (q->m_attachedPID <= 0) { if (q->m_attachedPID <= 0) {
debugMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED")); debugMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"));
return; return;
@@ -1021,8 +1023,6 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
return; return;
} }
//tryLoadDebuggingHelpers();
// jump over well-known frames // jump over well-known frames
static int stepCounter = 0; static int stepCounter = 0;
if (theDebuggerBoolSetting(SkipKnownFrames)) { if (theDebuggerBoolSetting(SkipKnownFrames)) {
@@ -1420,6 +1420,7 @@ bool GdbEngine::startDebugger()
//execCommand(_("set print pretty on")); //execCommand(_("set print pretty on"));
//execCommand(_("set confirm off")); //execCommand(_("set confirm off"));
//execCommand(_("set pagination off")); //execCommand(_("set pagination off"));
execCommand(_("set print inferior-events 1"));
execCommand(_("set breakpoint pending on")); execCommand(_("set breakpoint pending on"));
execCommand(_("set print elements 10000")); execCommand(_("set print elements 10000"));
execCommand(_("-data-list-register-names"), CB(handleRegisterListNames)); execCommand(_("-data-list-register-names"), CB(handleRegisterListNames));
@@ -1602,8 +1603,10 @@ void GdbEngine::handleTargetAsync(const GdbResultRecord &record, const QVariant
if (record.resultClass == GdbResultDone) { if (record.resultClass == GdbResultDone) {
//execCommand(_("info target"), handleStart); //execCommand(_("info target"), handleStart);
qq->notifyInferiorRunningRequested(); qq->notifyInferiorRunningRequested();
execCommand(_("target remote %1").arg(q->m_remoteChannel)); execCommand(_("target remote %1").arg(q->m_remoteChannel),
execCommand(_("-exec-continue"), CB(handleExecRun)); CB(handleAttach));
//execCommand(_("-exec-continue"), CB(handleExecRun));
handleAqcuiredInferior();
} else if (record.resultClass == GdbResultError) { } else if (record.resultClass == GdbResultError) {
// a typical response on "old" gdb is: // a typical response on "old" gdb is:
// &"set target-async on\n" // &"set target-async on\n"
@@ -1824,9 +1827,9 @@ void GdbEngine::sendInsertBreakpoint(int index)
//if (where.isEmpty()) //if (where.isEmpty())
// where = data->fileName; // where = data->fileName;
#endif #endif
// we need something like "\"file name.cpp\":100" to // The argument is simply a C-quoted version of the argument to the
// survive the gdb command line parser with file names intact // non-MI "break" command, including the "original" quoting it wants.
where = _("\"\\\"") + where + _("\\\":") + data->lineNumber + _c('"'); where = _("\"\\\"") + GdbMi::escapeCString(where) + _("\\\":") + data->lineNumber + _c('"');
} else { } else {
where = data->funcName; where = data->funcName;
} }
@@ -1987,6 +1990,8 @@ void GdbEngine::handleBreakInsert(const GdbResultRecord &record, const QVariant
handler->updateMarkers(); handler->updateMarkers();
} else if (record.resultClass == GdbResultError) { } else if (record.resultClass == GdbResultError) {
const BreakpointData *data = handler->at(index); const BreakpointData *data = handler->at(index);
// Note that it is perfectly correct that the file name is put
// in quotes but not escaped. GDB simply is like that.
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
//QString where = "\"\\\"" + data->fileName + "\\\":" //QString where = "\"\\\"" + data->fileName + "\\\":"
// + data->lineNumber + "\""; // + data->lineNumber + "\"";
@@ -3098,8 +3103,7 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const
QByteArray out = output.data(); QByteArray out = output.data();
out = out.mid(out.indexOf('"') + 2); // + 1 is success marker out = out.mid(out.indexOf('"') + 2); // + 1 is success marker
out = out.left(out.lastIndexOf('"')); out = out.left(out.lastIndexOf('"'));
//out.replace('\'', '"'); out.replace('\\', ""); // optimization: dumper output never needs real C unquoting
out.replace("\\", "");
out = "dummy={" + out + "}"; out = "dummy={" + out + "}";
//qDebug() << "OUTPUT: " << out; //qDebug() << "OUTPUT: " << out;
@@ -3302,7 +3306,7 @@ void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record,
QByteArray out = output.data(); QByteArray out = output.data();
int markerPos = out.indexOf('"') + 1; // position of 'success marker' int markerPos = out.indexOf('"') + 1; // position of 'success marker'
if (markerPos == -1 || out.at(markerPos) == 'f') { // 't' or 'f' if (markerPos == 0 || out.at(markerPos) == 'f') { // 't' or 'f'
// custom dumper produced no output // custom dumper produced no output
data.setError(strNotInScope); data.setError(strNotInScope);
insertData(data); insertData(data);
@@ -3311,7 +3315,7 @@ void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record,
out = out.mid(markerPos + 1); out = out.mid(markerPos + 1);
out = out.left(out.lastIndexOf('"')); out = out.left(out.lastIndexOf('"'));
out.replace("\\", ""); out.replace('\\', ""); // optimization: dumper output never needs real C unquoting
out = "dummy={" + out + "}"; out = "dummy={" + out + "}";
GdbMi contents; GdbMi contents;
@@ -3848,13 +3852,13 @@ void GdbEngine::tryLoadDebuggingHelpers()
execCommand(_("sharedlibrary .*")); // for LoadLibraryA execCommand(_("sharedlibrary .*")); // for LoadLibraryA
//execCommand(_("handle SIGSEGV pass stop print")); //execCommand(_("handle SIGSEGV pass stop print"));
//execCommand(_("set unwindonsignal off")); //execCommand(_("set unwindonsignal off"));
execCommand(_("call LoadLibraryA(\"") + lib + _("\")"), execCommand(_("call LoadLibraryA(\"") + GdbMi::escapeCString(lib) + _("\")"),
CB(handleDebuggingHelperSetup)); CB(handleDebuggingHelperSetup));
execCommand(_("sharedlibrary ") + dotEscape(lib)); execCommand(_("sharedlibrary ") + dotEscape(lib));
#elif defined(Q_OS_MAC) #elif defined(Q_OS_MAC)
//execCommand(_("sharedlibrary libc")); // for malloc //execCommand(_("sharedlibrary libc")); // for malloc
//execCommand(_("sharedlibrary libdl")); // for dlopen //execCommand(_("sharedlibrary libdl")); // for dlopen
execCommand(_("call (void)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), execCommand(_("call (void)dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
CB(handleDebuggingHelperSetup)); CB(handleDebuggingHelperSetup));
//execCommand(_("sharedlibrary ") + dotEscape(lib)); //execCommand(_("sharedlibrary ") + dotEscape(lib));
m_debuggingHelperState = DebuggingHelperLoadTried; m_debuggingHelperState = DebuggingHelperLoadTried;
@@ -3863,10 +3867,10 @@ void GdbEngine::tryLoadDebuggingHelpers()
QString flag = QString::number(RTLD_NOW); QString flag = QString::number(RTLD_NOW);
execCommand(_("sharedlibrary libc")); // for malloc execCommand(_("sharedlibrary libc")); // for malloc
execCommand(_("sharedlibrary libdl")); // for dlopen execCommand(_("sharedlibrary libdl")); // for dlopen
execCommand(_("call (void*)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), execCommand(_("call (void*)dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
CB(handleDebuggingHelperSetup)); CB(handleDebuggingHelperSetup));
// some older systems like CentOS 4.6 prefer this: // some older systems like CentOS 4.6 prefer this:
execCommand(_("call (void*)__dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"), execCommand(_("call (void*)__dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
CB(handleDebuggingHelperSetup)); CB(handleDebuggingHelperSetup));
execCommand(_("sharedlibrary ") + dotEscape(lib)); execCommand(_("sharedlibrary ") + dotEscape(lib));
#endif #endif

View File

@@ -112,9 +112,6 @@ private:
Q_SLOT void attemptBreakpointSynchronization(); Q_SLOT void attemptBreakpointSynchronization();
void loadSessionData() {}
void saveSessionData() {}
void assignValueInDebugger(const QString &expr, const QString &value); void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand(const QString & command); void executeDebuggerCommand(const QString & command);

View File

@@ -34,6 +34,8 @@
#include <QtCore/QByteArray> #include <QtCore/QByteArray>
#include <QtCore/QTextStream> #include <QtCore/QTextStream>
#include <ctype.h>
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -44,7 +46,7 @@ QTextStream &operator<<(QTextStream &os, const GdbMi &mi)
void GdbMi::parseResultOrValue(const char *&from, const char *to) void GdbMi::parseResultOrValue(const char *&from, const char *to)
{ {
while (from != to && QChar(*from).isSpace()) while (from != to && isspace(*from))
++from; ++from;
//qDebug() << "parseResultOrValue: " << QByteArray(from, to - from); //qDebug() << "parseResultOrValue: " << QByteArray(from, to - from);
@@ -74,6 +76,7 @@ QByteArray GdbMi::parseCString(const char *&from, const char *to)
//qDebug() << "parseCString: " << QByteArray::fromUtf16(from, to - from); //qDebug() << "parseCString: " << QByteArray::fromUtf16(from, to - from);
if (*from != '"') { if (*from != '"') {
qDebug() << "MI Parse Error, double quote expected"; qDebug() << "MI Parse Error, double quote expected";
++from; // So we don't hang
return QByteArray(); return QByteArray();
} }
const char *ptr = from; const char *ptr = from;
@@ -84,22 +87,66 @@ QByteArray GdbMi::parseCString(const char *&from, const char *to)
result = QByteArray(from + 1, ptr - from - 2); result = QByteArray(from + 1, ptr - from - 2);
break; break;
} }
if (*ptr == '\\' && ptr < to - 1) if (*ptr == '\\') {
++ptr; ++ptr;
if (ptr == to) {
qDebug() << "MI Parse Error, unterminated backslash escape";
from = ptr; // So we don't hang
return QByteArray();
}
}
++ptr; ++ptr;
} }
from = ptr;
if (result.contains('\\')) { int idx = result.indexOf('\\');
if (result.contains("\\032\\032")) if (idx >= 0) {
result.clear(); char *dst = result.data() + idx;
else { const char *src = dst + 1, *end = result.data() + result.length();
result = result.replace("\\n", "\n"); do {
result = result.replace("\\t", "\t"); char c = *src++;
result = result.replace("\\\"", "\""); switch (c) {
} case 'a': *dst++ = '\a'; break;
case 'b': *dst++ = '\b'; break;
case 'f': *dst++ = '\f'; break;
case 'n': *dst++ = '\n'; break;
case 'r': *dst++ = '\r'; break;
case 't': *dst++ = '\t'; break;
case 'v': *dst++ = '\v'; break;
case '"': *dst++ = '"'; break;
case '\\': *dst++ = '\\'; break;
default:
{
int chars = 0;
uchar prod = 0;
forever {
if (c < '0' || c > '7') {
--src;
break;
}
prod = prod * 8 + c - '0';
if (++chars == 3 || src == end)
break;
c = *src++;
}
if (!chars) {
qDebug() << "MI Parse Error, unrecognized backslash escape";
return QByteArray();
}
*dst++ = prod;
}
}
while (src != end) {
char c = *src++;
if (c == '\\')
break;
*dst++ = c;
}
} while (src != end);
*dst = 0;
result.truncate(dst - result.data());
} }
from = ptr;
return result; return result;
} }
@@ -203,10 +250,50 @@ void GdbMi::dumpChildren(QByteArray * str, bool multiline, int indent) const
} }
} }
static QByteArray escaped(QByteArray ba) class MyString : public QString {
public:
ushort at(int i) const { return constData()[i].unicode(); }
};
template<class ST, typename CT>
inline ST escapeCStringTpl(const ST &ba)
{ {
ba.replace("\"", "\\\""); ST ret;
return ba; ret.reserve(ba.length() * 2);
for (int i = 0; i < ba.length(); ++i) {
CT c = ba.at(i);
switch (c) {
case '\\': ret += "\\\\"; break;
case '\a': ret += "\\a"; break;
case '\b': ret += "\\b"; break;
case '\f': ret += "\\f"; break;
case '\n': ret += "\\n"; break;
case '\r': ret += "\\r"; break;
case '\t': ret += "\\t"; break;
case '\v': ret += "\\v"; break;
case '"': ret += "\\\""; break;
default:
if (c < 32 || c == 127) {
ret += '\\';
ret += '0' + (c >> 6);
ret += '0' + ((c >> 3) & 7);
ret += '0' + (c & 7);
} else {
ret += c;
}
}
}
return ret;
}
QString GdbMi::escapeCString(const QString &ba)
{
return escapeCStringTpl<MyString, ushort>(static_cast<const MyString &>(ba));
}
QByteArray GdbMi::escapeCString(const QByteArray &ba)
{
return escapeCStringTpl<QByteArray, uchar>(ba);
} }
QByteArray GdbMi::toString(bool multiline, int indent) const QByteArray GdbMi::toString(bool multiline, int indent) const
@@ -222,7 +309,7 @@ QByteArray GdbMi::toString(bool multiline, int indent) const
case Const: case Const:
if (!m_name.isEmpty()) if (!m_name.isEmpty())
result += m_name + "="; result += m_name + "=";
result += "\"" + escaped(m_data) + "\""; result += "\"" + escapeCString(m_data) + "\"";
break; break;
case Tuple: case Tuple:
if (!m_name.isEmpty()) if (!m_name.isEmpty())

View File

@@ -132,6 +132,8 @@ private:
friend class GdbEngine; friend class GdbEngine;
static QByteArray parseCString(const char *&from, const char *to); static QByteArray parseCString(const char *&from, const char *to);
static QByteArray escapeCString(const QByteArray &ba);
static QString escapeCString(const QString &ba);
void parseResultOrValue(const char *&from, const char *to); void parseResultOrValue(const char *&from, const char *to);
void parseValue(const char *&from, const char *to); void parseValue(const char *&from, const char *to);
void parseTuple(const char *&from, const char *to); void parseTuple(const char *&from, const char *to);

View File

@@ -74,9 +74,6 @@ public:
virtual void attemptBreakpointSynchronization() = 0; virtual void attemptBreakpointSynchronization() = 0;
virtual void loadSessionData() = 0;
virtual void saveSessionData() = 0;
virtual void reloadDisassembler() = 0; virtual void reloadDisassembler() = 0;
virtual void reloadModules() = 0; virtual void reloadModules() = 0;
@@ -87,6 +84,7 @@ public:
virtual void reloadRegisters() = 0; virtual void reloadRegisters() = 0;
virtual void reloadSourceFiles() = 0; virtual void reloadSourceFiles() = 0;
virtual void reloadFullStack() = 0;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -94,9 +94,6 @@ private:
void attemptBreakpointSynchronization(); void attemptBreakpointSynchronization();
void loadSessionData() {}
void saveSessionData() {}
void assignValueInDebugger(const QString &expr, const QString &value); void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand(const QString & command); void executeDebuggerCommand(const QString & command);
@@ -107,6 +104,7 @@ private:
void reloadModules(); void reloadModules();
void reloadRegisters() {} void reloadRegisters() {}
void reloadSourceFiles() {} void reloadSourceFiles() {}
void reloadFullStack() {}
bool supportsThreads() const { return true; } bool supportsThreads() const { return true; }
void maybeBreakNow(bool byFunction); void maybeBreakNow(bool byFunction);

View File

@@ -136,6 +136,7 @@ bool hasSideEffects(const QString &exp)
return exp.contains(QLatin1String("-=")) return exp.contains(QLatin1String("-="))
|| exp.contains(QLatin1String("+=")) || exp.contains(QLatin1String("+="))
|| exp.contains(QLatin1String("/=")) || exp.contains(QLatin1String("/="))
|| exp.contains(QLatin1String("%="))
|| exp.contains(QLatin1String("*=")) || exp.contains(QLatin1String("*="))
|| exp.contains(QLatin1String("&=")) || exp.contains(QLatin1String("&="))
|| exp.contains(QLatin1String("|=")) || exp.contains(QLatin1String("|="))
@@ -454,7 +455,7 @@ QDebug operator<<(QDebug in, const QtDumperResult &d)
const QtDumperResult::Child &c = d.children.at(i); const QtDumperResult::Child &c = d.children.at(i);
nospace << " #" << i << " addr=" << c.address nospace << " #" << i << " addr=" << c.address
<< " disabled=" << c.valuedisabled << " disabled=" << c.valuedisabled
<< " type=" << c.type << " type=" << c.type << " exp=" << c.exp
<< " name=" << c.name << " encoded=" << c.valueEncoded << " name=" << c.name << " encoded=" << c.valueEncoded
<< " value=" << c.value << " value=" << c.value
<< "childcount=" << c.childCount << '\n'; << "childcount=" << c.childCount << '\n';
@@ -1376,6 +1377,8 @@ bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r)
// Sanity // Sanity
if (r->childCount < r->children.size()) if (r->childCount < r->children.size())
r->childCount = r->children.size(); r->childCount = r->children.size();
if (debug)
qDebug() << '\n' << data << *r;
return true; return true;
} }

View File

@@ -506,17 +506,17 @@ void Project::setDisplayNameFor(const QString &buildConfiguration, const QString
emit buildConfigurationDisplayNameChanged(buildConfiguration); emit buildConfigurationDisplayNameChanged(buildConfiguration);
} }
QByteArray Project::predefinedMacros(const QString &fileName) const QByteArray Project::predefinedMacros(const QString &) const
{ {
return QByteArray(); return QByteArray();
} }
QStringList Project::includePaths(const QString &fileName) const QStringList Project::includePaths(const QString &) const
{ {
return QStringList(); return QStringList();
} }
QStringList Project::frameworkPaths(const QString &fileName) const QStringList Project::frameworkPaths(const QString &) const
{ {
return QStringList(); return QStringList();
} }

View File

@@ -56,6 +56,7 @@
#include "session.h" #include "session.h"
#include "sessiondialog.h" #include "sessiondialog.h"
#include "buildparserfactory.h" #include "buildparserfactory.h"
#include "projectexplorersettingspage.h"
#include <coreplugin/basemode.h> #include <coreplugin/basemode.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
@@ -233,6 +234,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
addAutoReleasedObject(new GccParserFactory); addAutoReleasedObject(new GccParserFactory);
addAutoReleasedObject(new MsvcParserFactory); addAutoReleasedObject(new MsvcParserFactory);
// Settings page
addAutoReleasedObject(new ProjectExplorerSettingsPage);
// context menus // context menus
Core::ActionContainer *msessionContextMenu = Core::ActionContainer *msessionContextMenu =
am->createMenu(Constants::M_SESSIONCONTEXT); am->createMenu(Constants::M_SESSIONCONTEXT);
@@ -619,7 +623,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
} }
// < -- Creator 1.0 compatibility code // < -- Creator 1.0 compatibility code
// TODO restore recentProjects
if (QSettings *s = core->settings()) { if (QSettings *s = core->settings()) {
const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList(); const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").toStringList();
const QStringList displayNames = s->value("ProjectExplorer/RecentProjects/DisplayNames").toStringList(); const QStringList displayNames = s->value("ProjectExplorer/RecentProjects/DisplayNames").toStringList();
@@ -631,7 +634,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
} }
} }
if (QSettings *s = core->settings()) {
m_projectExplorerSettings.buildBeforeRun = s->value("ProjectExplorer/Settings/BuildBeforeRun", true).toBool();
m_projectExplorerSettings.saveBeforeBuild = s->value("ProjectExplorer/Settings/SaveBeforeBuild", false).toBool();
}
connect(m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager())); connect(m_sessionManagerAction, SIGNAL(triggered()), this, SLOT(showSessionManager()));
connect(m_newAction, SIGNAL(triggered()), this, SLOT(newProject())); connect(m_newAction, SIGNAL(triggered()), this, SLOT(newProject()));
@@ -856,6 +862,9 @@ void ProjectExplorerPlugin::savePersistentSettings()
s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames); s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames);
s->setValue("ProjectExplorer/RecentProjects/DisplayNames", displayNames); s->setValue("ProjectExplorer/RecentProjects/DisplayNames", displayNames);
s->setValue("ProjectExplorer/Settings/BuildBeforeRun", m_projectExplorerSettings.buildBeforeRun);
s->setValue("ProjectExplorer/Settings/SaveBeforeBuild", m_projectExplorerSettings.saveBeforeBuild);
} }
} }
@@ -1110,6 +1119,36 @@ void ProjectExplorerPlugin::buildStateChanged(Project * pro)
updateActions(); updateActions();
} }
void ProjectExplorerPlugin::executeRunConfiguration(QSharedPointer<RunConfiguration> runConfiguration, const QString &runMode)
{
IRunConfigurationRunner *runner = findRunner(runConfiguration, runMode);
if (runner) {
emit aboutToExecuteProject(runConfiguration->project());
RunControl *control = runner->run(runConfiguration, runMode);
m_outputPane->createNewOutputWindow(control);
if (runMode == ProjectExplorer::Constants::RUNMODE)
m_outputPane->popup(false);
m_outputPane->showTabFor(control);
connect(control, SIGNAL(addToOutputWindow(RunControl *, const QString &)),
this, SLOT(addToApplicationOutputWindow(RunControl *, const QString &)));
connect(control, SIGNAL(addToOutputWindowInline(RunControl *, const QString &)),
this, SLOT(addToApplicationOutputWindowInline(RunControl *, const QString &)));
connect(control, SIGNAL(error(RunControl *, const QString &)),
this, SLOT(addErrorToApplicationOutputWindow(RunControl *, const QString &)));
connect(control, SIGNAL(finished()),
this, SLOT(runControlFinished()));
if (runMode == ProjectExplorer::Constants::DEBUGMODE)
m_debuggingRunControl = control;
control->start();
updateRunAction();
}
}
void ProjectExplorerPlugin::buildQueueFinished(bool success) void ProjectExplorerPlugin::buildQueueFinished(bool success)
{ {
if (debug) if (debug)
@@ -1118,38 +1157,13 @@ void ProjectExplorerPlugin::buildQueueFinished(bool success)
updateActions(); updateActions();
if (success && m_delayedRunConfiguration) { if (success && m_delayedRunConfiguration) {
IRunConfigurationRunner *runner = findRunner(m_delayedRunConfiguration, m_runMode); executeRunConfiguration(m_delayedRunConfiguration, m_runMode);
if (runner) { m_delayedRunConfiguration = QSharedPointer<RunConfiguration>(0);
emit aboutToExecuteProject(m_delayedRunConfiguration->project()); m_runMode = QString::null;
RunControl *control = runner->run(m_delayedRunConfiguration, m_runMode);
m_outputPane->createNewOutputWindow(control);
if (m_runMode == ProjectExplorer::Constants::RUNMODE)
m_outputPane->popup(false);
m_outputPane->showTabFor(control);
connect(control, SIGNAL(addToOutputWindow(RunControl *, const QString &)),
this, SLOT(addToApplicationOutputWindow(RunControl *, const QString &)));
connect(control, SIGNAL(addToOutputWindowInline(RunControl *, const QString &)),
this, SLOT(addToApplicationOutputWindowInline(RunControl *, const QString &)));
connect(control, SIGNAL(error(RunControl *, const QString &)),
this, SLOT(addErrorToApplicationOutputWindow(RunControl *, const QString &)));
connect(control, SIGNAL(finished()),
this, SLOT(runControlFinished()));
if (m_runMode == ProjectExplorer::Constants::DEBUGMODE)
m_debuggingRunControl = control;
control->start();
updateRunAction();
}
} else { } else {
if (m_buildManager->tasksAvailable()) if (m_buildManager->tasksAvailable())
m_buildManager->showTaskWindow(); m_buildManager->showTaskWindow();
} }
m_delayedRunConfiguration = QSharedPointer<RunConfiguration>(0);
m_runMode = QString::null;
} }
void ProjectExplorerPlugin::updateTaskActions() void ProjectExplorerPlugin::updateTaskActions()
@@ -1306,10 +1320,18 @@ bool ProjectExplorerPlugin::saveModifiedFiles(const QList<Project *> & projects)
} }
if (!filesToSave.isEmpty()) { if (!filesToSave.isEmpty()) {
bool cancelled; if (m_projectExplorerSettings.saveBeforeBuild) {
Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave, &cancelled); Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave);
if (cancelled) { } else {
return false; bool cancelled = false;
bool alwaysSave = false;
Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave, &cancelled, QString::null, "Always save files before build", &alwaysSave);
if (cancelled) {
return false;
}
if (alwaysSave) {
m_projectExplorerSettings.saveBeforeBuild = true;
}
} }
} }
return true; return true;
@@ -1408,12 +1430,16 @@ void ProjectExplorerPlugin::runProjectImpl(Project *pro)
if (!pro) if (!pro)
return; return;
if (saveModifiedFiles(QList<Project *>() << pro)) { if (m_projectExplorerSettings.buildBeforeRun) {
m_runMode = ProjectExplorer::Constants::RUNMODE; if (saveModifiedFiles(QList<Project *>() << pro)) {
m_runMode = ProjectExplorer::Constants::RUNMODE;
m_delayedRunConfiguration = pro->activeRunConfiguration();
m_delayedRunConfiguration = pro->activeRunConfiguration(); //NBS TODO make the build project step take into account project dependencies
//NBS TODO make the build project step take into account project dependencies m_buildManager->buildProject(pro, pro->activeBuildConfiguration());
m_buildManager->buildProject(pro, pro->activeBuildConfiguration()); }
} else {
executeRunConfiguration(pro->activeRunConfiguration(), ProjectExplorer::Constants::RUNMODE);
} }
} }
@@ -1905,4 +1931,15 @@ void ProjectExplorerPlugin::setSession(QAction *action)
m_session->loadSession(session); m_session->loadSession(session);
} }
void ProjectExplorerPlugin::setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes)
{
m_projectExplorerSettings = pes;
}
Internal::ProjectExplorerSettings ProjectExplorerPlugin::projectExplorerSettings() const
{
return m_projectExplorerSettings;
}
Q_EXPORT_PLUGIN(ProjectExplorerPlugin) Q_EXPORT_PLUGIN(ProjectExplorerPlugin)

View File

@@ -71,6 +71,12 @@ class OutputPane;
class ProjectWindow; class ProjectWindow;
class ProjectFileFactory; class ProjectFileFactory;
struct ProjectExplorerSettings
{
bool buildBeforeRun;
bool saveBeforeBuild;
};
} // namespace Internal } // namespace Internal
class PROJECTEXPLORER_EXPORT ProjectExplorerPlugin class PROJECTEXPLORER_EXPORT ProjectExplorerPlugin
@@ -109,6 +115,9 @@ public:
void extensionsInitialized(); void extensionsInitialized();
void shutdown(); void shutdown();
void setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes);
Internal::ProjectExplorerSettings projectExplorerSettings() const;
signals: signals:
void aboutToShowContextMenu(ProjectExplorer::Project *project, void aboutToShowContextMenu(ProjectExplorer::Project *project,
ProjectExplorer::Node *node); ProjectExplorer::Node *node);
@@ -186,6 +195,7 @@ private slots:
private: private:
void runProjectImpl(Project *pro); void runProjectImpl(Project *pro);
void executeRunConfiguration(QSharedPointer<RunConfiguration>, const QString &mode);
void setCurrent(Project *project, QString filePath, Node *node); void setCurrent(Project *project, QString filePath, Node *node);
QStringList allFilesWithDependencies(Project *pro); QStringList allFilesWithDependencies(Project *pro);
@@ -259,6 +269,7 @@ private:
RunControl *m_debuggingRunControl; RunControl *m_debuggingRunControl;
QString m_runMode; QString m_runMode;
QString m_projectFilterString; QString m_projectFilterString;
Internal::ProjectExplorerSettings m_projectExplorerSettings;
}; };
namespace Internal { namespace Internal {

View File

@@ -59,8 +59,9 @@ HEADERS += projectexplorer.h \
gccparser.h \ gccparser.h \
msvcparser.h \ msvcparser.h \
filewatcher.h \ filewatcher.h \
debugginghelper.h\ debugginghelper.h \
abstractmakestep.h abstractmakestep.h \
projectexplorersettingspage.h
SOURCES += projectexplorer.cpp \ SOURCES += projectexplorer.cpp \
projectwindow.cpp \ projectwindow.cpp \
buildmanager.cpp \ buildmanager.cpp \
@@ -109,7 +110,8 @@ SOURCES += projectexplorer.cpp \
msvcparser.cpp \ msvcparser.cpp \
filewatcher.cpp \ filewatcher.cpp \
debugginghelper.cpp \ debugginghelper.cpp \
abstractmakestep.cpp abstractmakestep.cpp \
projectexplorersettingspage.cpp
FORMS += dependenciespanel.ui \ FORMS += dependenciespanel.ui \
buildsettingspropertiespage.ui \ buildsettingspropertiespage.ui \
processstep.ui \ processstep.ui \
@@ -118,7 +120,8 @@ FORMS += dependenciespanel.ui \
sessiondialog.ui \ sessiondialog.ui \
projectwizardpage.ui \ projectwizardpage.ui \
buildstepspage.ui \ buildstepspage.ui \
removefiledialog.ui removefiledialog.ui \
projectexplorersettingspage.ui
win32 { win32 {
SOURCES += applicationlauncher_win.cpp \ SOURCES += applicationlauncher_win.cpp \
winguiprocess.cpp winguiprocess.cpp

View File

@@ -176,6 +176,11 @@ const char * const RESOURCE_MIMETYPE = "application/vnd.nokia.xml.qt.resource";
// build parsers // build parsers
const char * const BUILD_PARSER_MSVC = "BuildParser.MSVC"; const char * const BUILD_PARSER_MSVC = "BuildParser.MSVC";
const char * const BUILD_PARSER_GCC = "BuildParser.Gcc"; const char * const BUILD_PARSER_GCC = "BuildParser.Gcc";
// settings page
const char * const PROJECTEXPLORER_CATEGORY = "ProjectExplorer";
const char * const PROJECTEXPLORER_PAGE = "ProjectExplorer.ProjectExplorer";
} // namespace Constants } // namespace Constants
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -0,0 +1,89 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/
#include "projectexplorersettingspage.h"
#include "projectexplorerconstants.h"
#include "projectexplorer.h"
#include <QtGui/QLabel>
using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;
ProjectExplorerSettingsPage::ProjectExplorerSettingsPage()
{
}
ProjectExplorerSettingsPage::~ProjectExplorerSettingsPage()
{
}
QString ProjectExplorerSettingsPage::id() const
{
return Constants::PROJECTEXPLORER_PAGE;
}
QString ProjectExplorerSettingsPage::trName() const
{
return tr("Build and Run Settings");
}
QString ProjectExplorerSettingsPage::category() const
{
return Constants::PROJECTEXPLORER_PAGE;
}
QString ProjectExplorerSettingsPage::trCategory() const
{
return tr("Projectexplorer");
}
QWidget *ProjectExplorerSettingsPage::createPage(QWidget *parent)
{
QWidget *w = new QWidget(parent);
m_ui.setupUi(w);
ProjectExplorerSettings pes = ProjectExplorerPlugin::instance()->projectExplorerSettings();
m_ui.buildProjectBeforeRunCheckBox->setChecked(pes.buildBeforeRun);
m_ui.saveAllFilesCheckBox->setChecked(pes.saveBeforeBuild);
return w;
}
void ProjectExplorerSettingsPage::apply()
{
ProjectExplorerSettings pes;
pes.buildBeforeRun = m_ui.buildProjectBeforeRunCheckBox->isChecked();
pes.saveBeforeBuild = m_ui.saveAllFilesCheckBox->isChecked();
ProjectExplorerPlugin::instance()->setProjectExplorerSettings(pes);
}
void ProjectExplorerSettingsPage::finish()
{
// Nothing to do
}

View File

@@ -0,0 +1,60 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
**
**************************************************************************/
#ifndef PROJECTEXPLORERSETTINGSPAGE_H
#define PROJECTEXPLORERSETTINGSPAGE_H
#include <coreplugin/dialogs/ioptionspage.h>
#include "ui_projectexplorersettingspage.h"
namespace ProjectExplorer {
namespace Internal {
class ProjectExplorerSettingsPage : public Core::IOptionsPage
{
public:
ProjectExplorerSettingsPage();
~ProjectExplorerSettingsPage();
virtual QString id() const;
virtual QString trName() const;
virtual QString category() const;
virtual QString trCategory() const;
virtual QWidget *createPage(QWidget *parent);
virtual void apply();
virtual void finish();
private:
ProjectExplorer::Internal::Ui::ProjetExplorerSettingsPageUi m_ui;
};
} // Internal
} // ProjectExplorer
#endif // PROJECTEXPLORERSETTINGSPAGE_H

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProjectExplorer::Internal::ProjetExplorerSettingsPageUi</class>
<widget class="QWidget" name="ProjectExplorer::Internal::ProjetExplorerSettingsPageUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>541</width>
<height>358</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Build Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="saveAllFilesCheckBox">
<property name="text">
<string>Save all files before Build</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Run Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="buildProjectBeforeRunCheckBox">
<property name="text">
<string>Always build Project before Running</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -960,7 +960,8 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
skip_event: skip_event:
if (!ro && e->key() == Qt::Key_Delete && d->m_parenthesesMatchingEnabled) if (!ro && e->key() == Qt::Key_Delete && d->m_parenthesesMatchingEnabled)
slotCursorPositionChanged(); // parentheses matching d->m_parenthesesMatchingTimer->start(50);
if (!ro && d->m_contentsChanged && !e->text().isEmpty() && e->text().at(0).isPrint()) if (!ro && d->m_contentsChanged && !e->text().isEmpty() && e->text().at(0).isPrint())
emit requestAutoCompletion(editableInterface(), false); emit requestAutoCompletion(editableInterface(), false);
@@ -3535,9 +3536,18 @@ void BaseTextEditor::_q_matchParentheses()
} }
extraSelections.append(sel); extraSelections.append(sel);
} }
setExtraSelections(ParenthesesMatchingSelection, extraSelections);
if (animatePosition >= 0) {
foreach (QTextEdit::ExtraSelection sel, BaseTextEditor::extraSelections(ParenthesesMatchingSelection)) {
if (sel.cursor.selectionStart() == animatePosition
|| sel.cursor.selectionEnd() - 1 == animatePosition) {
animatePosition = -1;
break;
}
}
}
if (animatePosition >= 0) { if (animatePosition >= 0) {
if (d->m_animator) if (d->m_animator)
d->m_animator->finish(); // one animation is enough d->m_animator->finish(); // one animation is enough
@@ -3549,9 +3559,9 @@ void BaseTextEditor::_q_matchParentheses()
d->m_animator->setData(font(), pal, characterAt(d->m_animator->position())); d->m_animator->setData(font(), pal, characterAt(d->m_animator->position()));
connect(d->m_animator, SIGNAL(updateRequest(int,QRectF)), connect(d->m_animator, SIGNAL(updateRequest(int,QRectF)),
this, SLOT(_q_animateUpdate(int,QRectF))); this, SLOT(_q_animateUpdate(int,QRectF)));
} }
setExtraSelections(ParenthesesMatchingSelection, extraSelections);
} }
void BaseTextEditor::_q_highlightBlocks() void BaseTextEditor::_q_highlightBlocks()

View File

@@ -52,7 +52,7 @@ static const char test11[] =
"{name=\"0\",value=\"one\",type=\"QByteArray\"}]"; "{name=\"0\",value=\"one\",type=\"QByteArray\"}]";
static const char test12[] = static const char test12[] =
"[{iname=\"local.hallo\",value=\"\\\"\\\"\",type=\"QByteArray\"," "[{iname=\"local.hallo\",value=\"\\\"\\\\\\00382\\t\\377\",type=\"QByteArray\","
"numchild=\"0\"}]"; "numchild=\"0\"}]";
class tst_Debugger : public QObject class tst_Debugger : public QObject