Merge branch '1.1'

Conflicts:
	src/plugins/debugger/debuggeractions.cpp

Reviewed-by: hjk
This commit is contained in:
Thorbjørn Lindeijer
2009-04-16 11:20:52 +02:00
36 changed files with 716 additions and 287 deletions

1
.gitignore vendored
View File

@@ -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

6
dist/changes-1.1.0 vendored
View File

@@ -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.

View File

@@ -43,21 +43,6 @@
\endlist
\endtable
\raw HTML
<center>
<object width="425" height="344">
<param name="movie"
value="http://www.youtube.com/v/U7yje3D1UM4&hl=en&fs=1"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/U7yje3D1UM4&hl=en&fs=1"
type="application/x-shockwave-flash" allowscriptaccess="always"
allowfullscreen="true" width="425" height="344">
</embed>
</object>
</center>
\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
<center>
<object width="480" height="295">
<param name="movie"
value="http://www.youtube.com/v/6WGCxLIjRNg&hl=en&fs=1">
</param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube.com/v/6WGCxLIjRNg&hl=en&fs=1"
type="application/x-shockwave-flash" allowscriptaccess="always"
allowfullscreen="true" width="480" height="295">
</embed>
</object>
</center>
\endraw
Qt Creator provides various keyboard shortcuts to aid in the development
process. These shortcuts are listed in the table below:

View File

@@ -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;
}

View File

@@ -1,11 +1,50 @@
#!/bin/bash
osascript >/dev/null 2>&1 <<EOF
#! /bin/bash
### FIXME:
# - currentTab and geometry stuff does not work with macX 10.4 (tiger)
# - -async is always in effect, i.e., synchronous execution is not implemented
geom=
async=
while test -n "$1"; do
case $1 in
-async)
async=1
shift;;
-geom)
shift
w=${1%%x*}
y=${1#*x}
h=${y%%+*}
y=${y#*+}
x=${y%%+*}
y=${y#*+}
geom="\
set number of columns of currentTab to $w
set number of rows of currentTab to $h
set position of windows whose tabs contains currentTab to {$x, $y}"
shift;;
-e)
shift
break;;
*)
echo "Invalid call" >&2
exit 1;;
esac
done
args=
for i in "$@"; do
i=${i//\\/\\\\\\\\}
i=${i//\"/\\\\\\\"}
i=${i//\$/\\\\\\\$}
i=${i//\`/\\\\\\\`}
args="$args \\\"$i\\\""
done
osascript <<EOF
tell application "Terminal"
do script "$1 $2 +$3 +\"normal $4|\"; exit"
do script "$args; exit"
set currentTab to the result
set number of columns of currentTab to $5
set number of rows of currentTab to $6
set position of windows whose tabs contains currentTab to {$7, $8}
$geom
activate
end tell
EOF

View File

@@ -43,10 +43,14 @@
#include <windows.h>
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
};

View File

@@ -30,6 +30,8 @@
#include "consoleprocess.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtCore/QTemporaryFile>
#include <QtNetwork/QLocalSocket>
@@ -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 <RETURN> 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);
}

View File

@@ -73,18 +73,19 @@ enum {
ArgSocket,
ArgMsg,
ArgDir,
ArgEnv
ArgEnv,
ArgExe
};
/* syntax: $0 {"run"|"debug"} <pid-socket> <continuation-msg> <workdir> <env...> "" <exe> <args...> */
/* syntax: $0 {"run"|"debug"} <pid-socket> <continuation-msg> <workdir> <env-file> <exe> <args...> */
/* 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 */

View File

@@ -49,6 +49,7 @@
#include <extensionsystem/pluginmanager.h>
#include <utils/consoleprocess.h>
#include <utils/qtcassert.h>
#include <QtCore/QDebug>
@@ -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);

View File

@@ -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()));
}
}

View File

@@ -31,11 +31,14 @@
#include "stylehelper.h"
#include "utils/qtcolorbutton.h"
#include <utils/consoleprocess.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <QtGui/QMessageBox>
#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) {

View File

@@ -59,6 +59,9 @@ private slots:
void resetInterfaceColor();
void resetExternalEditor();
void showHelpForExternalEditor();
#ifdef Q_OS_UNIX
void resetTerminal();
#endif
private:
Ui_GeneralSettings *m_page;

View File

@@ -96,6 +96,34 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="terminalLabel">
<property name="text">
<string>Terminal:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="terminalEdit"/>
</item>
<item>
<widget class="QToolButton" name="resetTerminalButton">
<property name="toolTip">
<string>Reset to default</string>
</property>
<property name="text">
<string>R</string>
</property>
<property name="icon">
<iconset resource="core.qrc">
<normaloff>:/core/images/reset.png</normaloff>:/core/images/reset.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>

View File

@@ -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<QColor>());
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)

View File

@@ -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);

View File

@@ -77,7 +77,6 @@ enum DebuggerActionCode
AdjustColumnWidths,
AlwaysAdjustColumnWidths,
AutoQuit,
TerminalApplication,
LockView,
// Gdb

View File

@@ -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);

View File

@@ -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);

View File

@@ -163,6 +163,20 @@ static int &currentToken()
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

View File

@@ -39,17 +39,6 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="terminalLocation">
<property name="toolTip">
<string>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.</string>
</property>
<property name="text">
<string>Terminal:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelEnvironment">
<property name="text">
@@ -76,9 +65,6 @@ you indent to use or the name of a terminal that will be searched in your PATH.<
<item row="0" column="1">
<widget class="Core::Utils::PathChooser" name="gdbLocationChooser" native="true"/>
</item>
<item row="3" column="1">
<widget class="Core::Utils::PathChooser" name="terminalChooser" native="true"/>
</item>
</layout>
</widget>
</item>

View File

@@ -66,6 +66,8 @@ using namespace Debugger::Internal;
static const QString strNotInScope = QLatin1String("<not in scope>");
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<char, std::char_traits<char>, "
"std::allocator<char> >"), QLatin1String("std::string"));
type.replace(QLatin1String("basic_string<char, std::char_traits<char>, "
"std::allocator<char> >"), QLatin1String("string"));
// std::wstring
type.replace(QLatin1String("std::basic_string<wchar_t, std::char_traits<wchar_t>, "
"std::allocator<wchar_t> >"), QLatin1String("std::wstring"));
type.replace(QLatin1String("basic_string<wchar_t, std::char_traits<wchar_t>, "
"std::allocator<wchar_t> >"), 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<std::pair<const (.*), (.*)\\s*> > >"));
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<std::pair<(.*), (.*)> > >"));
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()

View File

@@ -216,7 +216,8 @@ private:
QList<WatchData> m_completeSet;
QList<WatchData> m_oldSet;
QList<WatchData> m_displaySet;
QStringList m_watchers;
QHash<QString, int> m_watchers;
QString watcherName(const QString &exp);
void setDisplayedIName(const QString &iname, bool on);
QSet<QString> m_expandedINames; // those expanded in the treeview

View File

@@ -50,6 +50,7 @@
#include <utils/qtcassert.h>
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QObject>
@@ -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

View File

@@ -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)

View File

@@ -30,6 +30,8 @@
#include "applicationlauncher.h"
#include "consoleprocess.h"
#include <coreplugin/icore.h>
#include <QtCore/QTimer>
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()),

View File

@@ -453,6 +453,7 @@ void Project::addRunConfiguration(QSharedPointer<RunConfiguration> runConfigurat
return;
}
m_runConfigurations.push_back(runConfiguration);
emit addedRunConfiguration(runConfiguration->name());
}
void Project::removeRunConfiguration(QSharedPointer<RunConfiguration> runConfiguration)
@@ -460,14 +461,19 @@ void Project::removeRunConfiguration(QSharedPointer<RunConfiguration> runConfigu
if(!m_runConfigurations.contains(runConfiguration)) {
qWarning()<<"Not removing runConfiguration"<<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<RunConfiguration>(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<RunConfiguration> Project::activeRunConfiguration() const

View File

@@ -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);

View File

@@ -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<QSharedPointer<RunConfiguration> > runConfigurations = m_project->runConfigurations();
for (int i=0; i<runConfigurations.size(); ++i) {
@@ -285,6 +294,14 @@ void RunSettingsWidget::activateRunConfiguration(int index)
m_ui->groupBox->layout()->addWidget(m_runConfigurationWidget);
}
void RunSettingsWidget::activeRunConfigurationChanged()
{
QSharedPointer<RunConfiguration> 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<RunConfiguration *>(sender());

View File

@@ -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;

View File

@@ -11,7 +11,7 @@
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>Debugging Helper Build Log</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>

32
src/plugins/texteditor/basetextdocument.cpp Normal file → Executable file
View File

@@ -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();

View File

@@ -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));

View File

@@ -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;

View File

@@ -142,6 +142,7 @@ int main(int argc, char *argv[])
if (args.size() == 2 && args.at(1) == "--run-debuggee") {
runDebuggee();
app.exec();
return 0;
}

View File

@@ -30,6 +30,8 @@
#include "fakevimhandler.h"
#include <QtCore/QSet>
#include <QtGui/QTextEdit>
#include <QtGui/QPlainTextEdit>
#include <QtTest/QtTest>
@@ -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<QTextEdit::ExtraSelection> m_selection;
QString m_statusMessage;
@@ -79,6 +87,8 @@ private:
};
const QString tst_FakeVim::lines =
/* 0 1 2 3 4 */
/* 0123456789012345678901234567890123457890 */
"\n"
"#include <QtCore>\n"
"#include <QtGui>\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("<QtCore>@"));
//check("j", insertCursor("<QtGui>@"));
move("j$", "<QtCore>@");
move("j$", "<QtGui>@");
move("2j", ")@");
}
void tst_FakeVim::commandDown()
{
setup();
check("j", insertCursor("@#include <QtCore"));
check("3j", insertCursor("@int main"));
check("4j", insertCursor("@ return app.exec()"));
move("j", "@#include <QtCore");
move("3j", "@int main");
move("4j", "@ return app.exec()");
}
void tst_FakeVim::commandUp()
{
setup();
check("j", insertCursor("@#include <QtCore"));
check("3j", insertCursor("@int main"));
check("4j", insertCursor("@ return app.exec()"));
move("j", "@#include <QtCore");
move("3j", "@int main");
move("4j", "@ return app.exec()");
}
void tst_FakeVim::commandRight()
{
setup();
move("4j", "@int main");
move("l", "i@nt main");
move("3l", "int @main");
move("50l", "argv[])@");
}
void tst_FakeVim::commandLeft()
{
setup();
move("4j", "@int main");
move("h", "@int main"); // no move over left border
move("$", "argv[])@");
move("h", "argv[]@)");
move("3h", "arg@v[])");
move("50h", "@int main");
}
void tst_FakeVim::commandW()
{
setup();
move("w", "@#include <QtCore");
move("w", "#@include <QtCore");
move("w", "#include @<QtCore");
move("3w", "@#include <QtGui");
}
/*
#include <QtCore>
#include <QtGui>
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"

View File

@@ -30,6 +30,7 @@
#include <stdio.h>
#include <qglobal.h>
extern "C" Q_DECL_EXPORT int pluginTest()
{
int s = 0;