diff --git a/.gitignore b/.gitignore index 2c79a07b759..e0c76e75e46 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ src/xml/lib/ # -------- bin/*.dll bin/qtcreator.bin +bin/qtcreator_process_stub bin/qtcreator.exe doc/qtcreator.qch tests/manual/cplusplus/cplusplus0 diff --git a/dist/changes-1.1.0 b/dist/changes-1.1.0 index 28e9f0c9b61..3fa27a9763c 100644 --- a/dist/changes-1.1.0 +++ b/dist/changes-1.1.0 @@ -18,9 +18,6 @@ Editing * Improved function argument hint. * More checkpoints in editor history. * Ctrl-click for jumping to a symbol definition. - * Context help for form editor widgets. - * Goto slot from form editor now works with multiple inheritance. - * Add signal/slot editor to form editor. * Improved open documents view (sorted, single-click, close buttons). * Copying text from the context help browser and output windows didn't work. @@ -36,7 +33,7 @@ Debugging no dumper buildstep anymore. * New dumper for std::set. Improved QString, QVariant, std::wstring * Make strategy to load shared objects configurable (auto-solib-add). - * Maximum stack depth configurable. + * Increase number of shown stack frames on request instead of loading them all. * Improved interaction in the Locals&Watchers view. Wizards @@ -48,6 +45,7 @@ Wizards Designer * Added signal/slot editor. * Fixed "Goto slot" (formatting/multiple inheritance). + * Context help for form editor widgets. Version control plugins * Fixed handling of colored git output. diff --git a/doc/qtcreator.qdoc b/doc/qtcreator.qdoc index e47ed3eb9b5..a59897820a3 100644 --- a/doc/qtcreator.qdoc +++ b/doc/qtcreator.qdoc @@ -43,21 +43,6 @@ \endlist \endtable - \raw HTML -
- - - - - - - -
- \endraw - To learn more about the Qt Creator, click on one of the links below: \list @@ -1438,23 +1423,6 @@ \title Keyboard Shortcuts - \raw HTML -
- - - - - - - - -
- \endraw - - Qt Creator provides various keyboard shortcuts to aid in the development process. These shortcuts are listed in the table below: diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp index 80ab420c5fa..06c1e1ae1cf 100644 --- a/share/qtcreator/gdbmacros/gdbmacros.cpp +++ b/share/qtcreator/gdbmacros/gdbmacros.cpp @@ -202,11 +202,12 @@ QT_END_NAMESPACE #endif // PRIVATE_OBJECT_ALLOWED -// this can be mangled typenames of nested templates, each char-by-char -// comma-separated integer list -static char qDumpInBuffer[10000]; -static char qDumpOutBuffer[100000]; -//static char qDumpSize[20]; +// This can be mangled typenames of nested templates, each char-by-char +// comma-separated integer list... +Q_DECL_EXPORT char qDumpInBuffer[10000]; + +// The output buffer. +Q_DECL_EXPORT char qDumpOutBuffer[100000]; namespace { @@ -2396,6 +2397,10 @@ static void handleProtocolVersion2and3(QDumper & d) const char *type = stripNamespace(d.outertype); // type[0] is usally 'Q', so don't use it switch (type[1]) { + case 'a': + if (isEqual(type, "map")) + qDumpStdMap(d); + break; case 'B': if (isEqual(type, "QByteArray")) qDumpQByteArray(d); @@ -2406,6 +2411,12 @@ static void handleProtocolVersion2and3(QDumper & d) else if (isEqual(type, "QDir")) qDumpQDir(d); break; + case 'e': + if (isEqual(type, "vector")) + qDumpStdVector(d); + else if (isEqual(type, "set")) + qDumpStdSet(d); + break; case 'F': if (isEqual(type, "QFile")) qDumpQFile(d); @@ -2418,6 +2429,10 @@ static void handleProtocolVersion2and3(QDumper & d) else if (isEqual(type, "QHashNode")) qDumpQHashNode(d); break; + case 'i': + if (isEqual(type, "list")) + qDumpStdList(d); + break; case 'I': if (isEqual(type, "QImage")) qDumpQImage(d); @@ -2510,7 +2525,7 @@ static void handleProtocolVersion2and3(QDumper & d) extern "C" Q_DECL_EXPORT -void qDumpObjectData440( +void *qDumpObjectData440( int protocolVersion, int token, void *data, @@ -2545,18 +2560,18 @@ void qDumpObjectData440( "\""NS"QMap\"," "\""NS"QMapNode\"," "\""NS"QModelIndex\"," - #if QT_VERSION >= 0x040500 +#if QT_VERSION >= 0x040500 "\""NS"QMultiMap\"," - #endif +#endif "\""NS"QObject\"," "\""NS"QObjectMethodList\"," // hack to get nested properties display "\""NS"QObjectPropertyList\"," - #if PRIVATE_OBJECT_ALLOWED +#if PRIVATE_OBJECT_ALLOWED "\""NS"QObjectSignal\"," "\""NS"QObjectSignalList\"," "\""NS"QObjectSlot\"," "\""NS"QObjectSlotList\"," - #endif // PRIVATE_OBJECT_ALLOWED +#endif // PRIVATE_OBJECT_ALLOWED // << "\""NS"QRegion\"," "\""NS"QSet\"," "\""NS"QString\"," @@ -2565,8 +2580,15 @@ void qDumpObjectData440( "\""NS"QVariant\"," "\""NS"QVector\"," "\""NS"QWidget\"," +#ifdef Q_OS_WIN + "\"basic_string\"," + "\"list\"," + "\"map\"," + "\"set\"," "\"string\"," + "\"vector\"," "\"wstring\"," +#endif "\"std::basic_string\"," "\"std::list\"," "\"std::map\"," @@ -2608,4 +2630,5 @@ void qDumpObjectData440( else { qDebug() << "Unsupported protocol version" << protocolVersion; } + return qDumpOutBuffer; } diff --git a/share/qtcreator/runInTerminal.command b/share/qtcreator/runInTerminal.command index 372820c1b11..3cc5baa050d 100755 --- a/share/qtcreator/runInTerminal.command +++ b/share/qtcreator/runInTerminal.command @@ -1,11 +1,50 @@ -#!/bin/bash -osascript >/dev/null 2>&1 <&2 + exit 1;; + esac +done +args= +for i in "$@"; do + i=${i//\\/\\\\\\\\} + i=${i//\"/\\\\\\\"} + i=${i//\$/\\\\\\\$} + i=${i//\`/\\\\\\\`} + args="$args \\\"$i\\\"" +done +osascript < QT_BEGIN_NAMESPACE class QWinEventNotifier; -class QTemporaryFile; QT_END_NAMESPACE #endif +QT_BEGIN_NAMESPACE +class QSettings; +class QTemporaryFile; +QT_END_NAMESPACE + namespace Core { namespace Utils { @@ -69,6 +73,13 @@ public: int exitCode() const { return m_appCode; } // This will be the signal number if exitStatus == CrashExit QProcess::ExitStatus exitStatus() const { return m_appStatus; } +#ifdef Q_OS_UNIX + void setSettings(QSettings *settings) { m_settings = settings; } + static QString defaultTerminalEmulator(); + static QString terminalEmulator(const QSettings *settings); + static void setTerminalEmulator(QSettings *settings, const QString &term); +#endif + signals: void processError(const QString &error); // These reflect the state of the actual client process @@ -102,15 +113,16 @@ private: QProcess::ExitStatus m_appStatus; QLocalServer m_stubServer; QLocalSocket *m_stubSocket; + QTemporaryFile *m_tempFile; #ifdef Q_OS_WIN PROCESS_INFORMATION *m_pid; HANDLE m_hInferior; QWinEventNotifier *inferiorFinishedNotifier; QWinEventNotifier *processFinishedNotifier; - QTemporaryFile *m_tempFile; #else QProcess m_process; QByteArray m_stubServerDir; + QSettings *m_settings; #endif }; diff --git a/src/libs/utils/consoleprocess_unix.cpp b/src/libs/utils/consoleprocess_unix.cpp index 2e20ac0c37a..a43264b59d0 100644 --- a/src/libs/utils/consoleprocess_unix.cpp +++ b/src/libs/utils/consoleprocess_unix.cpp @@ -30,6 +30,8 @@ #include "consoleprocess.h" #include +#include +#include #include #include @@ -48,6 +50,7 @@ ConsoleProcess::ConsoleProcess(QObject *parent) m_debug = false; m_appPid = 0; m_stubSocket = 0; + m_settings = 0; connect(&m_stubServer, SIGNAL(newConnection()), SLOT(stubConnectionAvailable())); @@ -72,8 +75,24 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args) return false; } - QStringList xtermArgs; - xtermArgs << "-e" + if (!environment().isEmpty()) { + m_tempFile = new QTemporaryFile(); + if (!m_tempFile->open()) { + stubServerShutdown(); + emit processError(tr("Cannot create temp file: %1").arg(m_tempFile->errorString())); + delete m_tempFile; + m_tempFile = 0; + return false; + } + foreach (const QString &var, environment()) { + m_tempFile->write(var.toLocal8Bit()); + m_tempFile->write("", 1); + } + m_tempFile->flush(); + } + + QStringList xtermArgs = terminalEmulator(m_settings).split(QLatin1Char(' ')); // FIXME: quoting + xtermArgs #ifdef Q_OS_MAC << (QCoreApplication::applicationDirPath() + "/../Resources/qtcreator_process_stub") #else @@ -82,13 +101,17 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args) << (m_debug ? "debug" : "exec") << m_stubServer.fullServerName() << tr("Press to close this window...") - << workingDirectory() << environment() << "" + << workingDirectory() + << (m_tempFile ? m_tempFile->fileName() : 0) << program << args; - m_process.start(QLatin1String("xterm"), xtermArgs); + QString xterm = xtermArgs.takeFirst(); + m_process.start(xterm, xtermArgs); if (!m_process.waitForStarted()) { stubServerShutdown(); - emit processError(tr("Cannot start console emulator xterm.")); + emit processError(tr("Cannot start terminal emulator %1.").arg(xterm)); + delete m_tempFile; + m_tempFile = 0; return false; } m_executable = program; @@ -173,6 +196,10 @@ void ConsoleProcess::readStubOutput() emit processError(tr("Cannot execute %1: %2") .arg(m_executable, errorMsg(out.mid(9).toInt()))); } else if (out.startsWith("pid ")) { + // Will not need it any more + delete m_tempFile; + m_tempFile = 0; + m_appPid = out.mid(4).toInt(); emit processStarted(); } else if (out.startsWith("exit ")) { @@ -199,6 +226,8 @@ void ConsoleProcess::stubExited() if (m_stubSocket && m_stubSocket->state() == QLocalSocket::ConnectedState) m_stubSocket->waitForDisconnected(); stubServerShutdown(); + delete m_tempFile; + m_tempFile = 0; if (m_appPid) { m_appStatus = QProcess::CrashExit; m_appCode = -1; @@ -207,3 +236,27 @@ void ConsoleProcess::stubExited() } emit wrapperStopped(); } + +QString ConsoleProcess::defaultTerminalEmulator() +{ +// FIXME: enable this once runInTerminal works nicely +#if 0 //def Q_OS_MAC + return QDir::cleanPath(QCoreApplication::applicationDirPath() + + QLatin1String("/../Resources/runInTerminal.command")); +#else + return QLatin1String("xterm"); +#endif +} + +QString ConsoleProcess::terminalEmulator(const QSettings *settings) +{ + QString dflt = defaultTerminalEmulator() + QLatin1String(" -e"); + if (!settings) + return dflt; + return settings->value(QLatin1String("General/TerminalEmulator"), dflt).toString(); +} + +void ConsoleProcess::setTerminalEmulator(QSettings *settings, const QString &term) +{ + return settings->setValue(QLatin1String("General/TerminalEmulator"), term); +} diff --git a/src/libs/utils/process_stub_unix.c b/src/libs/utils/process_stub_unix.c index 92c38bb5f0d..9a319403821 100644 --- a/src/libs/utils/process_stub_unix.c +++ b/src/libs/utils/process_stub_unix.c @@ -73,18 +73,19 @@ enum { ArgSocket, ArgMsg, ArgDir, - ArgEnv + ArgEnv, + ArgExe }; -/* syntax: $0 {"run"|"debug"} "" */ +/* syntax: $0 {"run"|"debug"} */ /* exit codes: 0 = ok, 1 = invocation error, 3 = internal error */ int main(int argc, char *argv[]) { - int envIdx = ArgEnv; int errNo; int chldPid; int chldStatus; int chldPipe[2]; + char **env = 0; struct sockaddr_un sau; if (argc < ArgEnv) { @@ -111,6 +112,35 @@ int main(int argc, char *argv[]) return 1; } + if (*argv[ArgEnv]) { + FILE *envFd; + char *envdata, *edp; + long size; + int count; + if (!(envFd = fopen(argv[ArgEnv], "r"))) { + fprintf(stderr, "Cannot read creator env file %s: %s\n", + argv[ArgEnv], strerror(errno)); + doExit(1); + } + fseek(envFd, 0, SEEK_END); + size = ftell(envFd); + rewind(envFd); + envdata = malloc(size); + if (fread(envdata, 1, size, envFd) != (size_t)size) { + perror("Failed to read env file"); + doExit(1); + } + fclose(envFd); + for (count = 0, edp = envdata; edp < envdata + size; ++count) + edp += strlen(edp) + 1; + env = malloc((count + 1) * sizeof(char *)); + for (count = 0, edp = envdata; edp < envdata + size; ++count) { + env[count] = edp; + edp += strlen(edp) + 1; + } + env[count] = 0; + } + /* Create execution result notification pipe. */ if (pipe(chldPipe)) { perror("Cannot create status pipe"); @@ -142,14 +172,10 @@ int main(int argc, char *argv[]) ptrace(PT_TRACE_ME, 0, 0, 0); #endif - for (envIdx = ArgEnv; *argv[envIdx]; ++envIdx) ; - if (envIdx != ArgEnv) { - argv[envIdx] = 0; - environ = argv + ArgEnv; - } - ++envIdx; + if (env) + environ = env; - execvp(argv[envIdx], argv + envIdx); + execvp(argv[ArgExe], argv + ArgExe); /* Only expected error: no such file or direcotry, i.e. executable not found */ errNo = errno; write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */ diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index dbfcc44c801..f9b2cde57b2 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -49,6 +49,7 @@ #include +#include #include #include @@ -73,6 +74,7 @@ Q_DECLARE_METATYPE(Core::IEditor*) using namespace Core; using namespace Core::Internal; +using namespace Core::Utils; enum { debugEditorManager=0 }; @@ -429,15 +431,14 @@ void EditorManager::init() QString EditorManager::defaultExternalEditor() const { -#ifdef Q_OS_MAC - return m_d->m_core->resourcePath() - +QLatin1String("/runInTerminal.command vi %f %l %c %W %H %x %y"); -#elif defined(Q_OS_UNIX) - return QLatin1String("xterm -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\""); -#elif defined (Q_OS_WIN) - return QLatin1String("notepad %f"); +#ifdef Q_OS_UNIX + return ConsoleProcess::defaultTerminalEmulator() + QLatin1String( +# ifdef Q_OS_MAC + " -async" +# endif + " -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\""); #else - return QString(); + return QLatin1String("notepad %f"); #endif } @@ -462,7 +463,7 @@ void EditorManager::removeEditor(IEditor *editor) } -void EditorManager::handleContextChange(IContext *context) +void EditorManager::handleContextChange(Core::IContext *context) { if (debugEditorManager) qDebug() << Q_FUNC_INFO; @@ -1172,9 +1173,8 @@ bool EditorManager::saveFile(IEditor *editor) return true; } - if (file->isReadOnly() || fileName.isEmpty()) { + if (file->isReadOnly() || fileName.isEmpty()) return saveFileAs(editor); - } m_d->m_core->fileManager()->blockFileChange(file); const bool success = file->save(fileName); diff --git a/src/plugins/coreplugin/filemanager.cpp b/src/plugins/coreplugin/filemanager.cpp index b996ed50407..a13c72accc3 100644 --- a/src/plugins/coreplugin/filemanager.cpp +++ b/src/plugins/coreplugin/filemanager.cpp @@ -453,7 +453,7 @@ void FileManager::changedFile(const QString &file) foreach (IFile *fileinterface, managedFiles(file)) m_changedFiles << fileinterface; if (wasempty && !m_changedFiles.isEmpty()) { - QTimer::singleShot (200, this, SLOT(checkForReload())); + QTimer::singleShot(200, this, SLOT(checkForReload())); } } diff --git a/src/plugins/coreplugin/generalsettings.cpp b/src/plugins/coreplugin/generalsettings.cpp index 969599b2d8a..ff0f73f3302 100644 --- a/src/plugins/coreplugin/generalsettings.cpp +++ b/src/plugins/coreplugin/generalsettings.cpp @@ -31,11 +31,14 @@ #include "stylehelper.h" #include "utils/qtcolorbutton.h" +#include #include +#include #include #include "ui_generalsettings.h" +using namespace Core::Utils; using namespace Core::Internal; GeneralSettings::GeneralSettings(): @@ -71,6 +74,13 @@ QWidget *GeneralSettings::createPage(QWidget *parent) m_page->colorButton->setColor(StyleHelper::baseColor()); m_page->externalEditorEdit->setText(EditorManager::instance()->externalEditor()); +#ifdef Q_OS_UNIX + m_page->terminalEdit->setText(ConsoleProcess::terminalEmulator(Core::ICore::instance()->settings())); +#else + m_page->terminalLabel->hide(); + m_page->terminalEdit->hide(); + m_page->resetTerminalButton->hide(); +#endif connect(m_page->resetButton, SIGNAL(clicked()), this, SLOT(resetInterfaceColor())); @@ -78,6 +88,10 @@ QWidget *GeneralSettings::createPage(QWidget *parent) this, SLOT(resetExternalEditor())); connect(m_page->helpExternalEditorButton, SIGNAL(clicked()), this, SLOT(showHelpForExternalEditor())); +#ifdef Q_OS_UNIX + connect(m_page->resetTerminalButton, SIGNAL(clicked()), + this, SLOT(resetTerminal())); +#endif return w; } @@ -87,6 +101,10 @@ void GeneralSettings::apply() // Apply the new base color if accepted StyleHelper::setBaseColor(m_page->colorButton->color()); EditorManager::instance()->setExternalEditor(m_page->externalEditorEdit->text()); +#ifdef Q_OS_UNIX + ConsoleProcess::setTerminalEmulator(Core::ICore::instance()->settings(), + m_page->terminalEdit->text()); +#endif } void GeneralSettings::finish() @@ -104,6 +122,13 @@ void GeneralSettings::resetExternalEditor() m_page->externalEditorEdit->setText(EditorManager::instance()->defaultExternalEditor()); } +#ifdef Q_OS_UNIX +void GeneralSettings::resetTerminal() +{ + m_page->terminalEdit->setText(ConsoleProcess::defaultTerminalEmulator() + QLatin1String(" -e")); +} +#endif + void GeneralSettings::showHelpForExternalEditor() { if (m_dialog) { diff --git a/src/plugins/coreplugin/generalsettings.h b/src/plugins/coreplugin/generalsettings.h index 9135df7f4a3..d75cd2d8a39 100644 --- a/src/plugins/coreplugin/generalsettings.h +++ b/src/plugins/coreplugin/generalsettings.h @@ -59,6 +59,9 @@ private slots: void resetInterfaceColor(); void resetExternalEditor(); void showHelpForExternalEditor(); +#ifdef Q_OS_UNIX + void resetTerminal(); +#endif private: Ui_GeneralSettings *m_page; diff --git a/src/plugins/coreplugin/generalsettings.ui b/src/plugins/coreplugin/generalsettings.ui index c014fae607b..826c45ae6bc 100644 --- a/src/plugins/coreplugin/generalsettings.ui +++ b/src/plugins/coreplugin/generalsettings.ui @@ -96,6 +96,34 @@ + + + + + + Terminal: + + + + + + + + + + Reset to default + + + R + + + + :/core/images/reset.png:/core/images/reset.png + + + + + diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 543111816b1..446b7544bb3 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -1070,11 +1070,14 @@ static const char *settingsGroup = "MainWindow"; static const char *geometryKey = "Geometry"; static const char *colorKey = "Color"; static const char *maxKey = "Maximized"; +static const char *fullScreenKey = "FullScreen"; void MainWindow::readSettings() { m_settings->beginGroup(QLatin1String(settingsGroup)); + StyleHelper::setBaseColor(m_settings->value(QLatin1String(colorKey)).value()); + const QVariant geom = m_settings->value(QLatin1String(geometryKey)); if (geom.isValid()) { setGeometry(geom.toRect()); @@ -1083,8 +1086,10 @@ void MainWindow::readSettings() } if (m_settings->value(QLatin1String(maxKey), false).toBool()) setWindowState(Qt::WindowMaximized); + setFullScreen(m_settings->value(QLatin1String(fullScreenKey), false).toBool()); m_settings->endGroup(); + m_editorManager->readSettings(m_settings); m_navigationWidget->restoreSettings(m_settings); m_rightPaneWidget->readSettings(m_settings); @@ -1093,14 +1098,18 @@ void MainWindow::readSettings() void MainWindow::writeSettings() { m_settings->beginGroup(QLatin1String(settingsGroup)); - m_settings->setValue(colorKey, StyleHelper::baseColor()); - const QString maxSettingsKey = QLatin1String(maxKey); - if (windowState() & Qt::WindowMaximized) { - m_settings->setValue(maxSettingsKey, true); + + m_settings->setValue(QLatin1String(colorKey), StyleHelper::baseColor()); + + if (windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen)) { + m_settings->setValue(QLatin1String(maxKey), (bool) (windowState() & Qt::WindowMaximized)); + m_settings->setValue(QLatin1String(fullScreenKey), (bool) (windowState() & Qt::WindowFullScreen)); } else { - m_settings->setValue(maxSettingsKey, false); + m_settings->setValue(QLatin1String(maxKey), false); + m_settings->setValue(QLatin1String(fullScreenKey), false); m_settings->setValue(QLatin1String(geometryKey), geometry()); } + m_settings->endGroup(); m_fileManager->saveRecentFiles(); @@ -1209,7 +1218,7 @@ QPrinter *MainWindow::printer() const { if (!m_printer) m_printer = new QPrinter(QPrinter::HighResolution); - return m_printer; + return m_printer; } void MainWindow::setFullScreen(bool on) diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp index 6ade9b34fde..7a6ff93fbc6 100644 --- a/src/plugins/debugger/debuggeractions.cpp +++ b/src/plugins/debugger/debuggeractions.cpp @@ -250,6 +250,7 @@ DebuggerSettings *DebuggerSettings::instance() // item = new SavedAction(instance); item->setSettingsKey(debugModeGroup, QLatin1String("Location")); + item->setDefaultValue("gdb"); instance->insertItem(GdbLocation, item); item = new SavedAction(instance); @@ -272,11 +273,6 @@ DebuggerSettings *DebuggerSettings::instance() item->setCheckable(true); instance->insertItem(UseToolTips, item); - item = new SavedAction(instance); - item->setDefaultValue(QLatin1String("xterm")); - item->setSettingsKey(debugModeGroup, QLatin1String("Terminal")); - instance->insertItem(TerminalApplication, item); - item = new SavedAction(instance); item->setSettingsKey(debugModeGroup, QLatin1String("ListSourceFiles")); item->setText(tr("List source files")); @@ -291,6 +287,7 @@ DebuggerSettings *DebuggerSettings::instance() item = new SavedAction(instance); item->setSettingsKey(debugModeGroup, QLatin1String("AllPluginBreakpoints")); + item->setDefaultValue(true); instance->insertItem(AllPluginBreakpoints, item); item = new SavedAction(instance); diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h index 6fc9366f7bf..0a43ffa91ee 100644 --- a/src/plugins/debugger/debuggeractions.h +++ b/src/plugins/debugger/debuggeractions.h @@ -77,7 +77,6 @@ enum DebuggerActionCode AdjustColumnWidths, AlwaysAdjustColumnWidths, AutoQuit, - TerminalApplication, LockView, // Gdb diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index c4c517327e7..483ad82a1e6 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -131,7 +131,7 @@ AttachCoreDialog::AttachCoreDialog(QWidget *parent) m_ui->execFileName->setPromptDialogTitle(tr("Select Executable")); m_ui->coreFileName->setExpectedKind(Core::Utils::PathChooser::File); - m_ui->coreFileName->setPromptDialogTitle(tr("Select Executable")); + m_ui->coreFileName->setPromptDialogTitle(tr("Select Core File")); m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 90cb7bd1f79..4d88db88c3a 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -269,8 +269,6 @@ QWidget *GdbOptionPage::createPage(QWidget *parent) m_ui.gdbLocationChooser->setPromptDialogTitle(tr("Choose Gdb Location")); m_ui.scriptFileChooser->setExpectedKind(Core::Utils::PathChooser::File); m_ui.scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script File")); - m_ui.terminalChooser->setExpectedKind(Core::Utils::PathChooser::Command); - m_ui.terminalChooser->setPromptDialogTitle(tr("Choose Location of Terminal Application")); m_group.clear(); m_group.insert(theDebuggerAction(GdbLocation), @@ -279,8 +277,6 @@ QWidget *GdbOptionPage::createPage(QWidget *parent) m_ui.scriptFileChooser); m_group.insert(theDebuggerAction(GdbEnvironment), m_ui.environmentEdit); - m_group.insert(theDebuggerAction(TerminalApplication), - m_ui.terminalChooser); m_group.insert(theDebuggerAction(AllPluginBreakpoints), m_ui.radioButtonAllPluginBreakpoints); diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp index 0279c15181f..0e161f10795 100644 --- a/src/plugins/debugger/gdbengine.cpp +++ b/src/plugins/debugger/gdbengine.cpp @@ -163,6 +163,20 @@ static int ¤tToken() return token; } +static bool isSkippable(int type) +{ + return type == RegisterListValues + && type == StackListThreads + && type == StackListFrames + && type == StackListLocals + && type == StackListArguments + && type == WatchVarAssign + && type == WatchVarListChildren + && type == WatchVarCreate + && type == WatchEvaluateExpression + && type == WatchToolTip; +} + /////////////////////////////////////////////////////////////////////// // // GdbEngine @@ -667,7 +681,7 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) GdbCookie cmd = m_cookieForToken.take(token); - if (record.token < m_oldestAcceptableToken) { + if (record.token < m_oldestAcceptableToken && isSkippable(cmd.type)) { //qDebug() << "### SKIPPING OLD RESULT " << record.toString(); //QMessageBox::information(m_mainWindow, tr("Skipped"), "xxx"); return; @@ -1140,9 +1154,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) + data.findChild("signal-name").toString(); } q->showStatusMessage(msg); - // FIXME: shouldn't this use a statis change? - debugMessage("CALLING PARENT EXITDEBUGGER"); - q->exitDebugger(); + sendCommand("-gdb-exit"); return; } @@ -1857,8 +1869,21 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber) void GdbEngine::setTokenBarrier() { - foreach (const GdbCookie &ck, m_cookieForToken) - QTC_ASSERT(ck.synchronized || ck.type == GdbInvalidCommand, return); + foreach (const GdbCookie &cookie, m_cookieForToken) { + QTC_ASSERT( + cookie.synchronized + || cookie.type == GdbInvalidCommand + // FIXME: use something like "command classes" for these cases: + || cookie.type == GdbInfoProc + || cookie.type == GdbStubAttached + || cookie.type == ModulesList + || cookie.type == WatchDebuggingHelperSetup + || cookie.type == GdbQueryDebuggingHelper, + qDebug() << "CMD: " << cookie.command << "TYPE: " << cookie.type + << "SYNC: " << cookie.synchronized; + return + ); + } PENDING_DEBUG("\n--- token barrier ---\n"); emit gdbInputAvailable(QString(), "--- token barrier ---"); m_oldestAcceptableToken = currentToken(); @@ -1930,7 +1955,10 @@ void GdbEngine::breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt if (pos > 0) { data->bpLineNumber = child.data().mid(pos + 1); data->markerLineNumber = child.data().mid(pos + 1).toInt(); - files.prepend(child.data().left(pos)); + QString file = child.data().left(pos); + if (file.startsWith('"') && file.endsWith('"')) + file = file.mid(1, file.size() - 2); + files.prepend(file); } else { files.prepend(child.data()); } @@ -1978,7 +2006,7 @@ void GdbEngine::sendInsertBreakpoint(int index) // set up fallback in case of pending breakpoints which aren't handled // by the MI interface #ifdef Q_OS_LINUX - QString cmd = "-break-insert "; + QString cmd = "-break-insert -f "; //if (!data->condition.isEmpty()) // cmd += "-c " + data->condition + " "; cmd += where; @@ -2133,6 +2161,8 @@ void GdbEngine::handleBreakInsert(const GdbResultRecord &record, int index) // + data->lineNumber + "\""; QString where = "\"" + data->fileName + "\":" + data->lineNumber; + // Should not happen with -break-insert -f. gdb older than 6.8? + QTC_ASSERT(false, /**/); sendCommand("break " + where, BreakInsert1, index); #endif #ifdef Q_OS_MAC @@ -3054,7 +3084,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren) } else if (outertype == m_namespace + "QMapNode") { extraArgs[2] = sizeofTypeExpression(data.type); extraArgs[3] = "(size_t)&(('" + data.type + "'*)0)->value"; - } else if (outertype == "std::vector") { + } else if (outertype == "std::vector" || outertype == "vector") { //qDebug() << "EXTRACT TEMPLATE: " << outertype << inners; if (inners.at(0) == "bool") { outertype = "std::vector::bool"; @@ -3062,18 +3092,18 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren) //extraArgs[extraArgCount++] = sizeofTypeExpression(data.type); //extraArgs[extraArgCount++] = "(size_t)&(('" + data.type + "'*)0)->value"; } - } else if (outertype == "std::deque") { + } else if (outertype == "std::deque" || outertype == "deque") { // remove 'std::allocator<...>': extraArgs[1] = "0"; - } else if (outertype == "std::stack") { + } else if (outertype == "std::stack" || outertype == "stack") { // remove 'std::allocator<...>': extraArgs[1] = "0"; - } else if (outertype == "std::set") { + } else if (outertype == "std::set" || outertype == "set") { // remove 'std::less<...>': extraArgs[1] = "0"; // remove 'std::allocator<...>': extraArgs[2] = "0"; - } else if (outertype == "std::map") { + } else if (outertype == "std::map" || outertype == "map") { // We don't want the comparator and the allocator confuse gdb. // But we need the offset of the second item in the value pair. // We read the type of the pair from the allocator argument because @@ -3084,7 +3114,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren) pairType = pairType.mid(15, pairType.size() - 15 - 2); extraArgs[2] = "(size_t)&(('" + pairType + "'*)0)->second"; extraArgs[3] = "0"; - } else if (outertype == "std::basic_string") { + } else if (outertype == "std::basic_string" || outertype == "basic_string") { //qDebug() << "EXTRACT TEMPLATE: " << outertype << inners; if (inners.at(0) == "char") { outertype = "std::string"; @@ -4148,10 +4178,10 @@ void GdbEngine::tryLoadDebuggingHelpers() QString flag = QString::number(RTLD_NOW); sendCommand("sharedlibrary libc"); // for malloc sendCommand("sharedlibrary libdl"); // for dlopen - sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")", + sendCommand("call (void*)dlopen(\"" + lib + "\", " + flag + ")", WatchDebuggingHelperSetup); // some older systems like CentOS 4.6 prefer this: - sendCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")", + sendCommand("call (void*)__dlopen(\"" + lib + "\", " + flag + ")", WatchDebuggingHelperSetup); sendCommand("sharedlibrary " + dotEscape(lib)); #endif diff --git a/src/plugins/debugger/gdboptionpage.ui b/src/plugins/debugger/gdboptionpage.ui index c3994e7b8e9..baf91e4667d 100644 --- a/src/plugins/debugger/gdboptionpage.ui +++ b/src/plugins/debugger/gdboptionpage.ui @@ -39,17 +39,6 @@ - - - - This is either a full abolute path leading to the terminal -you indent to use or the name of a terminal that will be searched in your PATH. - - - Terminal: - - - @@ -76,9 +65,6 @@ you indent to use or the name of a terminal that will be searched in your PATH.< - - - diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 9ccfb791d62..42e42f5f0b6 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -66,6 +66,8 @@ using namespace Debugger::Internal; static const QString strNotInScope = QLatin1String(""); +static int watcherCounter = 0; + //////////////////////////////////////////////////////////////////// // // WatchData @@ -356,54 +358,101 @@ WatchHandler::WatchHandler() SIGNAL(triggered()), this, SLOT(collapseChildren())); } +static QString chopConst(QString type) +{ + while (1) { + if (type.startsWith("const")) + type = type.mid(5); + else if (type.startsWith(' ')) + type = type.mid(1); + else if (type.endsWith("const")) + type.chop(5); + else if (type.endsWith(' ')) + type.chop(1); + else + break; + } + return type; +} + static QString niceType(QString type) { if (type.contains(QLatin1String("std::"))) { // std::string - type.replace(QLatin1String("std::basic_string, " - "std::allocator >"), QLatin1String("std::string")); + type.replace(QLatin1String("basic_string, " + "std::allocator >"), QLatin1String("string")); // std::wstring - type.replace(QLatin1String("std::basic_string, " - "std::allocator >"), QLatin1String("std::wstring")); + type.replace(QLatin1String("basic_string, " + "std::allocator >"), QLatin1String("wstring")); // std::vector - static QRegExp re1(QLatin1String("std::vector<(.*), std::allocator<(.*)>\\s*>")); + static QRegExp re1(QLatin1String("vector<(.*), std::allocator<(.*)>\\s*>")); re1.setMinimal(true); for (int i = 0; i != 10; ++i) { if (re1.indexIn(type) == -1 || re1.cap(1) != re1.cap(2)) break; - type.replace(re1.cap(0), QLatin1String("std::vector<") + re1.cap(1) + QLatin1Char('>')); + type.replace(re1.cap(0), QLatin1String("vector<") + re1.cap(1) + QLatin1Char('>')); + } + + // std::deque + static QRegExp re5(QLatin1String("deque<(.*), std::allocator<(.*)>\\s*>")); + re5.setMinimal(true); + for (int i = 0; i != 10; ++i) { + if (re5.indexIn(type) == -1 || re5.cap(1) != re5.cap(2)) + break; + type.replace(re5.cap(0), QLatin1String("deque<") + re5.cap(1) + QLatin1Char('>')); + } + + // std::stack + static QRegExp re6(QLatin1String("stack<(.*), std::deque<(.*), std::allocator<(.*)>\\s*> >")); + re6.setMinimal(true); + for (int i = 0; i != 10; ++i) { + if (re6.indexIn(type) == -1 || re6.cap(1) != re6.cap(2) + || re6.cap(1) != re6.cap(2)) + break; + type.replace(re6.cap(0), QLatin1String("stack<") + re6.cap(1) + QLatin1Char('>')); } // std::list - static QRegExp re2(QLatin1String("std::list<(.*), std::allocator<(.*)>\\s*>")); + static QRegExp re2(QLatin1String("list<(.*), std::allocator<(.*)>\\s*>")); re2.setMinimal(true); for (int i = 0; i != 10; ++i) { if (re2.indexIn(type) == -1 || re2.cap(1) != re2.cap(2)) break; - type.replace(re2.cap(0), QLatin1String("std::list<") + re2.cap(1) + QLatin1Char('>')); + type.replace(re2.cap(0), QLatin1String("list<") + re2.cap(1) + QLatin1Char('>')); } // std::map - static QRegExp re3(QLatin1String("std::map<(.*), (.*), std::less<(.*)\\s*>, " - "std::allocator > >")); - re3.setMinimal(true); - for (int i = 0; i != 10; ++i) { - if (re3.indexIn(type) == -1 || re3.cap(1) != re3.cap(3) - || re3.cap(1) != re3.cap(4) || re3.cap(2) != re3.cap(5)) - break; - type.replace(re3.cap(0), QLatin1String("std::map<") + re3.cap(1) + QLatin1String(", ") + re3.cap(2) + QLatin1Char('>')); + { + static QRegExp re(QLatin1String("map<(.*), (.*), std::less<(.*)>, " + "std::allocator > >")); + re.setMinimal(true); + for (int i = 0; i != 10; ++i) { + if (re.indexIn(type) == -1) + break; + QString key = chopConst(re.cap(1)); + QString value = chopConst(re.cap(2)); + QString key1 = chopConst(re.cap(3)); + QString key2 = chopConst(re.cap(4)); + QString value2 = chopConst(re.cap(5)); + if (value != value2 || key != key1 || key != key2) { + qDebug() << key << key1 << key2 << value << value2 + << (key == key1) << (key == key2) << (value == value2); + break; + } + type.replace(re.cap(0), QString("map<%1, %2>").arg(key).arg(value)); + } } // std::set - static QRegExp re4(QLatin1String("std::set<(.*), std::less<(.*)>, std::allocator<(.*)>\\s*>")); + static QRegExp re4(QLatin1String("set<(.*), std::less<(.*)>, std::allocator<(.*)>\\s*>")); re1.setMinimal(true); for (int i = 0; i != 10; ++i) { if (re4.indexIn(type) == -1 || re4.cap(1) != re4.cap(2) || re4.cap(1) != re4.cap(3)) break; - type.replace(re4.cap(0), QLatin1String("std::set<") + re4.cap(1) + QLatin1Char('>')); + type.replace(re4.cap(0), QLatin1String("set<") + re4.cap(1) + QLatin1Char('>')); } type.replace(QLatin1String(" >"), QString(QLatin1Char('>'))); @@ -875,17 +924,21 @@ void WatchHandler::watchExpression() watchExpression(action->data().toString()); } +QString WatchHandler::watcherName(const QString &exp) +{ + return QLatin1String("watch.") + QString::number(m_watchers[exp]); +} + void WatchHandler::watchExpression(const QString &exp) { // FIXME: 'exp' can contain illegal characters //MODEL_DEBUG("WATCH: " << exp); - static int counter = 0; + m_watchers[exp] = watcherCounter++; WatchData data; data.exp = exp; data.name = exp; - data.iname = QLatin1String("watch.") + QString::number(counter++); + data.iname = watcherName(exp); insertData(data); - m_watchers.append(exp); saveWatchers(); emit watchModelUpdateRequested(); } @@ -970,7 +1023,7 @@ void WatchHandler::removeWatchExpression() void WatchHandler::removeWatchExpression(const QString &exp) { MODEL_DEBUG("REMOVE WATCH: " << exp); - m_watchers.removeOne(exp); + m_watchers.remove(exp); for (int i = m_completeSet.size(); --i >= 0;) { const WatchData & data = m_completeSet.at(i); if (data.iname.startsWith(QLatin1String("watch.")) && data.exp == exp) { @@ -994,8 +1047,9 @@ void WatchHandler::reinitializeWatchersHelper() { // copy over all watchers and mark all watchers as incomplete int i = 0; - foreach (const QString &exp, m_watchers) { + foreach (const QString &exp, m_watchers.keys()) { WatchData data; + data.iname = watcherName(exp); data.level = -1; data.row = -1; data.parentIndex = -1; @@ -1205,15 +1259,16 @@ void WatchHandler::loadWatchers() { QVariant value; sessionValueRequested("Watchers", &value); - m_watchers = value.toStringList(); + foreach (const QString &exp, value.toStringList()) + m_watchers[exp] = watcherCounter++; //qDebug() << "LOAD WATCHERS: " << m_watchers; reinitializeWatchersHelper(); } void WatchHandler::saveWatchers() { - //qDebug() << "SAVE WATCHERS: " << m_watchers; - setSessionValueRequested("Watchers", m_watchers); + //qDebug() << "SAVE WATCHERS: " << m_watchers.keys(); + setSessionValueRequested("Watchers", QVariant(m_watchers.keys())); } void WatchHandler::saveSessionData() diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 3f773ac1df3..13f37dabf49 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -216,7 +216,8 @@ private: QList m_completeSet; QList m_oldSet; QList m_displaySet; - QStringList m_watchers; + QHash m_watchers; + QString watcherName(const QString &exp); void setDisplayedIName(const QString &iname, bool on); QSet m_expandedINames; // those expanded in the treeview diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp index 0b76cfc1de6..cc6e580a8f5 100644 --- a/src/plugins/fakevim/fakevimhandler.cpp +++ b/src/plugins/fakevim/fakevimhandler.cpp @@ -50,6 +50,7 @@ #include + #include #include #include @@ -606,22 +607,28 @@ EventResult FakeVimHandler::Private::handleKey(int key, int unmodified, void FakeVimHandler::Private::moveDown(int n) { - // m_tc.movePosition(Down, MoveAnchor, n); does not work for "hidden" - // documents like in the autotests - const QTextBlock &block = m_tc.block(); - const int col = m_tc.position() - block.position(); - const int line = block.blockNumber(); - const int pos = m_tc.document()->findBlockByNumber(line + n).position(); - setPosition(pos + qMin(block.length(), col)); - setPosition(pos); +#if 0 + // does not work for "hidden" documents like in the autotests + m_tc.movePosition(Down, MoveAnchor, n); +#else + const int col = m_tc.position() - m_tc.block().position(); + const int line = m_tc.block().blockNumber(); + const QTextBlock &block = m_tc.document()->findBlockByNumber(line + n); + const int pos = block.position(); + setPosition(pos + qMin(block.length() - 1, col)); + moveToTargetColumn(); +#endif } void FakeVimHandler::Private::moveToEndOfLine() { - // m_tc.movePosition(EndOfLine, MoveAnchor) does not work for "hidden" - // documents like in the autotests +#if 0 + // does not work for "hidden" documents like in the autotests + m_tc.movePosition(EndOfLine, MoveAnchor); +#else const QTextBlock &block = m_tc.block(); setPosition(block.position() + block.length() - 1); +#endif } void FakeVimHandler::Private::finishMovement(const QString &dotCommand) @@ -1668,7 +1675,6 @@ void FakeVimHandler::Private::selectRange(int beginLine, int endLine) void FakeVimHandler::Private::handleCommand(const QString &cmd) { m_tc = EDITOR(textCursor()); - init(); handleExCommand(cmd); EDITOR(setTextCursor(m_tc)); } @@ -2077,12 +2083,22 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat) void FakeVimHandler::Private::moveToTargetColumn() { - if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn) - m_tc.movePosition(EndOfLine, KeepAnchor); - else + if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn) { + const QTextBlock &block = m_tc.block(); + m_tc.setPosition(block.position() + block.length() - 1, KeepAnchor); + } else { m_tc.setPosition(m_tc.block().position() + m_targetColumn, KeepAnchor); + } } +/* if simple is given: + * class 0: spaces + * class 1: non-spaces + * else + * class 0: spaces + * class 1: non-space-or-letter-or-number + * class 2: letter-or-number + */ static int charClass(QChar c, bool simple) { if (simple) @@ -2100,6 +2116,7 @@ void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward) int lastClass = -1; while (true) { QChar c = doc->characterAt(m_tc.position() + (forward ? 1 : -1)); + qDebug() << "EXAMINING: " << c << " AT " << position(); int thisClass = charClass(c, simple); if (thisClass != lastClass && lastClass != 0) --repeat; @@ -2110,6 +2127,7 @@ void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward) break; forward ? moveRight() : moveLeft(); } + setTargetColumn(); } void FakeVimHandler::Private::handleFfTt(int key) @@ -2145,6 +2163,7 @@ void FakeVimHandler::Private::handleFfTt(int key) break; } } + setTargetColumn(); } void FakeVimHandler::Private::moveToNextWord(bool simple) @@ -2165,6 +2184,7 @@ void FakeVimHandler::Private::moveToNextWord(bool simple) if (m_tc.position() == n) break; } + setTargetColumn(); } void FakeVimHandler::Private::moveToMatchingParanthesis() @@ -2178,6 +2198,7 @@ void FakeVimHandler::Private::moveToMatchingParanthesis() if (m_submode == NoSubMode || m_submode == ZSubMode || m_submode == RegisterSubMode) m_tc.movePosition(Left, KeepAnchor, 1); } + setTargetColumn(); } int FakeVimHandler::Private::cursorLineOnScreen() const diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index 7f4e3eeada7..0ab92d82639 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -543,7 +543,7 @@ void FakeVimPluginPrivate::indentRegion(int *amount, int beginLine, int endLine, void FakeVimPluginPrivate::quitFakeVim() { - setUseFakeVim(false); + theFakeVimSetting(ConfigUseFakeVim)->setValue(false); } void FakeVimPluginPrivate::showCommandBuffer(const QString &contents) diff --git a/src/plugins/projectexplorer/applicationlauncher_x11.cpp b/src/plugins/projectexplorer/applicationlauncher_x11.cpp index b82db98a416..b79c25ff82c 100644 --- a/src/plugins/projectexplorer/applicationlauncher_x11.cpp +++ b/src/plugins/projectexplorer/applicationlauncher_x11.cpp @@ -30,6 +30,8 @@ #include "applicationlauncher.h" #include "consoleprocess.h" +#include + #include using namespace ProjectExplorer::Internal; @@ -52,6 +54,7 @@ ApplicationLauncher::ApplicationLauncher(QObject *parent) this, SLOT(bringToForeground())); m_consoleProcess = new ConsoleProcess(this); + m_consoleProcess->setSettings(Core::ICore::instance()->settings()); connect(m_consoleProcess, SIGNAL(processError(const QString&)), this, SIGNAL(applicationError(const QString&))); connect(m_consoleProcess, SIGNAL(processStopped()), diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 7106ac1383c..3f83f4763e7 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -453,6 +453,7 @@ void Project::addRunConfiguration(QSharedPointer runConfigurat return; } m_runConfigurations.push_back(runConfiguration); + emit addedRunConfiguration(runConfiguration->name()); } void Project::removeRunConfiguration(QSharedPointer runConfiguration) @@ -460,14 +461,19 @@ void Project::removeRunConfiguration(QSharedPointer runConfigu if(!m_runConfigurations.contains(runConfiguration)) { qWarning()<<"Not removing runConfiguration"<name()<<"becasue it doesn't exist"; return; - } - m_runConfigurations.removeOne(runConfiguration); + } + if (m_activeRunConfiguration == runConfiguration) { - if (m_runConfigurations.isEmpty()) + if (m_runConfigurations.size() <= 1) setActiveRunConfiguration(QSharedPointer(0)); + else if (m_runConfigurations.at(0) == m_activeRunConfiguration) + setActiveRunConfiguration(m_runConfigurations.at(1)); else setActiveRunConfiguration(m_runConfigurations.at(0)); } + + m_runConfigurations.removeOne(runConfiguration); + emit removedRunConfiguration(runConfiguration->name()); } QSharedPointer Project::activeRunConfiguration() const diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index fc8b9960a6b..bfe5872e781 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -140,6 +140,8 @@ signals: void fileListChanged(); void activeBuildConfigurationChanged(); void activeRunConfigurationChanged(); + void removedRunConfiguration(const QString &name); + void addedRunConfiguration(const QString &name); // This signal is jut there for updating the tree list in the buildsettings wizard void buildConfigurationDisplayNameChanged(const QString &buildConfiguraiton); diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp index bf4c5646376..b8c42716872 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp @@ -189,6 +189,15 @@ RunSettingsWidget::RunSettingsWidget(Project *project) connect(m_ui->removeToolButton, SIGNAL(clicked(bool)), this, SLOT(removeRunConfiguration())); + connect(m_project, SIGNAL(removedRunConfiguration(QString)), + this, SLOT(initRunConfigurationComboBox())); + + connect(m_project, SIGNAL(addedRunConfiguration(QString)), + this, SLOT(initRunConfigurationComboBox())); + + connect(m_project, SIGNAL(activeRunConfigurationChanged()), + this, SLOT(activeRunConfigurationChanged())); + initRunConfigurationComboBox(); const QList > runConfigurations = m_project->runConfigurations(); for (int i=0; igroupBox->layout()->addWidget(m_runConfigurationWidget); } +void RunSettingsWidget::activeRunConfigurationChanged() +{ + QSharedPointer active = m_project->activeRunConfiguration(); + delete m_runConfigurationWidget; + m_runConfigurationWidget = active->configurationWidget(); + m_ui->groupBox->layout()->addWidget(m_runConfigurationWidget); +} + void RunSettingsWidget::nameChanged() { RunConfiguration *rc = qobject_cast(sender()); diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.h b/src/plugins/projectexplorer/runsettingspropertiespage.h index 9caab4e4ac2..1412ad71271 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.h +++ b/src/plugins/projectexplorer/runsettingspropertiespage.h @@ -77,9 +77,9 @@ private slots: void addRunConfiguration(); void removeRunConfiguration(); void nameChanged(); - -private: void initRunConfigurationComboBox(); + void activeRunConfigurationChanged(); +private: Project *m_project; RunConfigurationsModel *m_runConfigurationsModel; Ui::RunSettingsPropertiesPage *m_ui; diff --git a/src/plugins/qt4projectmanager/showbuildlog.ui b/src/plugins/qt4projectmanager/showbuildlog.ui index 98c61b360e7..5b31a76861c 100644 --- a/src/plugins/qt4projectmanager/showbuildlog.ui +++ b/src/plugins/qt4projectmanager/showbuildlog.ui @@ -11,7 +11,7 @@ - Dialog + Debugging Helper Build Log diff --git a/src/plugins/texteditor/basetextdocument.cpp b/src/plugins/texteditor/basetextdocument.cpp old mode 100644 new mode 100755 index 07f0ce46260..665dd5617aa --- a/src/plugins/texteditor/basetextdocument.cpp +++ b/src/plugins/texteditor/basetextdocument.cpp @@ -47,6 +47,12 @@ using namespace TextEditor; +#if defined (Q_OS_WIN) +QT_BEGIN_NAMESPACE +extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; +QT_END_NAMESPACE +#endif + #if defined (Q_OS_WIN) # define NATIVE_LINE_TERMINATOR CRLFLineTerminator #else @@ -140,8 +146,20 @@ bool BaseTextDocument::isReadOnly() const return true; if (m_fileName.isEmpty()) //have no corresponding file, so editing is ok return false; + const QFileInfo fi(m_fileName); - return !fi.isWritable(); + +#ifdef Q_OS_WIN + // Check for permissions on NTFS file systems + qt_ntfs_permission_lookup++; +#endif + + const bool ro = !fi.isWritable(); + +#ifdef Q_OS_WIN + qt_ntfs_permission_lookup--; +#endif + return ro; } bool BaseTextDocument::isModified() const @@ -157,19 +175,9 @@ bool BaseTextDocument::open(const QString &fileName) m_fileName = fi.absoluteFilePath(); QFile file(fileName); - if (!file.exists()) + if (!file.open(QIODevice::ReadOnly)) return false; - if (!fi.isReadable()) - return false; - - if (!fi.isWritable()) { - if (!file.open(QIODevice::ReadOnly)) - return false; - } else { - if (!file.open(QIODevice::ReadWrite)) - return false; - } title = fi.fileName(); QByteArray buf = file.readAll(); diff --git a/src/shared/help/helpviewer.cpp b/src/shared/help/helpviewer.cpp index 5aaf78ee9af..89a13358352 100644 --- a/src/shared/help/helpviewer.cpp +++ b/src/shared/help/helpviewer.cpp @@ -213,9 +213,8 @@ HelpViewer::HelpViewer(QHelpEngine *engine, CentralWidget *parent) : QWebView(parent), helpEngine(engine), parentWidget(parent) { setPage(new HelpPage(parent, helpEngine, this)); - // Enable JavaScript and Plugins for embedded videos - settings()->setAttribute(QWebSettings::PluginsEnabled, true); - settings()->setAttribute(QWebSettings::JavaEnabled, true); + settings()->setAttribute(QWebSettings::PluginsEnabled, false); + settings()->setAttribute(QWebSettings::JavaEnabled, false); page()->setNetworkAccessManager(new HelpNetworkAccessManager(engine, this)); diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 19041d7bb77..1313f7c0306 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -151,6 +151,8 @@ public: QString m_pendingComment; bool m_syntaxError; bool m_contNextLine; + bool m_inQuote; + int m_parens; /////////////// Evaluating pro file contents @@ -251,6 +253,8 @@ bool ProFileEvaluator::Private::read(ProFile *pro) // Parser state m_block = 0; m_commentItem = 0; + m_inQuote = false; + m_parens = 0; m_contNextLine = false; m_syntaxError = false; m_lineNo = 1; @@ -274,71 +278,83 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0) if (m_blockstack.isEmpty()) return false; - ushort quote = 0; - int parens = 0; - bool contNextLine = false; + int parens = m_parens; + bool inQuote = m_inQuote; + bool escaped = false; QString line = line0.simplified(); for (int i = 0; !m_syntaxError && i < line.length(); ++i) { ushort c = line.at(i).unicode(); - if (quote && c == quote) - quote = 0; - else if (c == '(') - ++parens; - else if (c == ')') - --parens; - else if (c == '"' && (i == 0 || line.at(i - 1).unicode() != '\\')) - quote = c; - else if (!parens && !quote) { - if (c == '#') { - insertComment(line.mid(i + 1)); - contNextLine = m_contNextLine; - break; - } - if (c == '\\' && i >= line.count() - 1) { - updateItem(); - contNextLine = true; + if (c == '#') { // Yep - no escaping possible + insertComment(line.mid(i + 1)); + escaped = m_contNextLine; + break; + } + if (!escaped) { + if (c == '\\') { + escaped = true; + m_proitem += c; + continue; + } else if (c == '"') { + inQuote = !inQuote; + m_proitem += c; continue; } - if (m_block && (m_block->blockKind() & ProBlock::VariableKind)) { - if (c == ' ') - updateItem(); - else - m_proitem += c; - continue; - } - if (c == ':') { - enterScope(false); - continue; - } - if (c == '{') { - enterScope(true); - continue; - } - if (c == '}') { - leaveScope(); - continue; - } - if (c == '=') { - insertVariable(line, &i); - continue; - } - if (c == '|' || c == '!') { - insertOperator(c); - continue; + } else { + escaped = false; + } + if (!inQuote) { + if (c == '(') { + ++parens; + } else if (c == ')') { + --parens; + } else if (!parens) { + if (m_block && (m_block->blockKind() & ProBlock::VariableKind)) { + if (c == ' ') + updateItem(); + else + m_proitem += c; + continue; + } + if (c == ':') { + enterScope(false); + continue; + } + if (c == '{') { + enterScope(true); + continue; + } + if (c == '}') { + leaveScope(); + continue; + } + if (c == '=') { + insertVariable(line, &i); + continue; + } + if (c == '|' || c == '!') { + insertOperator(c); + continue; + } } } m_proitem += c; } - m_contNextLine = contNextLine; - - if (!m_syntaxError) { - updateItem(); - if (!m_contNextLine) - finalizeBlock(); + m_inQuote = inQuote; + m_parens = parens; + m_contNextLine = escaped; + if (escaped) { + m_proitem.chop(1); + return true; + } else { + if (!m_syntaxError) { + updateItem(); + if (!m_contNextLine) + finalizeBlock(); + } + return !m_syntaxError; } - return !m_syntaxError; } void ProFileEvaluator::Private::finalizeBlock() @@ -357,6 +373,9 @@ void ProFileEvaluator::Private::insertVariable(const QString &line, int *i) { ProVariable::VariableOperator opkind; + if (m_proitem.isEmpty()) // Line starting with '=', like a conflict marker + return; + switch (m_proitem.at(m_proitem.length() - 1).unicode()) { case '+': m_proitem.chop(1); @@ -636,11 +655,11 @@ bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro) evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok); evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"), &ok); - QStringList tmp = m_valuemap.value("CONFIG"); + QStringList tmp = m_valuemap.value(QLatin1String("CONFIG")); tmp.append(m_addUserConfigCmdArgs); foreach(const QString &remove, m_removeUserConfigCmdArgs) tmp.removeAll(remove); - m_valuemap.insert("CONFIG", tmp); + m_valuemap.insert(QLatin1String("CONFIG"), tmp); m_cumulative = cumulative; } @@ -2021,7 +2040,13 @@ ProFile *ProFileEvaluator::parsedProFile(const QString &fileName) { QFileInfo fi(fileName); if (fi.exists()) { - ProFile *pro = new ProFile(fi.absoluteFilePath()); + QString fn = QDir::cleanPath(fi.absoluteFilePath()); + foreach (const ProFile *pf, d->m_profileStack) + if (pf->fileName() == fn) { + errorMessage(d->format("circular inclusion of %1").arg(fn)); + return 0; + } + ProFile *pro = new ProFile(fn); if (d->read(pro)) return pro; delete pro; diff --git a/tests/auto/debugger/main.cpp b/tests/auto/debugger/main.cpp index f59a54a6790..13ece24e546 100644 --- a/tests/auto/debugger/main.cpp +++ b/tests/auto/debugger/main.cpp @@ -142,6 +142,7 @@ int main(int argc, char *argv[]) if (args.size() == 2 && args.at(1) == "--run-debuggee") { runDebuggee(); + app.exec(); return 0; } diff --git a/tests/auto/fakevim/main.cpp b/tests/auto/fakevim/main.cpp index b82f1a13bcb..a1ac3be7826 100644 --- a/tests/auto/fakevim/main.cpp +++ b/tests/auto/fakevim/main.cpp @@ -30,6 +30,8 @@ #include "fakevimhandler.h" #include + +#include #include #include @@ -37,13 +39,15 @@ using namespace FakeVim; using namespace FakeVim::Internal; +#define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s) class tst_FakeVim : public QObject { Q_OBJECT public: - tst_FakeVim(); + tst_FakeVim(bool); + ~tst_FakeVim(); public slots: void changeStatusData(const QString &info) { m_statusData = info; } @@ -51,14 +55,17 @@ public slots: void changeExtraInformation(const QString &info) { m_infoMessage = info; } private slots: - void commandI(); void commandDollar(); void commandDown(); + void commandLeft(); + void commandRight(); + void commandI(); void commandUp(); + void commandW(); private: void setup(); - void send(const QString &command); // send a normal command + void send(const QString &command) { sendEx("normal " + command); } void sendEx(const QString &command); // send an ex command bool checkContentsHelper(QString expected, const char* file, int line); @@ -66,8 +73,9 @@ private: const char* file, int line); QString insertCursor(const QString &needle0); - QPlainTextEdit m_editor; - FakeVimHandler m_handler; + QTextEdit *m_textedit; + QPlainTextEdit *m_plaintextedit; + FakeVimHandler *m_handler; QList m_selection; QString m_statusMessage; @@ -79,6 +87,8 @@ private: }; const QString tst_FakeVim::lines = + /* 0 1 2 3 4 */ + /* 0123456789012345678901234567890123457890 */ "\n" "#include \n" "#include \n" @@ -92,46 +102,70 @@ const QString tst_FakeVim::lines = const QString tst_FakeVim::escape = QChar(27); -tst_FakeVim::tst_FakeVim() - : m_handler(&m_editor, this) +tst_FakeVim::tst_FakeVim(bool usePlainTextEdit) { - QObject::connect(&m_handler, SIGNAL(commandBufferChanged(QString)), - this, SLOT(changeStatusMessage(QString))); - QObject::connect(&m_handler, SIGNAL(extraInformationChanged(QString)), - this, SLOT(changeExtraInformation(QString))); - QObject::connect(&m_handler, SIGNAL(statusDataChanged(QString)), - this, SLOT(changeStatusData(QString))); + if (usePlainTextEdit) { + m_textedit = 0; + m_plaintextedit = new QPlainTextEdit; + } else { + m_textedit = new QTextEdit; + m_plaintextedit = 0; + } + m_handler = 0; +} + +tst_FakeVim::~tst_FakeVim() +{ + delete m_handler; + delete m_textedit; + delete m_plaintextedit; } void tst_FakeVim::setup() { + delete m_handler; + m_handler = 0; m_statusMessage.clear(); m_statusData.clear(); m_infoMessage.clear(); - m_editor.setPlainText(lines); - QTextCursor tc = m_editor.textCursor(); - tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - m_editor.setTextCursor(tc); - m_editor.setPlainText(lines); - //m_editor.show(); - //qApp->exec(); - QCOMPARE(m_editor.toPlainText(), lines); -} + if (m_textedit) { + m_textedit->setPlainText(lines); + QTextCursor tc = m_textedit->textCursor(); + tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + m_textedit->setTextCursor(tc); + m_textedit->setPlainText(lines); + m_handler = new FakeVimHandler(m_textedit); + } else { + m_plaintextedit->setPlainText(lines); + QTextCursor tc = m_plaintextedit->textCursor(); + tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + m_plaintextedit->setTextCursor(tc); + m_plaintextedit->setPlainText(lines); + m_handler = new FakeVimHandler(m_plaintextedit); + } -void tst_FakeVim::send(const QString &command) -{ - m_handler.handleCommand("normal " + command); + QObject::connect(m_handler, SIGNAL(commandBufferChanged(QString)), + this, SLOT(changeStatusMessage(QString))); + QObject::connect(m_handler, SIGNAL(extraInformationChanged(QString)), + this, SLOT(changeExtraInformation(QString))); + QObject::connect(m_handler, SIGNAL(statusDataChanged(QString)), + this, SLOT(changeStatusData(QString))); + + QCOMPARE(EDITOR(toPlainText()), lines); } void tst_FakeVim::sendEx(const QString &command) { - m_handler.handleCommand(command); + if (m_handler) + m_handler->handleCommand(command); + else + qDebug() << "NO HANDLER YET"; } bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line) { - QString got = m_editor.toPlainText(); - int pos = m_editor.textCursor().position(); + QString got = EDITOR(toPlainText()); + int pos = EDITOR(textCursor().position()); got = got.left(pos) + "@" + got.mid(pos); QStringList wantlist = want.split('\n'); QStringList gotlist = got.split('\n'); @@ -172,6 +206,10 @@ bool tst_FakeVim::checkHelper(bool ex, QString cmd, QString expected, do { if (!checkHelper(false, cmd, expected, __FILE__, __LINE__)) \ return; } while (0) +#define move(cmd, expected) \ + do { if (!checkHelper(false, cmd, insertCursor(expected), __FILE__, __LINE__)) \ + return; } while (0) + // Runs an ex command and checks the result. // Cursor position is marked by a '@' in the expected contents. #define checkEx(cmd, expected) \ @@ -183,14 +221,13 @@ QString tst_FakeVim::insertCursor(const QString &needle0) QString needle = needle0; needle.remove('@'); QString lines0 = lines; - lines0.replace(needle, needle0); - //qDebug() << "LINES: " << lines0; + int pos = lines0.indexOf(needle); + lines0.replace(pos, needle.size(), needle0); return lines0; } void tst_FakeVim::commandI() { - return; setup(); // empty insertion at start of document @@ -205,6 +242,8 @@ void tst_FakeVim::commandI() check("ixxx" + escape, "xx@x" + lines); check("u", "@" + lines); +return; + // combine insertions check("ia" + escape, "@a" + lines); check("ibx" + escape, "b@xa" + lines); @@ -219,28 +258,86 @@ void tst_FakeVim::commandI() void tst_FakeVim::commandDollar() { setup(); - check("j$", insertCursor("@")); - //check("j", insertCursor("@")); + move("j$", "@"); + move("j$", "@"); + move("2j", ")@"); } void tst_FakeVim::commandDown() { setup(); - check("j", insertCursor("@#include +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + return app.exec(); +} +*/ + +int main(int argc, char *argv[]) \ +{ + int res = 0; + QApplication app(argc, argv); \ + + // Test with QPlainTextEdit. + tst_FakeVim plaintextedit(true); + res += QTest::qExec(&plaintextedit, argc, argv); + +#if 0 + // Test with QTextEdit, too. + tst_FakeVim textedit(false); + res += QTest::qExec(&textedit, argc, argv); +#endif + + return res; +} -QTEST_MAIN(tst_FakeVim) #include "main.moc" diff --git a/tests/manual/gdbdebugger/simple/plugin.cpp b/tests/manual/gdbdebugger/simple/plugin.cpp index df4c6c00ac6..2942ab3c7da 100644 --- a/tests/manual/gdbdebugger/simple/plugin.cpp +++ b/tests/manual/gdbdebugger/simple/plugin.cpp @@ -30,6 +30,7 @@ #include #include + extern "C" Q_DECL_EXPORT int pluginTest() { int s = 0;