From 66bea14fef08fbae841995e0b1e288fb66cc4678 Mon Sep 17 00:00:00 2001 From: dt Date: Tue, 5 May 2009 18:21:40 +0200 Subject: [PATCH 01/20] Add options to: Save All before Build and Build before Run So now you can choose not to automatically build before running. And you can chose to automatically save all files before building. The options are global and the default is the same as before. --- src/plugins/projectexplorer/project.cpp | 6 +- .../projectexplorer/projectexplorer.cpp | 111 ++++++++++++------ src/plugins/projectexplorer/projectexplorer.h | 11 ++ .../projectexplorer/projectexplorer.pro | 11 +- .../projectexplorerconstants.h | 5 + 5 files changed, 98 insertions(+), 46 deletions(-) diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 459f8114acf..cc18fbcfd36 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -506,17 +506,17 @@ void Project::setDisplayNameFor(const QString &buildConfiguration, const QString emit buildConfigurationDisplayNameChanged(buildConfiguration); } -QByteArray Project::predefinedMacros(const QString &fileName) const +QByteArray Project::predefinedMacros(const QString &) const { return QByteArray(); } -QStringList Project::includePaths(const QString &fileName) const +QStringList Project::includePaths(const QString &) const { return QStringList(); } -QStringList Project::frameworkPaths(const QString &fileName) const +QStringList Project::frameworkPaths(const QString &) const { return QStringList(); } diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index ebb6a1000a7..4dbf49d7561 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -56,6 +56,7 @@ #include "session.h" #include "sessiondialog.h" #include "buildparserfactory.h" +#include "projectexplorersettingspage.h" #include #include @@ -233,6 +234,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er addAutoReleasedObject(new GccParserFactory); addAutoReleasedObject(new MsvcParserFactory); + // Settings page + addAutoReleasedObject(new ProjectExplorerSettingsPage); + // context menus Core::ActionContainer *msessionContextMenu = am->createMenu(Constants::M_SESSIONCONTEXT); @@ -619,7 +623,6 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er } // < -- Creator 1.0 compatibility code - // TODO restore recentProjects if (QSettings *s = core->settings()) { const QStringList fileNames = s->value("ProjectExplorer/RecentProjects/FileNames").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_newAction, SIGNAL(triggered()), this, SLOT(newProject())); @@ -856,6 +862,9 @@ void ProjectExplorerPlugin::savePersistentSettings() s->setValue("ProjectExplorer/RecentProjects/FileNames", fileNames); 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(); } +void ProjectExplorerPlugin::executeRunConfiguration(QSharedPointer 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) { if (debug) @@ -1118,38 +1157,13 @@ void ProjectExplorerPlugin::buildQueueFinished(bool success) updateActions(); if (success && m_delayedRunConfiguration) { - IRunConfigurationRunner *runner = findRunner(m_delayedRunConfiguration, m_runMode); - if (runner) { - emit aboutToExecuteProject(m_delayedRunConfiguration->project()); - - 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(); - } + executeRunConfiguration(m_delayedRunConfiguration, m_runMode); + m_delayedRunConfiguration = QSharedPointer(0); + m_runMode = QString::null; } else { if (m_buildManager->tasksAvailable()) m_buildManager->showTaskWindow(); } - - m_delayedRunConfiguration = QSharedPointer(0); - m_runMode = QString::null; } void ProjectExplorerPlugin::updateTaskActions() @@ -1306,10 +1320,14 @@ bool ProjectExplorerPlugin::saveModifiedFiles(const QList & projects) } if (!filesToSave.isEmpty()) { - bool cancelled; - Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave, &cancelled); - if (cancelled) { - return false; + if (m_projectExplorerSettings.saveBeforeBuild) { + Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave); + } else { + bool cancelled = false; + Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave, &cancelled); + if (cancelled) { + return false; + } } } return true; @@ -1408,12 +1426,16 @@ void ProjectExplorerPlugin::runProjectImpl(Project *pro) if (!pro) return; - if (saveModifiedFiles(QList() << pro)) { - m_runMode = ProjectExplorer::Constants::RUNMODE; + if (m_projectExplorerSettings.buildBeforeRun) { + if (saveModifiedFiles(QList() << 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 - m_buildManager->buildProject(pro, pro->activeBuildConfiguration()); + //NBS TODO make the build project step take into account project dependencies + m_buildManager->buildProject(pro, pro->activeBuildConfiguration()); + } + } else { + executeRunConfiguration(pro->activeRunConfiguration(), ProjectExplorer::Constants::RUNMODE); } } @@ -1905,4 +1927,15 @@ void ProjectExplorerPlugin::setSession(QAction *action) 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) diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index 987cb323fb6..6beca9504f9 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -71,6 +71,12 @@ class OutputPane; class ProjectWindow; class ProjectFileFactory; +struct ProjectExplorerSettings +{ + bool buildBeforeRun; + bool saveBeforeBuild; +}; + } // namespace Internal class PROJECTEXPLORER_EXPORT ProjectExplorerPlugin @@ -109,6 +115,9 @@ public: void extensionsInitialized(); void shutdown(); + void setProjectExplorerSettings(const Internal::ProjectExplorerSettings &pes); + Internal::ProjectExplorerSettings projectExplorerSettings() const; + signals: void aboutToShowContextMenu(ProjectExplorer::Project *project, ProjectExplorer::Node *node); @@ -186,6 +195,7 @@ private slots: private: void runProjectImpl(Project *pro); + void executeRunConfiguration(QSharedPointer, const QString &mode); void setCurrent(Project *project, QString filePath, Node *node); QStringList allFilesWithDependencies(Project *pro); @@ -259,6 +269,7 @@ private: RunControl *m_debuggingRunControl; QString m_runMode; QString m_projectFilterString; + Internal::ProjectExplorerSettings m_projectExplorerSettings; }; namespace Internal { diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index e6a04cf83d9..170a54387ea 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -59,8 +59,9 @@ HEADERS += projectexplorer.h \ gccparser.h \ msvcparser.h \ filewatcher.h \ - debugginghelper.h\ - abstractmakestep.h + debugginghelper.h \ + abstractmakestep.h \ + projectexplorersettingspage.h SOURCES += projectexplorer.cpp \ projectwindow.cpp \ buildmanager.cpp \ @@ -109,7 +110,8 @@ SOURCES += projectexplorer.cpp \ msvcparser.cpp \ filewatcher.cpp \ debugginghelper.cpp \ - abstractmakestep.cpp + abstractmakestep.cpp \ + projectexplorersettingspage.cpp FORMS += dependenciespanel.ui \ buildsettingspropertiespage.ui \ processstep.ui \ @@ -118,7 +120,8 @@ FORMS += dependenciespanel.ui \ sessiondialog.ui \ projectwizardpage.ui \ buildstepspage.ui \ - removefiledialog.ui + removefiledialog.ui \ + projectexplorersettingspage.ui win32 { SOURCES += applicationlauncher_win.cpp \ winguiprocess.cpp diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 10c56b8deaa..351f333a27e 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -176,6 +176,11 @@ const char * const RESOURCE_MIMETYPE = "application/vnd.nokia.xml.qt.resource"; // build parsers const char * const BUILD_PARSER_MSVC = "BuildParser.MSVC"; 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 ProjectExplorer From f0c1244cbe6eca66b56f01b2bba958b2f155e754 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 4 May 2009 20:49:40 +0200 Subject: [PATCH 02/20] fix MI parser & dumper --- src/plugins/debugger/gdbmi.cpp | 101 ++++++++++++++++++++++++++++----- src/plugins/debugger/gdbmi.h | 1 + tests/auto/debugger/main.cpp | 2 +- 3 files changed, 88 insertions(+), 16 deletions(-) diff --git a/src/plugins/debugger/gdbmi.cpp b/src/plugins/debugger/gdbmi.cpp index 4cbd53ab1fe..bb858ad4db3 100644 --- a/src/plugins/debugger/gdbmi.cpp +++ b/src/plugins/debugger/gdbmi.cpp @@ -34,6 +34,8 @@ #include #include +#include + namespace Debugger { namespace Internal { @@ -44,7 +46,7 @@ QTextStream &operator<<(QTextStream &os, const GdbMi &mi) void GdbMi::parseResultOrValue(const char *&from, const char *to) { - while (from != to && QChar(*from).isSpace()) + while (from != to && isspace(*from)) ++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); if (*from != '"') { qDebug() << "MI Parse Error, double quote expected"; + ++from; // So we don't hang return QByteArray(); } const char *ptr = from; @@ -84,22 +87,66 @@ QByteArray GdbMi::parseCString(const char *&from, const char *to) result = QByteArray(from + 1, ptr - from - 2); break; } - if (*ptr == '\\' && ptr < to - 1) + if (*ptr == '\\') { ++ptr; + if (ptr == to) { + qDebug() << "MI Parse Error, unterminated backslash escape"; + from = ptr; // So we don't hang + return QByteArray(); + } + } ++ptr; } + from = ptr; - if (result.contains('\\')) { - if (result.contains("\\032\\032")) - result.clear(); - else { - result = result.replace("\\n", "\n"); - result = result.replace("\\t", "\t"); - result = result.replace("\\\"", "\""); - } + int idx = result.indexOf('\\'); + if (idx >= 0) { + char *dst = result.data() + idx; + const char *src = dst + 1, *end = result.data() + result.length(); + do { + char c = *src++; + 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; } @@ -203,10 +250,34 @@ void GdbMi::dumpChildren(QByteArray * str, bool multiline, int indent) const } } -static QByteArray escaped(QByteArray ba) +QByteArray GdbMi::escapeCString(const QByteArray &ba) { - ba.replace("\"", "\\\""); - return ba; + QByteArray ret; + ret.reserve(ba.length() * 2); + for (int i = 0; i < ba.length(); ++i) { + uchar 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; } QByteArray GdbMi::toString(bool multiline, int indent) const @@ -222,7 +293,7 @@ QByteArray GdbMi::toString(bool multiline, int indent) const case Const: if (!m_name.isEmpty()) result += m_name + "="; - result += "\"" + escaped(m_data) + "\""; + result += "\"" + escapeCString(m_data) + "\""; break; case Tuple: if (!m_name.isEmpty()) diff --git a/src/plugins/debugger/gdbmi.h b/src/plugins/debugger/gdbmi.h index 311bef2a7ce..30de06be386 100644 --- a/src/plugins/debugger/gdbmi.h +++ b/src/plugins/debugger/gdbmi.h @@ -132,6 +132,7 @@ private: friend class GdbEngine; static QByteArray parseCString(const char *&from, const char *to); + static QByteArray escapeCString(const QByteArray &ba); void parseResultOrValue(const char *&from, const char *to); void parseValue(const char *&from, const char *to); void parseTuple(const char *&from, const char *to); diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp index 4e7eeeeb61f..afb51a38c01 100644 --- a/tests/auto/debugger/main.cpp +++ b/tests/auto/debugger/main.cpp @@ -52,7 +52,7 @@ static const char test11[] = "{name=\"0\",value=\"one\",type=\"QByteArray\"}]"; static const char test12[] = - "[{iname=\"local.hallo\",value=\"\\\"\\\"\",type=\"QByteArray\"," + "[{iname=\"local.hallo\",value=\"\\\"\\\\\\00382\\t\\377\",type=\"QByteArray\"," "numchild=\"0\"}]"; class tst_Debugger : public QObject From 57a93374cdd1774783ed39336ff34700fa689346 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2009 15:53:17 +0200 Subject: [PATCH 03/20] add some C escaping to relevant MI commands --- src/plugins/debugger/gdbengine.cpp | 16 +++++++++------- src/plugins/debugger/gdbmi.cpp | 22 +++++++++++++++++++--- src/plugins/debugger/gdbmi.h | 1 + 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 653a6817b62..1706b09b6e2 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -1824,9 +1824,9 @@ void GdbEngine::sendInsertBreakpoint(int index) //if (where.isEmpty()) // where = data->fileName; #endif - // we need something like "\"file name.cpp\":100" to - // survive the gdb command line parser with file names intact - where = _("\"\\\"") + where + _("\\\":") + data->lineNumber + _c('"'); + // The argument is simply a C-quoted version of the argument to the + // non-MI "break" command, including the "original" quoting it wants. + where = _("\"\\\"") + GdbMi::escapeCString(where) + _("\\\":") + data->lineNumber + _c('"'); } else { where = data->funcName; } @@ -1987,6 +1987,8 @@ void GdbEngine::handleBreakInsert(const GdbResultRecord &record, const QVariant handler->updateMarkers(); } else if (record.resultClass == GdbResultError) { 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 //QString where = "\"\\\"" + data->fileName + "\\\":" // + data->lineNumber + "\""; @@ -3848,13 +3850,13 @@ void GdbEngine::tryLoadDebuggingHelpers() execCommand(_("sharedlibrary .*")); // for LoadLibraryA //execCommand(_("handle SIGSEGV pass stop print")); //execCommand(_("set unwindonsignal off")); - execCommand(_("call LoadLibraryA(\"") + lib + _("\")"), + execCommand(_("call LoadLibraryA(\"") + GdbMi::escapeCString(lib) + _("\")"), CB(handleDebuggingHelperSetup)); execCommand(_("sharedlibrary ") + dotEscape(lib)); #elif defined(Q_OS_MAC) //execCommand(_("sharedlibrary libc")); // for malloc //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)); //execCommand(_("sharedlibrary ") + dotEscape(lib)); m_debuggingHelperState = DebuggingHelperLoadTried; @@ -3863,10 +3865,10 @@ void GdbEngine::tryLoadDebuggingHelpers() QString flag = QString::number(RTLD_NOW); execCommand(_("sharedlibrary libc")); // for malloc 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)); // 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)); execCommand(_("sharedlibrary ") + dotEscape(lib)); #endif diff --git a/src/plugins/debugger/gdbmi.cpp b/src/plugins/debugger/gdbmi.cpp index bb858ad4db3..e2fd7e7a25a 100644 --- a/src/plugins/debugger/gdbmi.cpp +++ b/src/plugins/debugger/gdbmi.cpp @@ -250,12 +250,18 @@ void GdbMi::dumpChildren(QByteArray * str, bool multiline, int indent) const } } -QByteArray GdbMi::escapeCString(const QByteArray &ba) +class MyString : public QString { +public: + ushort at(int i) const { return constData()[i].unicode(); } +}; + +template +inline ST escapeCStringTpl(const ST &ba) { - QByteArray ret; + ST ret; ret.reserve(ba.length() * 2); for (int i = 0; i < ba.length(); ++i) { - uchar c = ba.at(i); + CT c = ba.at(i); switch (c) { case '\\': ret += "\\\\"; break; case '\a': ret += "\\a"; break; @@ -280,6 +286,16 @@ QByteArray GdbMi::escapeCString(const QByteArray &ba) return ret; } +QString GdbMi::escapeCString(const QString &ba) +{ + return escapeCStringTpl(static_cast(ba)); +} + +QByteArray GdbMi::escapeCString(const QByteArray &ba) +{ + return escapeCStringTpl(ba); +} + QByteArray GdbMi::toString(bool multiline, int indent) const { QByteArray result; diff --git a/src/plugins/debugger/gdbmi.h b/src/plugins/debugger/gdbmi.h index 30de06be386..1e9731bb303 100644 --- a/src/plugins/debugger/gdbmi.h +++ b/src/plugins/debugger/gdbmi.h @@ -133,6 +133,7 @@ private: 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 parseValue(const char *&from, const char *to); void parseTuple(const char *&from, const char *to); From 0368b2134a4cd1a46c29b7b03c3fa417bbb57815 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2009 18:49:35 +0200 Subject: [PATCH 04/20] fix typos --- share/qtcreator/gdbmacros/gdbmacros.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index 6277c5477cd..e5786afc048 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -94,10 +94,10 @@ int qtGhVersion = QT_VERSION; \c{qDumpObjectData440()}. 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)} - function. At the bare minimum it should contain something like: + function. At the bare minimum it should contain something like this: \c{ @@ -127,7 +127,7 @@ int qtGhVersion = QT_VERSION; \endlist 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{ if (d.dumpChildren) { @@ -1168,7 +1168,7 @@ static void qDumpQHashNode(QDumper &d) P(d, "numchild", 2); 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.beginHash(); P(d, "name", "key"); @@ -2679,7 +2679,7 @@ void *qDumpObjectData440( // This is a list of all available dumpers. Note that some templates // 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. d << "dumpers=[" "\""NS"QByteArray\"," From 0b802b31c894771c9fc5a10184081796b77fa4e6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2009 18:52:57 +0200 Subject: [PATCH 05/20] less inefficient still quite some potential ... --- share/qtcreator/gdbmacros/gdbmacros.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index e5786afc048..fdcbfad0f83 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -221,16 +221,19 @@ Q_DECL_EXPORT char qDumpOutBuffer[100000]; namespace { +static QByteArray strPtrConst = "* const"; + 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); - if (type.endsWith("* const")) + if (type.endsWith(strPtrConst)) type.chop(7); if (type.endsWith(' ')) type.chop(1); @@ -279,7 +282,10 @@ static bool isEqual(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. @@ -293,11 +299,18 @@ static bool startsWith(const char *s, const char *t) # define qCheckPointer(d) do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) #endif +#ifdef QT_NAMESPACE 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; } +#else +inline const char *stripNamespace(const char *type) +{ + return type; +} +#endif static bool isSimpleType(const char *type) { From b590b6adc14b598435966e98376b1a3e5d6c0ff3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2009 19:41:53 +0200 Subject: [PATCH 06/20] fix (rather theoretical) off-by-one --- src/plugins/debugger/gdbengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 1706b09b6e2..3adcface13e 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -3304,7 +3304,7 @@ void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record, QByteArray out = output.data(); 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 data.setError(strNotInScope); insertData(data); From 192c0e7423828895ff3a4cf4ce253ec599a1273f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2009 19:42:11 +0200 Subject: [PATCH 07/20] document dumper output parsing hack --- src/plugins/debugger/gdbengine.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 3adcface13e..12e1aa1623b 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -3100,8 +3100,7 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const QByteArray out = output.data(); out = out.mid(out.indexOf('"') + 2); // + 1 is success marker out = out.left(out.lastIndexOf('"')); - //out.replace('\'', '"'); - out.replace("\\", ""); + out.replace('\\', ""); // optimization: dumper output never needs real C unquoting out = "dummy={" + out + "}"; //qDebug() << "OUTPUT: " << out; @@ -3313,7 +3312,7 @@ void GdbEngine::handleDebuggingHelperValue2(const GdbResultRecord &record, out = out.mid(markerPos + 1); out = out.left(out.lastIndexOf('"')); - out.replace("\\", ""); + out.replace('\\', ""); // optimization: dumper output never needs real C unquoting out = "dummy={" + out + "}"; GdbMi contents; From 61d74351628da15d2139869e7e53662340be08bf Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2009 20:33:31 +0200 Subject: [PATCH 08/20] add missing operator --- src/plugins/debugger/watchutils.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 5693c2c2159..407ada9cadf 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -136,6 +136,7 @@ bool hasSideEffects(const QString &exp) return exp.contains(QLatin1String("-=")) || exp.contains(QLatin1String("+=")) || exp.contains(QLatin1String("/=")) + || exp.contains(QLatin1String("%=")) || exp.contains(QLatin1String("*=")) || exp.contains(QLatin1String("&=")) || exp.contains(QLatin1String("|=")) From 094c1bfca1356107d58309eff6ea7590e5d035a2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 5 May 2009 20:34:13 +0200 Subject: [PATCH 09/20] twice helps twice? --- src/plugins/debugger/cdb/cdbdumperhelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/cdb/cdbdumperhelper.cpp b/src/plugins/debugger/cdb/cdbdumperhelper.cpp index 541aa7ea1d0..b76398254d0 100644 --- a/src/plugins/debugger/cdb/cdbdumperhelper.cpp +++ b/src/plugins/debugger/cdb/cdbdumperhelper.cpp @@ -571,7 +571,7 @@ CdbDumperHelper::DumpResult CdbDumperHelper::dumpType(const WatchData &wd, bool if (der == DumpExecuteSizeFailed) m_failedTypes.push_back(wd.type); // log error - *errorMessage = *errorMessage = msgDumpFailed(wd, errorMessage); + *errorMessage = msgDumpFailed(wd, errorMessage); m_access->showDebuggerOutput(m_messagePrefix, *errorMessage); return DumpError; } From 3294f1f61cc821d869b0c5f034bd97d9bf1a8652 Mon Sep 17 00:00:00 2001 From: dt Date: Wed, 6 May 2009 08:21:57 +0200 Subject: [PATCH 10/20] Added missing files of last commit. --- .../projectexplorersettingspage.cpp | 89 +++++++++++++++++++ .../projectexplorersettingspage.h | 60 +++++++++++++ .../projectexplorersettingspage.ui | 69 ++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 src/plugins/projectexplorer/projectexplorersettingspage.cpp create mode 100644 src/plugins/projectexplorer/projectexplorersettingspage.h create mode 100644 src/plugins/projectexplorer/projectexplorersettingspage.ui diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.cpp b/src/plugins/projectexplorer/projectexplorersettingspage.cpp new file mode 100644 index 00000000000..f5e87f827ed --- /dev/null +++ b/src/plugins/projectexplorer/projectexplorersettingspage.cpp @@ -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 + +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 +} diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.h b/src/plugins/projectexplorer/projectexplorersettingspage.h new file mode 100644 index 00000000000..378bfc54c7d --- /dev/null +++ b/src/plugins/projectexplorer/projectexplorersettingspage.h @@ -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 +#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 diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.ui b/src/plugins/projectexplorer/projectexplorersettingspage.ui new file mode 100644 index 00000000000..6f48641355e --- /dev/null +++ b/src/plugins/projectexplorer/projectexplorersettingspage.ui @@ -0,0 +1,69 @@ + + + ProjectExplorer::Internal::ProjetExplorerSettingsPageUi + + + + 0 + 0 + 541 + 358 + + + + Form + + + + 0 + + + + + Build Settings + + + + + + Save all files before Build + + + + + + + + + + Run Settings + + + + + + Always build Project before Running + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + From 63384fbdc3c6819cebaa4a43637a942b4612f1bc Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 6 May 2009 09:22:05 +0200 Subject: [PATCH 11/20] Made std::vector/std::list work with CDB dumpers. --- share/qtcreator/gdbmacros/gdbmacros.cpp | 28 +++++++++++++----- share/qtcreator/gdbmacros/test/main.cpp | 39 +++++++++++++++++++------ src/plugins/debugger/watchutils.cpp | 4 ++- 3 files changed, 53 insertions(+), 18 deletions(-) diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index fdcbfad0f83..b3f054ffbb2 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -32,7 +32,7 @@ // this relies on contents copied from qobject_p.h #define PRIVATE_OBJECT_ALLOWED 1 -#ifdef HAS_QOBJECT_P_H +#ifdef HAS_QOBJECT_P_H // Detected by qmake # include #endif #include @@ -149,7 +149,7 @@ int qtGhVersion = QT_VERSION; # define NSY "" #endif -#if PRIVATE_OBJECT_ALLOWED && !HAS_QOBJECT_P_H +#if PRIVATE_OBJECT_ALLOWED && !defined(HAS_QOBJECT_P_H) #if defined(QT_BEGIN_NAMESPACE) QT_BEGIN_NAMESPACE @@ -292,8 +292,8 @@ static bool startsWith(const char *s, const char *t) // On Windows, try to be less crash-prone by checking memory using WinAPI #ifdef Q_OS_WIN -# define qCheckAccess(d) if (IsBadReadPtr(d, 1)) return; do { qProvokeSegFaultHelper = *(char*)d; } while (0) -# define qCheckPointer(d) if (d && IsBadReadPtr(d, 1)) return; do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) +# define qCheckAccess(d) do { if (IsBadReadPtr(d, 1)) return; qProvokeSegFaultHelper = *(char*)d; } while (0) +# define qCheckPointer(d) do { if (d && IsBadReadPtr(d, 1)) return; if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) #else # define qCheckAccess(d) do { qProvokeSegFaultHelper = *(char*)d; } while (0) # define qCheckPointer(d) do { if (d) qProvokeSegFaultHelper = *(char*)d; } while (0) @@ -2252,7 +2252,14 @@ static void qDumpQWeakPointer(QDumper &d) static void qDumpStdList(QDumper &d) { const std::list &list = *reinterpret_cast *>(d.data); - const void *p = d.data; +#ifdef Q_CC_MSVC + const int size = static_cast(list.size()); + if (size < 0) + return; + if (size) + qCheckAccess(list.begin().operator ->()); +#else + const void *p = d.data; qCheckAccess(p); p = deref(p); qCheckAccess(p); @@ -2264,7 +2271,7 @@ static void qDumpStdList(QDumper &d) qCheckAccess(p); p = deref(addOffset(p, sizeof(void*))); qCheckAccess(p); - +#endif int nn = 0; std::list::const_iterator it = list.begin(); for (; nn < 101 && it != list.end(); ++nn, ++it) @@ -2447,7 +2454,7 @@ static void qDumpStdWString(QDumper &d) } static void qDumpStdVector(QDumper &d) -{ +{ // Correct type would be something like: // std::_Vector_base >>::_Vector_impl struct VectorImpl { @@ -2455,8 +2462,13 @@ static void qDumpStdVector(QDumper &d) char *finish; char *end_of_storage; }; +#ifdef Q_CC_MSVC + // Pointers are at end of the structure + const char * vcp = static_cast(d.data); + const VectorImpl *v = reinterpret_cast(vcp + sizeof(std::vector) - sizeof(VectorImpl)); +#else const VectorImpl *v = static_cast(d.data); - +#endif // Try to provoke segfaults early to prevent the frontend // from asking for unavailable child details int nn = (v->finish - v->start) / d.extraInt[0]; diff --git a/share/qtcreator/gdbmacros/test/main.cpp b/share/qtcreator/gdbmacros/test/main.cpp index f760e40aa98..fcb6d9061cd 100644 --- a/share/qtcreator/gdbmacros/test/main.cpp +++ b/share/qtcreator/gdbmacros/test/main.cpp @@ -30,11 +30,11 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -204,19 +204,36 @@ static int dumpStdStringVector() return 0; } +static int dumpStdIntSet() +{ + std::set 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::allocator_type), 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} + +static int dumpStdStringSet() +{ + std::set 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::allocator_type), 0, 0); + fputs(qDumpOutBuffer, stdout); + fputc('\n', stdout); + return 0; +} static int dumpQObject() { + // Requires the childOffset to be know, but that is not critical QTimer t; - QObjectPrivate *tp = reinterpret_cast(&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", ""); - qDumpObjectData440(2, 42, &t, 1, childOffset, 0, 0, 0); + qDumpObjectData440(2, 42, &t, 1, 0, 0, 0, 0); fputs(qDumpOutBuffer, stdout); fputc('\n', stdout); return 0; @@ -256,6 +273,10 @@ int main(int argc, char *argv[]) dumpStdIntVector(); if (!qstrcmp(arg, "vector")) dumpStdStringVector(); + if (!qstrcmp(arg, "set")) + dumpStdIntSet(); + if (!qstrcmp(arg, "set")) + dumpStdStringSet(); if (!qstrcmp(arg, "QObject")) dumpQObject(); } diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp index 407ada9cadf..812442a3238 100644 --- a/src/plugins/debugger/watchutils.cpp +++ b/src/plugins/debugger/watchutils.cpp @@ -455,7 +455,7 @@ QDebug operator<<(QDebug in, const QtDumperResult &d) const QtDumperResult::Child &c = d.children.at(i); nospace << " #" << i << " addr=" << c.address << " disabled=" << c.valuedisabled - << " type=" << c.type + << " type=" << c.type << " exp=" << c.exp << " name=" << c.name << " encoded=" << c.valueEncoded << " value=" << c.value << "childcount=" << c.childCount << '\n'; @@ -1377,6 +1377,8 @@ bool QtDumperHelper::parseValue(const char *data, QtDumperResult *r) // Sanity if (r->childCount < r->children.size()) r->childCount = r->children.size(); + if (debug) + qDebug() << '\n' << data << *r; return true; } From 457addbf4011342a0452fc6c26756c56c44e60b3 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 6 May 2009 09:17:16 +0200 Subject: [PATCH 12/20] debugger: imporev grey-out logic on the dumper settings page --- src/plugins/debugger/debuggerplugin.cpp | 8 +++++--- src/plugins/debugger/dumperoptionpage.ui | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index cbb8a160cab..01d882dba00 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -368,6 +368,7 @@ QWidget *DebuggingHelperOptionPage::createPage(QWidget *parent) mdebug->addAction(cmd); #endif #endif + updateState(); return w; } @@ -376,9 +377,10 @@ void DebuggingHelperOptionPage::updateState() { m_ui.checkBoxUseCustomDebuggingHelperLocation->setEnabled( m_ui.checkBoxUseDebuggingHelpers->isChecked()); - m_ui.dumperLocationChooser->setEnabled( - m_ui.checkBoxUseDebuggingHelpers->isChecked() - && m_ui.checkBoxUseCustomDebuggingHelperLocation->isChecked()); + bool locationEnabled = m_ui.checkBoxUseDebuggingHelpers->isChecked() + && m_ui.checkBoxUseCustomDebuggingHelperLocation->isChecked(); + m_ui.dumperLocationChooser->setEnabled(locationEnabled); + m_ui.dumperLocationLabel->setEnabled(locationEnabled); } } // namespace Internal diff --git a/src/plugins/debugger/dumperoptionpage.ui b/src/plugins/debugger/dumperoptionpage.ui index dc11cfac9d8..0ff6ddc6c2d 100644 --- a/src/plugins/debugger/dumperoptionpage.ui +++ b/src/plugins/debugger/dumperoptionpage.ui @@ -73,7 +73,7 @@ - + Location: From 62f40474a60673a634708a83366788179e9b0db8 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 6 May 2009 09:44:11 +0200 Subject: [PATCH 13/20] debugger: work on gdbserver based remote debugging Works only with Archer, possibly gdb head. It attaches now, sets breakpoints, steps etc but cannot be stopped when running. --- src/plugins/debugger/gdbengine.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 12e1aa1623b..272a9e076a6 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -1021,8 +1021,6 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) return; } - //tryLoadDebuggingHelpers(); - // jump over well-known frames static int stepCounter = 0; if (theDebuggerBoolSetting(SkipKnownFrames)) { @@ -1420,6 +1418,7 @@ bool GdbEngine::startDebugger() //execCommand(_("set print pretty on")); //execCommand(_("set confirm off")); //execCommand(_("set pagination off")); + execCommand(_("set print inferior-events 1")); execCommand(_("set breakpoint pending on")); execCommand(_("set print elements 10000")); execCommand(_("-data-list-register-names"), CB(handleRegisterListNames)); @@ -1602,8 +1601,10 @@ void GdbEngine::handleTargetAsync(const GdbResultRecord &record, const QVariant if (record.resultClass == GdbResultDone) { //execCommand(_("info target"), handleStart); qq->notifyInferiorRunningRequested(); - execCommand(_("target remote %1").arg(q->m_remoteChannel)); - execCommand(_("-exec-continue"), CB(handleExecRun)); + execCommand(_("target remote %1").arg(q->m_remoteChannel), + CB(handleAttach)); + //execCommand(_("-exec-continue"), CB(handleExecRun)); + handleAqcuiredInferior(); } else if (record.resultClass == GdbResultError) { // a typical response on "old" gdb is: // &"set target-async on\n" From 4381b9d244bc6b8a035753ebafd276d66edec4f5 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 6 May 2009 10:13:36 +0200 Subject: [PATCH 14/20] debugger: introduce a "NoEngine" option --- src/plugins/debugger/cdb/cdbdebugengine.cpp | 8 --- src/plugins/debugger/cdb/cdbdebugengine.h | 3 - src/plugins/debugger/debuggermanager.cpp | 73 ++++++++++----------- src/plugins/debugger/debuggermanager.h | 2 +- src/plugins/debugger/gdbengine.h | 3 - src/plugins/debugger/idebuggerengine.h | 3 - src/plugins/debugger/scriptengine.h | 3 - 7 files changed, 34 insertions(+), 61 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index a7d60ad7fe7..72a60595ca1 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -1186,14 +1186,6 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa errorMessage); } -void CdbDebugEngine::loadSessionData() -{ -} - -void CdbDebugEngine::saveSessionData() -{ -} - void CdbDebugEngine::reloadDisassembler() { enum { ContextLines = 40 }; diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h index 35fce47f66f..04185c05bb4 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.h +++ b/src/plugins/debugger/cdb/cdbdebugengine.h @@ -85,9 +85,6 @@ public: virtual void attemptBreakpointSynchronization(); - virtual void loadSessionData(); - virtual void saveSessionData(); - virtual void reloadDisassembler(); virtual void reloadModules(); diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index ee7c653f06e..b9879aaacac 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -427,7 +427,7 @@ QList DebuggerManager::initializeEngines(const QStringList const bool cdbDisabled = arguments.contains(_("-disable-cdb")); winEngine = createWinEngine(this, cdbDisabled, &rc); scriptEngine = createScriptEngine(this, &rc); - setDebuggerType(GdbDebugger); + setDebuggerType(NoDebugger); if (Debugger::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << gdbEngine << winEngine << scriptEngine << rc.size(); return rc; @@ -445,6 +445,8 @@ void DebuggerManager::setDebuggerType(DebuggerType type) case WinDebugger: m_engine = winEngine; break; + case NoDebugger: + m_engine = 0; } } @@ -697,7 +699,6 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) if (Debugger::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << fileName << lineNumber; - QTC_ASSERT(m_engine, return); QTC_ASSERT(m_breakHandler, return); if (status() != DebuggerInferiorRunning && status() != DebuggerInferiorStopped @@ -712,7 +713,8 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) m_breakHandler->setBreakpoint(fileName, lineNumber); else m_breakHandler->removeBreakpoint(index); - m_engine->attemptBreakpointSynchronization(); + + attemptBreakpointSynchronization(); } void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineNumber) @@ -720,7 +722,6 @@ void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineN if (Debugger::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << fileName << lineNumber; - QTC_ASSERT(m_engine, return); QTC_ASSERT(m_breakHandler, return); if (status() != DebuggerInferiorRunning && status() != DebuggerInferiorStopped @@ -731,24 +732,26 @@ void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineN } m_breakHandler->toggleBreakpointEnabled(fileName, lineNumber); - m_engine->attemptBreakpointSynchronization(); + + attemptBreakpointSynchronization(); } void DebuggerManager::attemptBreakpointSynchronization() { - m_engine->attemptBreakpointSynchronization(); + if (m_engine) + m_engine->attemptBreakpointSynchronization(); } void DebuggerManager::setToolTipExpression(const QPoint &pos, const QString &exp) { - QTC_ASSERT(m_engine, return); - m_engine->setToolTipExpression(pos, exp); + if (m_engine) + m_engine->setToolTipExpression(pos, exp); } void DebuggerManager::updateWatchModel() { - QTC_ASSERT(m_engine, return); - m_engine->updateWatchModel(); + if (m_engine) + m_engine->updateWatchModel(); } QVariant DebuggerManager::sessionValue(const QString &name) @@ -946,9 +949,9 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl) DebuggerType type; QString errorMessage; - const bool hasDebugger = startMode() == AttachExternal ? - determineDebuggerType(m_attachedPID, &type, &errorMessage) : - determineDebuggerType(m_executable, &type, &errorMessage); + const bool hasDebugger = startMode() == AttachExternal + ? determineDebuggerType(m_attachedPID, &type, &errorMessage) + : determineDebuggerType(m_executable, &type, &errorMessage); if (!hasDebugger) { QMessageBox::warning(mainWindow(), tr("Warning"), tr("Cannot debug '%1': %2").arg(m_executable, errorMessage)); @@ -1117,18 +1120,14 @@ void DebuggerManager::aboutToSaveSession() void DebuggerManager::loadSessionData() { - QTC_ASSERT(m_engine, return); m_breakHandler->loadSessionData(); m_watchHandler->loadSessionData(); - m_engine->loadSessionData(); } void DebuggerManager::saveSessionData() { - QTC_ASSERT(m_engine, return); m_breakHandler->saveSessionData(); m_watchHandler->saveSessionData(); - m_engine->saveSessionData(); } void DebuggerManager::dumpLog() @@ -1164,17 +1163,15 @@ void DebuggerManager::setBreakpoint(const QString &fileName, int lineNumber) qDebug() << Q_FUNC_INFO << fileName << lineNumber; QTC_ASSERT(m_breakHandler, return); - QTC_ASSERT(m_engine, return); m_breakHandler->setBreakpoint(fileName, lineNumber); - m_engine->attemptBreakpointSynchronization(); + attemptBreakpointSynchronization(); } void DebuggerManager::breakByFunction(const QString &functionName) { QTC_ASSERT(m_breakHandler, return); - QTC_ASSERT(m_engine, return); m_breakHandler->breakByFunction(functionName); - m_engine->attemptBreakpointSynchronization(); + attemptBreakpointSynchronization(); } void DebuggerManager::breakByFunction() @@ -1300,14 +1297,16 @@ void DebuggerManager::queryCurrentTextEditor(QString *fileName, int *lineNumber, void DebuggerManager::continueExec() { - m_engine->continueInferior(); + if (m_engine) + m_engine->continueInferior(); } void DebuggerManager::interruptDebuggingRequest() { if (Debugger::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << status(); - QTC_ASSERT(m_engine, return); + if (!m_engine) + return; bool interruptIsExit = (status() != DebuggerInferiorRunning); if (interruptIsExit) exitDebugger(); @@ -1319,11 +1318,10 @@ void DebuggerManager::interruptDebuggingRequest() void DebuggerManager::runToLineExec() { - QTC_ASSERT(m_engine, return); QString fileName; int lineNumber = -1; emit currentTextEditorRequested(&fileName, &lineNumber, 0); - if (!fileName.isEmpty()) { + if (m_engine && !fileName.isEmpty()) { if (Debugger::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << fileName << lineNumber; m_engine->runToLineExec(fileName, lineNumber); @@ -1360,7 +1358,7 @@ void DebuggerManager::runToFunctionExec() if (Debugger::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << functionName; - if (!functionName.isEmpty()) + if (m_engine && !functionName.isEmpty()) m_engine->runToFunctionExec(functionName); } @@ -1369,7 +1367,7 @@ void DebuggerManager::jumpToLineExec() QString fileName; int lineNumber = -1; emit currentTextEditorRequested(&fileName, &lineNumber, 0); - if (!fileName.isEmpty()) { + if (m_engine && !fileName.isEmpty()) { if (Debugger::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << fileName << lineNumber; m_engine->jumpToLineExec(fileName, lineNumber); @@ -1404,10 +1402,8 @@ void DebuggerManager::fileOpen(const QString &fileName) void DebuggerManager::reloadDisassembler() { - QTC_ASSERT(m_engine, return); - if (!m_disassemblerDock || !m_disassemblerDock->isVisible()) - return; - m_engine->reloadDisassembler(); + if (m_engine && m_disassemblerDock && m_disassemblerDock->isVisible()) + m_engine->reloadDisassembler(); } void DebuggerManager::disassemblerDockToggled(bool on) @@ -1425,9 +1421,8 @@ void DebuggerManager::disassemblerDockToggled(bool on) void DebuggerManager::reloadSourceFiles() { - if (!m_sourceFilesDock || !m_sourceFilesDock->isVisible()) - return; - m_engine->reloadSourceFiles(); + if (m_engine && m_sourceFilesDock && m_sourceFilesDock->isVisible()) + m_engine->reloadSourceFiles(); } void DebuggerManager::sourceFilesDockToggled(bool on) @@ -1445,9 +1440,8 @@ void DebuggerManager::sourceFilesDockToggled(bool on) void DebuggerManager::reloadModules() { - if (!m_modulesDock || !m_modulesDock->isVisible()) - return; - m_engine->reloadModules(); + if (m_engine && m_modulesDock && m_modulesDock->isVisible()) + m_engine->reloadModules(); } void DebuggerManager::modulesDockToggled(bool on) @@ -1490,9 +1484,8 @@ void DebuggerManager::registerDockToggled(bool on) void DebuggerManager::reloadRegisters() { - if (!m_registerDock || !m_registerDock->isVisible()) - return; - m_engine->reloadRegisters(); + if (m_engine && m_registerDock && m_registerDock->isVisible()) + m_engine->reloadRegisters(); } ////////////////////////////////////////////////////////////////////// diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index ad92a003f3b..1d9e97d0368 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -202,7 +202,7 @@ public: QMainWindow *mainWindow() const { return m_mainWindow; } QLabel *statusLabel() const { return m_statusLabel; } - enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger }; + enum DebuggerType { NoDebugger, GdbDebugger, ScriptDebugger, WinDebugger }; public slots: void startNewDebugger(DebuggerRunControl *runControl); diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h index c053bc1c0ac..87523ae703b 100644 --- a/src/plugins/debugger/gdbengine.h +++ b/src/plugins/debugger/gdbengine.h @@ -112,9 +112,6 @@ private: Q_SLOT void attemptBreakpointSynchronization(); - void loadSessionData() {} - void saveSessionData() {} - void assignValueInDebugger(const QString &expr, const QString &value); void executeDebuggerCommand(const QString & command); diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index 0d3863a34e7..cf700c20877 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -74,9 +74,6 @@ public: virtual void attemptBreakpointSynchronization() = 0; - virtual void loadSessionData() = 0; - virtual void saveSessionData() = 0; - virtual void reloadDisassembler() = 0; virtual void reloadModules() = 0; diff --git a/src/plugins/debugger/scriptengine.h b/src/plugins/debugger/scriptengine.h index ee5612d09d8..79568aca88f 100644 --- a/src/plugins/debugger/scriptengine.h +++ b/src/plugins/debugger/scriptengine.h @@ -94,9 +94,6 @@ private: void attemptBreakpointSynchronization(); - void loadSessionData() {} - void saveSessionData() {} - void assignValueInDebugger(const QString &expr, const QString &value); void executeDebuggerCommand(const QString & command); From 67d327c7cc0b88ad3c16fa932e8809fbea14d48b Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 6 May 2009 10:21:50 +0200 Subject: [PATCH 15/20] debugger: make stack reload engine-agnostic --- src/plugins/debugger/cdb/cdbdebugengine.h | 1 + src/plugins/debugger/debuggermanager.cpp | 13 +++++++++++-- src/plugins/debugger/debuggermanager.h | 1 + src/plugins/debugger/gdbengine.cpp | 6 +----- src/plugins/debugger/idebuggerengine.h | 1 + src/plugins/debugger/scriptengine.h | 1 + 6 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h index 04185c05bb4..74547ab33ad 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.h +++ b/src/plugins/debugger/cdb/cdbdebugengine.h @@ -94,6 +94,7 @@ public: virtual void reloadRegisters(); virtual void reloadSourceFiles(); + virtual void reloadFullStack() {} protected: void timerEvent(QTimerEvent*); diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index b9879aaacac..23cc84059d2 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -206,6 +206,10 @@ void DebuggerManager::init() stackView->setModel(m_stackHandler->stackModel()); connect(stackView, SIGNAL(frameActivated(int)), this, SLOT(activateFrame(int))); + connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()), + this, SLOT(reloadFullStack())); + connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()), + this, SLOT(reloadFullStack())); // Threads m_threadsHandler = new ThreadsHandler; @@ -273,9 +277,8 @@ void DebuggerManager::init() m_registerHandler = new RegisterHandler; registerView->setModel(m_registerHandler->model()); - m_watchHandler = new WatchHandler; - // Locals + m_watchHandler = new WatchHandler; QTreeView *localsView = qobject_cast(m_localsWindow); localsView->setModel(m_watchHandler->model()); @@ -1539,6 +1542,12 @@ DebuggerStartMode DebuggerManager::startMode() const return m_runControl->startMode(); } +void DebuggerManager::reloadFullStack() +{ + if (m_engine) + m_engine->reloadFullStack(); +} + ////////////////////////////////////////////////////////////////////// // diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 1d9e97d0368..38a0c5d7b74 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -279,6 +279,7 @@ private slots: void setStatus(int status); void clearStatusMessage(); void attemptBreakpointSynchronization(); + void reloadFullStack(); private: // diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 272a9e076a6..f7d6071c7ee 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -158,17 +158,13 @@ void GdbEngine::initializeConnections() q, SLOT(showApplicationOutput(QString)), Qt::QueuedConnection); + // FIXME: These trigger even if the engine is not active connect(theDebuggerAction(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)), this, SLOT(setUseDebuggingHelpers(QVariant))); connect(theDebuggerAction(DebugDebuggingHelpers), SIGNAL(valueChanged(QVariant)), this, SLOT(setDebugDebuggingHelpers(QVariant))); connect(theDebuggerAction(RecheckDebuggingHelpers), SIGNAL(triggered()), this, SLOT(recheckDebuggingHelperAvailability())); - - connect(theDebuggerAction(ExpandStack), SIGNAL(triggered()), - this, SLOT(reloadFullStack())); - connect(theDebuggerAction(MaximalStackDepth), SIGNAL(triggered()), - this, SLOT(reloadFullStack())); } void GdbEngine::initializeVariables() diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index cf700c20877..ececbe9aa7a 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -84,6 +84,7 @@ public: virtual void reloadRegisters() = 0; virtual void reloadSourceFiles() = 0; + virtual void reloadFullStack() = 0; }; } // namespace Internal diff --git a/src/plugins/debugger/scriptengine.h b/src/plugins/debugger/scriptengine.h index 79568aca88f..1e116b39015 100644 --- a/src/plugins/debugger/scriptengine.h +++ b/src/plugins/debugger/scriptengine.h @@ -104,6 +104,7 @@ private: void reloadModules(); void reloadRegisters() {} void reloadSourceFiles() {} + void reloadFullStack() {} bool supportsThreads() const { return true; } void maybeBreakNow(bool byFunction); From 8d7389fa8da09794416bb1c37ddf7d9d5184dc88 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Wed, 6 May 2009 10:49:33 +0200 Subject: [PATCH 16/20] Fix: Compile on Mac OS X with the official Qt for Mac / Qt SDK for Mac. Find translation helper binaries in QT_INSTALL_BINS. QT_INSTALL_PREFIX is / on OS X, since it cannot have a meaningful value, unless you are compiling Qt to work from the build dir, in which case QT_INSTALL_PREFIX is set to this directory. --- share/qtcreator/translations/translations.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/translations/translations.pro b/share/qtcreator/translations/translations.pro index dd4f6d5d47e..0c4fd7fb187 100644 --- a/share/qtcreator/translations/translations.pro +++ b/share/qtcreator/translations/translations.pro @@ -9,8 +9,8 @@ defineReplace(prependAll) { return($$result) } -LUPDATE = $$targetPath($$[QT_INSTALL_PREFIX]/bin/lupdate) -locations relative -no-ui-lines -LRELEASE = $$targetPath($$[QT_INSTALL_PREFIX]/bin/lrelease) +LUPDATE = $$targetPath($$[QT_INSTALL_BINS]/bin/lupdate) -locations relative -no-ui-lines +LRELEASE = $$targetPath($$[QT_INSTALL_BINS]/bin/lrelease) TS_FILES = $$prependAll(TRANSLATIONS, $$PWD/qtcreator_,.ts) From 68d85acaa512c9cdcb33323a3ccf9a2f811a41bf Mon Sep 17 00:00:00 2001 From: mae Date: Wed, 6 May 2009 11:18:56 +0200 Subject: [PATCH 17/20] supress parentheses animation if the position was part of the previous parentheses highlighting. This makes the Delete key work smoother when the cursor is positioned behind a closing parenthesis. --- src/plugins/texteditor/basetexteditor.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index d01cc3f1d6e..0918c841548 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -960,7 +960,8 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e) skip_event: 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()) emit requestAutoCompletion(editableInterface(), false); @@ -3535,9 +3536,18 @@ void BaseTextEditor::_q_matchParentheses() } 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 (d->m_animator) 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())); connect(d->m_animator, SIGNAL(updateRequest(int,QRectF)), this, SLOT(_q_animateUpdate(int,QRectF))); - } - + } + setExtraSelections(ParenthesesMatchingSelection, extraSelections); } void BaseTextEditor::_q_highlightBlocks() From b5df077946bce198ecaf40ec3e86c3a05713a765 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 6 May 2009 11:37:41 +0200 Subject: [PATCH 18/20] debugger: use -exec-interrupt to interrupt inferiors in gdbserver --- src/plugins/debugger/gdbengine.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index f7d6071c7ee..454a71df9ef 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -528,12 +528,18 @@ void GdbEngine::readGdbStandardOutput() void GdbEngine::interruptInferior() { qq->notifyInferiorStopRequested(); + if (m_gdbProc.state() == QProcess::NotRunning) { debugMessage(_("TRYING TO INTERRUPT INFERIOR WITHOUT RUNNING GDB")); qq->notifyInferiorExited(); return; } + if (q->startMode() == AttachRemote) { + execCommand(_("-exec-interrupt")); + return; + } + if (q->m_attachedPID <= 0) { debugMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED")); return; From 8ab578b11abe73eda2b6ed03a885763728a1057e Mon Sep 17 00:00:00 2001 From: dt Date: Wed, 6 May 2009 11:55:21 +0200 Subject: [PATCH 19/20] Show a nice checkbox in the save dialog for SaveBeforeBuild --- .../coreplugin/dialogs/saveitemsdialog.cpp | 13 +++++++++++++ .../coreplugin/dialogs/saveitemsdialog.h | 3 ++- .../coreplugin/dialogs/saveitemsdialog.ui | 7 +++++++ src/plugins/coreplugin/filemanager.cpp | 18 +++++++++++++++--- src/plugins/coreplugin/filemanager.h | 9 +++++++-- .../projectexplorer/projectexplorer.cpp | 6 +++++- 6 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp b/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp index 80b15b4c94b..c49ae2dbbe6 100644 --- a/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp @@ -55,6 +55,8 @@ SaveItemsDialog::SaveItemsDialog(QWidget *parent, 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.saveBeforeBuildCheckBox->setVisible(false); + foreach (IFile *file, items) { QString visibleName; QString directory; @@ -121,3 +123,14 @@ QList SaveItemsDialog::itemsToSave() const { 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(); +} diff --git a/src/plugins/coreplugin/dialogs/saveitemsdialog.h b/src/plugins/coreplugin/dialogs/saveitemsdialog.h index ff22baa1f66..237db0d752d 100644 --- a/src/plugins/coreplugin/dialogs/saveitemsdialog.h +++ b/src/plugins/coreplugin/dialogs/saveitemsdialog.h @@ -57,7 +57,8 @@ public: QList items); void setMessage(const QString &msg); - + void setAlwaysSaveMessage(const QString &msg); + bool alwaysSaveChecked(); QList itemsToSave() const; private slots: diff --git a/src/plugins/coreplugin/dialogs/saveitemsdialog.ui b/src/plugins/coreplugin/dialogs/saveitemsdialog.ui index 966be8f4f30..6f37a47ddda 100644 --- a/src/plugins/coreplugin/dialogs/saveitemsdialog.ui +++ b/src/plugins/coreplugin/dialogs/saveitemsdialog.ui @@ -56,6 +56,13 @@ + + + + Automatically save all Files before building + + + diff --git a/src/plugins/coreplugin/filemanager.cpp b/src/plugins/coreplugin/filemanager.cpp index 5a9276fd851..b42611b2217 100644 --- a/src/plugins/coreplugin/filemanager.cpp +++ b/src/plugins/coreplugin/filemanager.cpp @@ -292,9 +292,11 @@ QList FileManager::saveModifiedFilesSilently(const QList &file Asks the user whether to save the files listed in \a files . Returns the files that have not been saved. */ QList FileManager::saveModifiedFiles(const QList &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) @@ -307,7 +309,11 @@ static QMessageBox::StandardButton skipFailedPrompt(QWidget *parent, const QStri } QList FileManager::saveModifiedFiles(const QList &files, - bool *cancelled, bool silently, const QString &message) + bool *cancelled, + bool silently, + const QString &message, + const QString &alwaysSaveMessage, + bool *alwaysSave) { if (cancelled) (*cancelled) = false; @@ -338,12 +344,18 @@ QList FileManager::saveModifiedFiles(const QList &files, SaveItemsDialog dia(m_mainWindow, modifiedFiles); if (!message.isEmpty()) dia.setMessage(message); + if (!alwaysSaveMessage.isNull()) + dia.setAlwaysSaveMessage(alwaysSaveMessage); if (dia.exec() != QDialog::Accepted) { if (cancelled) (*cancelled) = true; + if (alwaysSave) + *alwaysSave = dia.alwaysSaveChecked(); notSaved = modifiedFiles; return notSaved; } + if (alwaysSave) + *alwaysSave = dia.alwaysSaveChecked(); filesToSave = dia.itemsToSave(); } diff --git a/src/plugins/coreplugin/filemanager.h b/src/plugins/coreplugin/filemanager.h index 52dafe4ca88..6be80514fd8 100644 --- a/src/plugins/coreplugin/filemanager.h +++ b/src/plugins/coreplugin/filemanager.h @@ -97,7 +97,9 @@ public: QList saveModifiedFilesSilently(const QList &files); QList saveModifiedFiles(const QList &files, bool *cancelled = 0, - const QString &message = QString()); + const QString &message = QString(), + const QString &alwaysSaveMessage = QString::null, + bool *alwaysSave = 0); signals: void currentFileChanged(const QString &filePath); @@ -116,7 +118,10 @@ private: void updateFileInfo(IFile *file); QList saveModifiedFiles(const QList &files, - bool *cancelled, bool silently, const QString &message); + bool *cancelled, bool silently, + const QString &message, + const QString &alwaysSaveMessage = QString::null, + bool *alwaysSave = 0); QMap m_managedFiles; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 4dbf49d7561..eae61dd93b1 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1324,10 +1324,14 @@ bool ProjectExplorerPlugin::saveModifiedFiles(const QList & projects) Core::ICore::instance()->fileManager()->saveModifiedFilesSilently(filesToSave); } else { bool cancelled = false; - Core::ICore::instance()->fileManager()->saveModifiedFiles(filesToSave, &cancelled); + 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; From 99becbe187f816c44ace1091516140eaa8283541 Mon Sep 17 00:00:00 2001 From: Daniel Molkentin Date: Wed, 6 May 2009 12:05:02 +0200 Subject: [PATCH 20/20] Fix for 8d7389fa8da09794416bb1c37ddf7d9d5184dc88. --- share/qtcreator/translations/translations.pro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/translations/translations.pro b/share/qtcreator/translations/translations.pro index 0c4fd7fb187..2021a405d8e 100644 --- a/share/qtcreator/translations/translations.pro +++ b/share/qtcreator/translations/translations.pro @@ -9,8 +9,8 @@ defineReplace(prependAll) { return($$result) } -LUPDATE = $$targetPath($$[QT_INSTALL_BINS]/bin/lupdate) -locations relative -no-ui-lines -LRELEASE = $$targetPath($$[QT_INSTALL_BINS]/bin/lrelease) +LUPDATE = $$targetPath($$[QT_INSTALL_BINS]/lupdate) -locations relative -no-ui-lines +LRELEASE = $$targetPath($$[QT_INSTALL_BINS]/lrelease) TS_FILES = $$prependAll(TRANSLATIONS, $$PWD/qtcreator_,.ts)