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/*.dll
bin/qtcreator.bin bin/qtcreator.bin
bin/qtcreator_process_stub
bin/qtcreator.exe bin/qtcreator.exe
doc/qtcreator.qch doc/qtcreator.qch
tests/manual/cplusplus/cplusplus0 tests/manual/cplusplus/cplusplus0

6
dist/changes-1.1.0 vendored
View File

@@ -18,9 +18,6 @@ Editing
* Improved function argument hint. * Improved function argument hint.
* More checkpoints in editor history. * More checkpoints in editor history.
* Ctrl-click for jumping to a symbol definition. * 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). * Improved open documents view (sorted, single-click, close buttons).
* Copying text from the context help browser and output windows didn't work. * Copying text from the context help browser and output windows didn't work.
@@ -36,7 +33,7 @@ Debugging
no dumper buildstep anymore. no dumper buildstep anymore.
* New dumper for std::set. Improved QString, QVariant, std::wstring * New dumper for std::set. Improved QString, QVariant, std::wstring
* Make strategy to load shared objects configurable (auto-solib-add). * 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. * Improved interaction in the Locals&Watchers view.
Wizards Wizards
@@ -48,6 +45,7 @@ Wizards
Designer Designer
* Added signal/slot editor. * Added signal/slot editor.
* Fixed "Goto slot" (formatting/multiple inheritance). * Fixed "Goto slot" (formatting/multiple inheritance).
* Context help for form editor widgets.
Version control plugins Version control plugins
* Fixed handling of colored git output. * Fixed handling of colored git output.

View File

@@ -43,21 +43,6 @@
\endlist \endlist
\endtable \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: To learn more about the Qt Creator, click on one of the links below:
\list \list
@@ -1438,23 +1423,6 @@
\title Keyboard Shortcuts \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 Qt Creator provides various keyboard shortcuts to aid in the development
process. These shortcuts are listed in the table below: process. These shortcuts are listed in the table below:

View File

@@ -202,11 +202,12 @@ QT_END_NAMESPACE
#endif // PRIVATE_OBJECT_ALLOWED #endif // PRIVATE_OBJECT_ALLOWED
// this can be mangled typenames of nested templates, each char-by-char // This can be mangled typenames of nested templates, each char-by-char
// comma-separated integer list // comma-separated integer list...
static char qDumpInBuffer[10000]; Q_DECL_EXPORT char qDumpInBuffer[10000];
static char qDumpOutBuffer[100000];
//static char qDumpSize[20]; // The output buffer.
Q_DECL_EXPORT char qDumpOutBuffer[100000];
namespace { namespace {
@@ -2396,6 +2397,10 @@ static void handleProtocolVersion2and3(QDumper & d)
const char *type = stripNamespace(d.outertype); const char *type = stripNamespace(d.outertype);
// type[0] is usally 'Q', so don't use it // type[0] is usally 'Q', so don't use it
switch (type[1]) { switch (type[1]) {
case 'a':
if (isEqual(type, "map"))
qDumpStdMap(d);
break;
case 'B': case 'B':
if (isEqual(type, "QByteArray")) if (isEqual(type, "QByteArray"))
qDumpQByteArray(d); qDumpQByteArray(d);
@@ -2406,6 +2411,12 @@ static void handleProtocolVersion2and3(QDumper & d)
else if (isEqual(type, "QDir")) else if (isEqual(type, "QDir"))
qDumpQDir(d); qDumpQDir(d);
break; break;
case 'e':
if (isEqual(type, "vector"))
qDumpStdVector(d);
else if (isEqual(type, "set"))
qDumpStdSet(d);
break;
case 'F': case 'F':
if (isEqual(type, "QFile")) if (isEqual(type, "QFile"))
qDumpQFile(d); qDumpQFile(d);
@@ -2418,6 +2429,10 @@ static void handleProtocolVersion2and3(QDumper & d)
else if (isEqual(type, "QHashNode")) else if (isEqual(type, "QHashNode"))
qDumpQHashNode(d); qDumpQHashNode(d);
break; break;
case 'i':
if (isEqual(type, "list"))
qDumpStdList(d);
break;
case 'I': case 'I':
if (isEqual(type, "QImage")) if (isEqual(type, "QImage"))
qDumpQImage(d); qDumpQImage(d);
@@ -2510,7 +2525,7 @@ static void handleProtocolVersion2and3(QDumper & d)
extern "C" Q_DECL_EXPORT extern "C" Q_DECL_EXPORT
void qDumpObjectData440( void *qDumpObjectData440(
int protocolVersion, int protocolVersion,
int token, int token,
void *data, void *data,
@@ -2565,8 +2580,15 @@ void qDumpObjectData440(
"\""NS"QVariant\"," "\""NS"QVariant\","
"\""NS"QVector\"," "\""NS"QVector\","
"\""NS"QWidget\"," "\""NS"QWidget\","
#ifdef Q_OS_WIN
"\"basic_string\","
"\"list\","
"\"map\","
"\"set\","
"\"string\"," "\"string\","
"\"vector\","
"\"wstring\"," "\"wstring\","
#endif
"\"std::basic_string\"," "\"std::basic_string\","
"\"std::list\"," "\"std::list\","
"\"std::map\"," "\"std::map\","
@@ -2608,4 +2630,5 @@ void qDumpObjectData440(
else { else {
qDebug() << "Unsupported protocol version" << protocolVersion; qDebug() << "Unsupported protocol version" << protocolVersion;
} }
return qDumpOutBuffer;
} }

View File

@@ -1,11 +1,50 @@
#! /bin/bash #! /bin/bash
osascript >/dev/null 2>&1 <<EOF
### 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" tell application "Terminal"
do script "$1 $2 +$3 +\"normal $4|\"; exit" do script "$args; exit"
set currentTab to the result set currentTab to the result
set number of columns of currentTab to $5 $geom
set number of rows of currentTab to $6
set position of windows whose tabs contains currentTab to {$7, $8}
activate activate
end tell end tell
EOF EOF

View File

@@ -43,10 +43,14 @@
#include <windows.h> #include <windows.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QWinEventNotifier; class QWinEventNotifier;
class QTemporaryFile;
QT_END_NAMESPACE QT_END_NAMESPACE
#endif #endif
QT_BEGIN_NAMESPACE
class QSettings;
class QTemporaryFile;
QT_END_NAMESPACE
namespace Core { namespace Core {
namespace Utils { namespace Utils {
@@ -69,6 +73,13 @@ public:
int exitCode() const { return m_appCode; } // This will be the signal number if exitStatus == CrashExit int exitCode() const { return m_appCode; } // This will be the signal number if exitStatus == CrashExit
QProcess::ExitStatus exitStatus() const { return m_appStatus; } 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: signals:
void processError(const QString &error); void processError(const QString &error);
// These reflect the state of the actual client process // These reflect the state of the actual client process
@@ -102,15 +113,16 @@ private:
QProcess::ExitStatus m_appStatus; QProcess::ExitStatus m_appStatus;
QLocalServer m_stubServer; QLocalServer m_stubServer;
QLocalSocket *m_stubSocket; QLocalSocket *m_stubSocket;
QTemporaryFile *m_tempFile;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
PROCESS_INFORMATION *m_pid; PROCESS_INFORMATION *m_pid;
HANDLE m_hInferior; HANDLE m_hInferior;
QWinEventNotifier *inferiorFinishedNotifier; QWinEventNotifier *inferiorFinishedNotifier;
QWinEventNotifier *processFinishedNotifier; QWinEventNotifier *processFinishedNotifier;
QTemporaryFile *m_tempFile;
#else #else
QProcess m_process; QProcess m_process;
QByteArray m_stubServerDir; QByteArray m_stubServerDir;
QSettings *m_settings;
#endif #endif
}; };

View File

@@ -30,6 +30,8 @@
#include "consoleprocess.h" #include "consoleprocess.h"
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QSettings>
#include <QtCore/QTemporaryFile> #include <QtCore/QTemporaryFile>
#include <QtNetwork/QLocalSocket> #include <QtNetwork/QLocalSocket>
@@ -48,6 +50,7 @@ ConsoleProcess::ConsoleProcess(QObject *parent)
m_debug = false; m_debug = false;
m_appPid = 0; m_appPid = 0;
m_stubSocket = 0; m_stubSocket = 0;
m_settings = 0;
connect(&m_stubServer, SIGNAL(newConnection()), SLOT(stubConnectionAvailable())); connect(&m_stubServer, SIGNAL(newConnection()), SLOT(stubConnectionAvailable()));
@@ -72,8 +75,24 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
return false; return false;
} }
QStringList xtermArgs; if (!environment().isEmpty()) {
xtermArgs << "-e" 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 #ifdef Q_OS_MAC
<< (QCoreApplication::applicationDirPath() + "/../Resources/qtcreator_process_stub") << (QCoreApplication::applicationDirPath() + "/../Resources/qtcreator_process_stub")
#else #else
@@ -82,13 +101,17 @@ bool ConsoleProcess::start(const QString &program, const QStringList &args)
<< (m_debug ? "debug" : "exec") << (m_debug ? "debug" : "exec")
<< m_stubServer.fullServerName() << m_stubServer.fullServerName()
<< tr("Press <RETURN> to close this window...") << tr("Press <RETURN> to close this window...")
<< workingDirectory() << environment() << "" << workingDirectory()
<< (m_tempFile ? m_tempFile->fileName() : 0)
<< program << args; << program << args;
m_process.start(QLatin1String("xterm"), xtermArgs); QString xterm = xtermArgs.takeFirst();
m_process.start(xterm, xtermArgs);
if (!m_process.waitForStarted()) { if (!m_process.waitForStarted()) {
stubServerShutdown(); 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; return false;
} }
m_executable = program; m_executable = program;
@@ -173,6 +196,10 @@ void ConsoleProcess::readStubOutput()
emit processError(tr("Cannot execute %1: %2") emit processError(tr("Cannot execute %1: %2")
.arg(m_executable, errorMsg(out.mid(9).toInt()))); .arg(m_executable, errorMsg(out.mid(9).toInt())));
} else if (out.startsWith("pid ")) { } else if (out.startsWith("pid ")) {
// Will not need it any more
delete m_tempFile;
m_tempFile = 0;
m_appPid = out.mid(4).toInt(); m_appPid = out.mid(4).toInt();
emit processStarted(); emit processStarted();
} else if (out.startsWith("exit ")) { } else if (out.startsWith("exit ")) {
@@ -199,6 +226,8 @@ void ConsoleProcess::stubExited()
if (m_stubSocket && m_stubSocket->state() == QLocalSocket::ConnectedState) if (m_stubSocket && m_stubSocket->state() == QLocalSocket::ConnectedState)
m_stubSocket->waitForDisconnected(); m_stubSocket->waitForDisconnected();
stubServerShutdown(); stubServerShutdown();
delete m_tempFile;
m_tempFile = 0;
if (m_appPid) { if (m_appPid) {
m_appStatus = QProcess::CrashExit; m_appStatus = QProcess::CrashExit;
m_appCode = -1; m_appCode = -1;
@@ -207,3 +236,27 @@ void ConsoleProcess::stubExited()
} }
emit wrapperStopped(); 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, ArgSocket,
ArgMsg, ArgMsg,
ArgDir, 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 */ /* exit codes: 0 = ok, 1 = invocation error, 3 = internal error */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int envIdx = ArgEnv;
int errNo; int errNo;
int chldPid; int chldPid;
int chldStatus; int chldStatus;
int chldPipe[2]; int chldPipe[2];
char **env = 0;
struct sockaddr_un sau; struct sockaddr_un sau;
if (argc < ArgEnv) { if (argc < ArgEnv) {
@@ -111,6 +112,35 @@ int main(int argc, char *argv[])
return 1; 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. */ /* Create execution result notification pipe. */
if (pipe(chldPipe)) { if (pipe(chldPipe)) {
perror("Cannot create status pipe"); perror("Cannot create status pipe");
@@ -142,14 +172,10 @@ int main(int argc, char *argv[])
ptrace(PT_TRACE_ME, 0, 0, 0); ptrace(PT_TRACE_ME, 0, 0, 0);
#endif #endif
for (envIdx = ArgEnv; *argv[envIdx]; ++envIdx) ; if (env)
if (envIdx != ArgEnv) { environ = env;
argv[envIdx] = 0;
environ = argv + ArgEnv;
}
++envIdx;
execvp(argv[envIdx], argv + envIdx); execvp(argv[ArgExe], argv + ArgExe);
/* Only expected error: no such file or direcotry, i.e. executable not found */ /* Only expected error: no such file or direcotry, i.e. executable not found */
errNo = errno; errNo = errno;
write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */ write(chldPipe[1], &errNo, sizeof(errNo)); /* Only realistic error case is SIGPIPE */

View File

@@ -49,6 +49,7 @@
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/consoleprocess.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
@@ -73,6 +74,7 @@ Q_DECLARE_METATYPE(Core::IEditor*)
using namespace Core; using namespace Core;
using namespace Core::Internal; using namespace Core::Internal;
using namespace Core::Utils;
enum { debugEditorManager=0 }; enum { debugEditorManager=0 };
@@ -429,15 +431,14 @@ void EditorManager::init()
QString EditorManager::defaultExternalEditor() const QString EditorManager::defaultExternalEditor() const
{ {
#ifdef Q_OS_UNIX
return ConsoleProcess::defaultTerminalEmulator() + QLatin1String(
# ifdef Q_OS_MAC # ifdef Q_OS_MAC
return m_d->m_core->resourcePath() " -async"
+QLatin1String("/runInTerminal.command vi %f %l %c %W %H %x %y"); # endif
#elif defined(Q_OS_UNIX) " -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\"");
return QLatin1String("xterm -geom %Wx%H+%x+%y -e vi %f +%l +\"normal %c|\"");
#elif defined (Q_OS_WIN)
return QLatin1String("notepad %f");
#else #else
return QString(); return QLatin1String("notepad %f");
#endif #endif
} }
@@ -462,7 +463,7 @@ void EditorManager::removeEditor(IEditor *editor)
} }
void EditorManager::handleContextChange(IContext *context) void EditorManager::handleContextChange(Core::IContext *context)
{ {
if (debugEditorManager) if (debugEditorManager)
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
@@ -1172,9 +1173,8 @@ bool EditorManager::saveFile(IEditor *editor)
return true; return true;
} }
if (file->isReadOnly() || fileName.isEmpty()) { if (file->isReadOnly() || fileName.isEmpty())
return saveFileAs(editor); return saveFileAs(editor);
}
m_d->m_core->fileManager()->blockFileChange(file); m_d->m_core->fileManager()->blockFileChange(file);
const bool success = file->save(fileName); const bool success = file->save(fileName);

View File

@@ -31,11 +31,14 @@
#include "stylehelper.h" #include "stylehelper.h"
#include "utils/qtcolorbutton.h" #include "utils/qtcolorbutton.h"
#include <utils/consoleprocess.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/icore.h>
#include <QtGui/QMessageBox> #include <QtGui/QMessageBox>
#include "ui_generalsettings.h" #include "ui_generalsettings.h"
using namespace Core::Utils;
using namespace Core::Internal; using namespace Core::Internal;
GeneralSettings::GeneralSettings(): GeneralSettings::GeneralSettings():
@@ -71,6 +74,13 @@ QWidget *GeneralSettings::createPage(QWidget *parent)
m_page->colorButton->setColor(StyleHelper::baseColor()); m_page->colorButton->setColor(StyleHelper::baseColor());
m_page->externalEditorEdit->setText(EditorManager::instance()->externalEditor()); 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()), connect(m_page->resetButton, SIGNAL(clicked()),
this, SLOT(resetInterfaceColor())); this, SLOT(resetInterfaceColor()));
@@ -78,6 +88,10 @@ QWidget *GeneralSettings::createPage(QWidget *parent)
this, SLOT(resetExternalEditor())); this, SLOT(resetExternalEditor()));
connect(m_page->helpExternalEditorButton, SIGNAL(clicked()), connect(m_page->helpExternalEditorButton, SIGNAL(clicked()),
this, SLOT(showHelpForExternalEditor())); this, SLOT(showHelpForExternalEditor()));
#ifdef Q_OS_UNIX
connect(m_page->resetTerminalButton, SIGNAL(clicked()),
this, SLOT(resetTerminal()));
#endif
return w; return w;
} }
@@ -87,6 +101,10 @@ void GeneralSettings::apply()
// Apply the new base color if accepted // Apply the new base color if accepted
StyleHelper::setBaseColor(m_page->colorButton->color()); StyleHelper::setBaseColor(m_page->colorButton->color());
EditorManager::instance()->setExternalEditor(m_page->externalEditorEdit->text()); 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() void GeneralSettings::finish()
@@ -104,6 +122,13 @@ void GeneralSettings::resetExternalEditor()
m_page->externalEditorEdit->setText(EditorManager::instance()->defaultExternalEditor()); 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() void GeneralSettings::showHelpForExternalEditor()
{ {
if (m_dialog) { if (m_dialog) {

View File

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

View File

@@ -96,6 +96,34 @@
</item> </item>
</layout> </layout>
</item> </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> <item>
<layout class="QHBoxLayout" name="horizontalLayout_5"> <layout class="QHBoxLayout" name="horizontalLayout_5">
<item> <item>

View File

@@ -1070,11 +1070,14 @@ static const char *settingsGroup = "MainWindow";
static const char *geometryKey = "Geometry"; static const char *geometryKey = "Geometry";
static const char *colorKey = "Color"; static const char *colorKey = "Color";
static const char *maxKey = "Maximized"; static const char *maxKey = "Maximized";
static const char *fullScreenKey = "FullScreen";
void MainWindow::readSettings() void MainWindow::readSettings()
{ {
m_settings->beginGroup(QLatin1String(settingsGroup)); m_settings->beginGroup(QLatin1String(settingsGroup));
StyleHelper::setBaseColor(m_settings->value(QLatin1String(colorKey)).value<QColor>()); StyleHelper::setBaseColor(m_settings->value(QLatin1String(colorKey)).value<QColor>());
const QVariant geom = m_settings->value(QLatin1String(geometryKey)); const QVariant geom = m_settings->value(QLatin1String(geometryKey));
if (geom.isValid()) { if (geom.isValid()) {
setGeometry(geom.toRect()); setGeometry(geom.toRect());
@@ -1083,8 +1086,10 @@ void MainWindow::readSettings()
} }
if (m_settings->value(QLatin1String(maxKey), false).toBool()) if (m_settings->value(QLatin1String(maxKey), false).toBool())
setWindowState(Qt::WindowMaximized); setWindowState(Qt::WindowMaximized);
setFullScreen(m_settings->value(QLatin1String(fullScreenKey), false).toBool());
m_settings->endGroup(); m_settings->endGroup();
m_editorManager->readSettings(m_settings); m_editorManager->readSettings(m_settings);
m_navigationWidget->restoreSettings(m_settings); m_navigationWidget->restoreSettings(m_settings);
m_rightPaneWidget->readSettings(m_settings); m_rightPaneWidget->readSettings(m_settings);
@@ -1093,14 +1098,18 @@ void MainWindow::readSettings()
void MainWindow::writeSettings() void MainWindow::writeSettings()
{ {
m_settings->beginGroup(QLatin1String(settingsGroup)); m_settings->beginGroup(QLatin1String(settingsGroup));
m_settings->setValue(colorKey, StyleHelper::baseColor());
const QString maxSettingsKey = QLatin1String(maxKey); m_settings->setValue(QLatin1String(colorKey), StyleHelper::baseColor());
if (windowState() & Qt::WindowMaximized) {
m_settings->setValue(maxSettingsKey, true); 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 { } 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->setValue(QLatin1String(geometryKey), geometry());
} }
m_settings->endGroup(); m_settings->endGroup();
m_fileManager->saveRecentFiles(); m_fileManager->saveRecentFiles();

View File

@@ -250,6 +250,7 @@ DebuggerSettings *DebuggerSettings::instance()
// //
item = new SavedAction(instance); item = new SavedAction(instance);
item->setSettingsKey(debugModeGroup, QLatin1String("Location")); item->setSettingsKey(debugModeGroup, QLatin1String("Location"));
item->setDefaultValue("gdb");
instance->insertItem(GdbLocation, item); instance->insertItem(GdbLocation, item);
item = new SavedAction(instance); item = new SavedAction(instance);
@@ -272,11 +273,6 @@ DebuggerSettings *DebuggerSettings::instance()
item->setCheckable(true); item->setCheckable(true);
instance->insertItem(UseToolTips, item); 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 = new SavedAction(instance);
item->setSettingsKey(debugModeGroup, QLatin1String("ListSourceFiles")); item->setSettingsKey(debugModeGroup, QLatin1String("ListSourceFiles"));
item->setText(tr("List source files")); item->setText(tr("List source files"));
@@ -291,6 +287,7 @@ DebuggerSettings *DebuggerSettings::instance()
item = new SavedAction(instance); item = new SavedAction(instance);
item->setSettingsKey(debugModeGroup, QLatin1String("AllPluginBreakpoints")); item->setSettingsKey(debugModeGroup, QLatin1String("AllPluginBreakpoints"));
item->setDefaultValue(true);
instance->insertItem(AllPluginBreakpoints, item); instance->insertItem(AllPluginBreakpoints, item);
item = new SavedAction(instance); item = new SavedAction(instance);

View File

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

View File

@@ -131,7 +131,7 @@ AttachCoreDialog::AttachCoreDialog(QWidget *parent)
m_ui->execFileName->setPromptDialogTitle(tr("Select Executable")); m_ui->execFileName->setPromptDialogTitle(tr("Select Executable"));
m_ui->coreFileName->setExpectedKind(Core::Utils::PathChooser::File); 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); 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.gdbLocationChooser->setPromptDialogTitle(tr("Choose Gdb Location"));
m_ui.scriptFileChooser->setExpectedKind(Core::Utils::PathChooser::File); m_ui.scriptFileChooser->setExpectedKind(Core::Utils::PathChooser::File);
m_ui.scriptFileChooser->setPromptDialogTitle(tr("Choose Location of Startup Script 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.clear();
m_group.insert(theDebuggerAction(GdbLocation), m_group.insert(theDebuggerAction(GdbLocation),
@@ -279,8 +277,6 @@ QWidget *GdbOptionPage::createPage(QWidget *parent)
m_ui.scriptFileChooser); m_ui.scriptFileChooser);
m_group.insert(theDebuggerAction(GdbEnvironment), m_group.insert(theDebuggerAction(GdbEnvironment),
m_ui.environmentEdit); m_ui.environmentEdit);
m_group.insert(theDebuggerAction(TerminalApplication),
m_ui.terminalChooser);
m_group.insert(theDebuggerAction(AllPluginBreakpoints), m_group.insert(theDebuggerAction(AllPluginBreakpoints),
m_ui.radioButtonAllPluginBreakpoints); m_ui.radioButtonAllPluginBreakpoints);

View File

@@ -163,6 +163,20 @@ static int &currentToken()
return token; 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 // GdbEngine
@@ -667,7 +681,7 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
GdbCookie cmd = m_cookieForToken.take(token); 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(); //qDebug() << "### SKIPPING OLD RESULT " << record.toString();
//QMessageBox::information(m_mainWindow, tr("Skipped"), "xxx"); //QMessageBox::information(m_mainWindow, tr("Skipped"), "xxx");
return; return;
@@ -1140,9 +1154,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
+ data.findChild("signal-name").toString(); + data.findChild("signal-name").toString();
} }
q->showStatusMessage(msg); q->showStatusMessage(msg);
// FIXME: shouldn't this use a statis change? sendCommand("-gdb-exit");
debugMessage("CALLING PARENT EXITDEBUGGER");
q->exitDebugger();
return; return;
} }
@@ -1857,8 +1869,21 @@ void GdbEngine::jumpToLineExec(const QString &fileName, int lineNumber)
void GdbEngine::setTokenBarrier() void GdbEngine::setTokenBarrier()
{ {
foreach (const GdbCookie &ck, m_cookieForToken) foreach (const GdbCookie &cookie, m_cookieForToken) {
QTC_ASSERT(ck.synchronized || ck.type == GdbInvalidCommand, return); 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"); PENDING_DEBUG("\n--- token barrier ---\n");
emit gdbInputAvailable(QString(), "--- token barrier ---"); emit gdbInputAvailable(QString(), "--- token barrier ---");
m_oldestAcceptableToken = currentToken(); m_oldestAcceptableToken = currentToken();
@@ -1930,7 +1955,10 @@ void GdbEngine::breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt
if (pos > 0) { if (pos > 0) {
data->bpLineNumber = child.data().mid(pos + 1); data->bpLineNumber = child.data().mid(pos + 1);
data->markerLineNumber = child.data().mid(pos + 1).toInt(); 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 { } else {
files.prepend(child.data()); 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 // set up fallback in case of pending breakpoints which aren't handled
// by the MI interface // by the MI interface
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
QString cmd = "-break-insert "; QString cmd = "-break-insert -f ";
//if (!data->condition.isEmpty()) //if (!data->condition.isEmpty())
// cmd += "-c " + data->condition + " "; // cmd += "-c " + data->condition + " ";
cmd += where; cmd += where;
@@ -2133,6 +2161,8 @@ void GdbEngine::handleBreakInsert(const GdbResultRecord &record, int index)
// + data->lineNumber + "\""; // + data->lineNumber + "\"";
QString where = "\"" + data->fileName + "\":" QString where = "\"" + data->fileName + "\":"
+ data->lineNumber; + data->lineNumber;
// Should not happen with -break-insert -f. gdb older than 6.8?
QTC_ASSERT(false, /**/);
sendCommand("break " + where, BreakInsert1, index); sendCommand("break " + where, BreakInsert1, index);
#endif #endif
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
@@ -3054,7 +3084,7 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
} else if (outertype == m_namespace + "QMapNode") { } else if (outertype == m_namespace + "QMapNode") {
extraArgs[2] = sizeofTypeExpression(data.type); extraArgs[2] = sizeofTypeExpression(data.type);
extraArgs[3] = "(size_t)&(('" + data.type + "'*)0)->value"; 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; //qDebug() << "EXTRACT TEMPLATE: " << outertype << inners;
if (inners.at(0) == "bool") { if (inners.at(0) == "bool") {
outertype = "std::vector::bool"; outertype = "std::vector::bool";
@@ -3062,18 +3092,18 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
//extraArgs[extraArgCount++] = sizeofTypeExpression(data.type); //extraArgs[extraArgCount++] = sizeofTypeExpression(data.type);
//extraArgs[extraArgCount++] = "(size_t)&(('" + data.type + "'*)0)->value"; //extraArgs[extraArgCount++] = "(size_t)&(('" + data.type + "'*)0)->value";
} }
} else if (outertype == "std::deque") { } else if (outertype == "std::deque" || outertype == "deque") {
// remove 'std::allocator<...>': // remove 'std::allocator<...>':
extraArgs[1] = "0"; extraArgs[1] = "0";
} else if (outertype == "std::stack") { } else if (outertype == "std::stack" || outertype == "stack") {
// remove 'std::allocator<...>': // remove 'std::allocator<...>':
extraArgs[1] = "0"; extraArgs[1] = "0";
} else if (outertype == "std::set") { } else if (outertype == "std::set" || outertype == "set") {
// remove 'std::less<...>': // remove 'std::less<...>':
extraArgs[1] = "0"; extraArgs[1] = "0";
// remove 'std::allocator<...>': // remove 'std::allocator<...>':
extraArgs[2] = "0"; 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. // We don't want the comparator and the allocator confuse gdb.
// But we need the offset of the second item in the value pair. // 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 // 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); pairType = pairType.mid(15, pairType.size() - 15 - 2);
extraArgs[2] = "(size_t)&(('" + pairType + "'*)0)->second"; extraArgs[2] = "(size_t)&(('" + pairType + "'*)0)->second";
extraArgs[3] = "0"; extraArgs[3] = "0";
} else if (outertype == "std::basic_string") { } else if (outertype == "std::basic_string" || outertype == "basic_string") {
//qDebug() << "EXTRACT TEMPLATE: " << outertype << inners; //qDebug() << "EXTRACT TEMPLATE: " << outertype << inners;
if (inners.at(0) == "char") { if (inners.at(0) == "char") {
outertype = "std::string"; outertype = "std::string";
@@ -4148,10 +4178,10 @@ void GdbEngine::tryLoadDebuggingHelpers()
QString flag = QString::number(RTLD_NOW); QString flag = QString::number(RTLD_NOW);
sendCommand("sharedlibrary libc"); // for malloc sendCommand("sharedlibrary libc"); // for malloc
sendCommand("sharedlibrary libdl"); // for dlopen sendCommand("sharedlibrary libdl"); // for dlopen
sendCommand("call (void)dlopen(\"" + lib + "\", " + flag + ")", sendCommand("call (void*)dlopen(\"" + lib + "\", " + flag + ")",
WatchDebuggingHelperSetup); WatchDebuggingHelperSetup);
// some older systems like CentOS 4.6 prefer this: // some older systems like CentOS 4.6 prefer this:
sendCommand("call (void)__dlopen(\"" + lib + "\", " + flag + ")", sendCommand("call (void*)__dlopen(\"" + lib + "\", " + flag + ")",
WatchDebuggingHelperSetup); WatchDebuggingHelperSetup);
sendCommand("sharedlibrary " + dotEscape(lib)); sendCommand("sharedlibrary " + dotEscape(lib));
#endif #endif

View File

@@ -39,17 +39,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="1" column="0">
<widget class="QLabel" name="labelEnvironment"> <widget class="QLabel" name="labelEnvironment">
<property name="text"> <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"> <item row="0" column="1">
<widget class="Core::Utils::PathChooser" name="gdbLocationChooser" native="true"/> <widget class="Core::Utils::PathChooser" name="gdbLocationChooser" native="true"/>
</item> </item>
<item row="3" column="1">
<widget class="Core::Utils::PathChooser" name="terminalChooser" native="true"/>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@@ -66,6 +66,8 @@ using namespace Debugger::Internal;
static const QString strNotInScope = QLatin1String("<not in scope>"); static const QString strNotInScope = QLatin1String("<not in scope>");
static int watcherCounter = 0;
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// //
// WatchData // WatchData
@@ -356,54 +358,101 @@ WatchHandler::WatchHandler()
SIGNAL(triggered()), this, SLOT(collapseChildren())); 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) static QString niceType(QString type)
{ {
if (type.contains(QLatin1String("std::"))) { if (type.contains(QLatin1String("std::"))) {
// std::string // std::string
type.replace(QLatin1String("std::basic_string<char, std::char_traits<char>, " type.replace(QLatin1String("basic_string<char, std::char_traits<char>, "
"std::allocator<char> >"), QLatin1String("std::string")); "std::allocator<char> >"), QLatin1String("string"));
// std::wstring // std::wstring
type.replace(QLatin1String("std::basic_string<wchar_t, std::char_traits<wchar_t>, " type.replace(QLatin1String("basic_string<wchar_t, std::char_traits<wchar_t>, "
"std::allocator<wchar_t> >"), QLatin1String("std::wstring")); "std::allocator<wchar_t> >"), QLatin1String("wstring"));
// std::vector // std::vector
static QRegExp re1(QLatin1String("std::vector<(.*), std::allocator<(.*)>\\s*>")); static QRegExp re1(QLatin1String("vector<(.*), std::allocator<(.*)>\\s*>"));
re1.setMinimal(true); re1.setMinimal(true);
for (int i = 0; i != 10; ++i) { for (int i = 0; i != 10; ++i) {
if (re1.indexIn(type) == -1 || re1.cap(1) != re1.cap(2)) if (re1.indexIn(type) == -1 || re1.cap(1) != re1.cap(2))
break; 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 // std::list
static QRegExp re2(QLatin1String("std::list<(.*), std::allocator<(.*)>\\s*>")); static QRegExp re2(QLatin1String("list<(.*), std::allocator<(.*)>\\s*>"));
re2.setMinimal(true); re2.setMinimal(true);
for (int i = 0; i != 10; ++i) { for (int i = 0; i != 10; ++i) {
if (re2.indexIn(type) == -1 || re2.cap(1) != re2.cap(2)) if (re2.indexIn(type) == -1 || re2.cap(1) != re2.cap(2))
break; 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 // std::map
static QRegExp re3(QLatin1String("std::map<(.*), (.*), std::less<(.*)\\s*>, " {
"std::allocator<std::pair<const (.*), (.*)\\s*> > >")); static QRegExp re(QLatin1String("map<(.*), (.*), std::less<(.*)>, "
re3.setMinimal(true); "std::allocator<std::pair<(.*), (.*)> > >"));
re.setMinimal(true);
for (int i = 0; i != 10; ++i) { for (int i = 0; i != 10; ++i) {
if (re3.indexIn(type) == -1 || re3.cap(1) != re3.cap(3) if (re.indexIn(type) == -1)
|| re3.cap(1) != re3.cap(4) || re3.cap(2) != re3.cap(5))
break; break;
type.replace(re3.cap(0), QLatin1String("std::map<") + re3.cap(1) + QLatin1String(", ") + re3.cap(2) + QLatin1Char('>')); 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 // 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); re1.setMinimal(true);
for (int i = 0; i != 10; ++i) { for (int i = 0; i != 10; ++i) {
if (re4.indexIn(type) == -1 || re4.cap(1) != re4.cap(2) if (re4.indexIn(type) == -1 || re4.cap(1) != re4.cap(2)
|| re4.cap(1) != re4.cap(3)) || re4.cap(1) != re4.cap(3))
break; 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('>'))); type.replace(QLatin1String(" >"), QString(QLatin1Char('>')));
@@ -875,17 +924,21 @@ void WatchHandler::watchExpression()
watchExpression(action->data().toString()); watchExpression(action->data().toString());
} }
QString WatchHandler::watcherName(const QString &exp)
{
return QLatin1String("watch.") + QString::number(m_watchers[exp]);
}
void WatchHandler::watchExpression(const QString &exp) void WatchHandler::watchExpression(const QString &exp)
{ {
// FIXME: 'exp' can contain illegal characters // FIXME: 'exp' can contain illegal characters
//MODEL_DEBUG("WATCH: " << exp); //MODEL_DEBUG("WATCH: " << exp);
static int counter = 0; m_watchers[exp] = watcherCounter++;
WatchData data; WatchData data;
data.exp = exp; data.exp = exp;
data.name = exp; data.name = exp;
data.iname = QLatin1String("watch.") + QString::number(counter++); data.iname = watcherName(exp);
insertData(data); insertData(data);
m_watchers.append(exp);
saveWatchers(); saveWatchers();
emit watchModelUpdateRequested(); emit watchModelUpdateRequested();
} }
@@ -970,7 +1023,7 @@ void WatchHandler::removeWatchExpression()
void WatchHandler::removeWatchExpression(const QString &exp) void WatchHandler::removeWatchExpression(const QString &exp)
{ {
MODEL_DEBUG("REMOVE WATCH: " << exp); MODEL_DEBUG("REMOVE WATCH: " << exp);
m_watchers.removeOne(exp); m_watchers.remove(exp);
for (int i = m_completeSet.size(); --i >= 0;) { for (int i = m_completeSet.size(); --i >= 0;) {
const WatchData & data = m_completeSet.at(i); const WatchData & data = m_completeSet.at(i);
if (data.iname.startsWith(QLatin1String("watch.")) && data.exp == exp) { 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 // copy over all watchers and mark all watchers as incomplete
int i = 0; int i = 0;
foreach (const QString &exp, m_watchers) { foreach (const QString &exp, m_watchers.keys()) {
WatchData data; WatchData data;
data.iname = watcherName(exp);
data.level = -1; data.level = -1;
data.row = -1; data.row = -1;
data.parentIndex = -1; data.parentIndex = -1;
@@ -1205,15 +1259,16 @@ void WatchHandler::loadWatchers()
{ {
QVariant value; QVariant value;
sessionValueRequested("Watchers", &value); sessionValueRequested("Watchers", &value);
m_watchers = value.toStringList(); foreach (const QString &exp, value.toStringList())
m_watchers[exp] = watcherCounter++;
//qDebug() << "LOAD WATCHERS: " << m_watchers; //qDebug() << "LOAD WATCHERS: " << m_watchers;
reinitializeWatchersHelper(); reinitializeWatchersHelper();
} }
void WatchHandler::saveWatchers() void WatchHandler::saveWatchers()
{ {
//qDebug() << "SAVE WATCHERS: " << m_watchers; //qDebug() << "SAVE WATCHERS: " << m_watchers.keys();
setSessionValueRequested("Watchers", m_watchers); setSessionValueRequested("Watchers", QVariant(m_watchers.keys()));
} }
void WatchHandler::saveSessionData() void WatchHandler::saveSessionData()

View File

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

View File

@@ -50,6 +50,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QFile> #include <QtCore/QFile>
#include <QtCore/QObject> #include <QtCore/QObject>
@@ -606,22 +607,28 @@ EventResult FakeVimHandler::Private::handleKey(int key, int unmodified,
void FakeVimHandler::Private::moveDown(int n) void FakeVimHandler::Private::moveDown(int n)
{ {
// m_tc.movePosition(Down, MoveAnchor, n); does not work for "hidden" #if 0
// documents like in the autotests // does not work for "hidden" documents like in the autotests
const QTextBlock &block = m_tc.block(); m_tc.movePosition(Down, MoveAnchor, n);
const int col = m_tc.position() - block.position(); #else
const int line = block.blockNumber(); const int col = m_tc.position() - m_tc.block().position();
const int pos = m_tc.document()->findBlockByNumber(line + n).position(); const int line = m_tc.block().blockNumber();
setPosition(pos + qMin(block.length(), col)); const QTextBlock &block = m_tc.document()->findBlockByNumber(line + n);
setPosition(pos); const int pos = block.position();
setPosition(pos + qMin(block.length() - 1, col));
moveToTargetColumn();
#endif
} }
void FakeVimHandler::Private::moveToEndOfLine() void FakeVimHandler::Private::moveToEndOfLine()
{ {
// m_tc.movePosition(EndOfLine, MoveAnchor) does not work for "hidden" #if 0
// documents like in the autotests // does not work for "hidden" documents like in the autotests
m_tc.movePosition(EndOfLine, MoveAnchor);
#else
const QTextBlock &block = m_tc.block(); const QTextBlock &block = m_tc.block();
setPosition(block.position() + block.length() - 1); setPosition(block.position() + block.length() - 1);
#endif
} }
void FakeVimHandler::Private::finishMovement(const QString &dotCommand) 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) void FakeVimHandler::Private::handleCommand(const QString &cmd)
{ {
m_tc = EDITOR(textCursor()); m_tc = EDITOR(textCursor());
init();
handleExCommand(cmd); handleExCommand(cmd);
EDITOR(setTextCursor(m_tc)); EDITOR(setTextCursor(m_tc));
} }
@@ -2077,12 +2083,22 @@ void FakeVimHandler::Private::shiftRegionLeft(int repeat)
void FakeVimHandler::Private::moveToTargetColumn() void FakeVimHandler::Private::moveToTargetColumn()
{ {
if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn) if (m_targetColumn == -1 || m_tc.block().length() <= m_targetColumn) {
m_tc.movePosition(EndOfLine, KeepAnchor); const QTextBlock &block = m_tc.block();
else m_tc.setPosition(block.position() + block.length() - 1, KeepAnchor);
} else {
m_tc.setPosition(m_tc.block().position() + m_targetColumn, KeepAnchor); 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) static int charClass(QChar c, bool simple)
{ {
if (simple) if (simple)
@@ -2100,6 +2116,7 @@ void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward)
int lastClass = -1; int lastClass = -1;
while (true) { while (true) {
QChar c = doc->characterAt(m_tc.position() + (forward ? 1 : -1)); QChar c = doc->characterAt(m_tc.position() + (forward ? 1 : -1));
qDebug() << "EXAMINING: " << c << " AT " << position();
int thisClass = charClass(c, simple); int thisClass = charClass(c, simple);
if (thisClass != lastClass && lastClass != 0) if (thisClass != lastClass && lastClass != 0)
--repeat; --repeat;
@@ -2110,6 +2127,7 @@ void FakeVimHandler::Private::moveToWordBoundary(bool simple, bool forward)
break; break;
forward ? moveRight() : moveLeft(); forward ? moveRight() : moveLeft();
} }
setTargetColumn();
} }
void FakeVimHandler::Private::handleFfTt(int key) void FakeVimHandler::Private::handleFfTt(int key)
@@ -2145,6 +2163,7 @@ void FakeVimHandler::Private::handleFfTt(int key)
break; break;
} }
} }
setTargetColumn();
} }
void FakeVimHandler::Private::moveToNextWord(bool simple) void FakeVimHandler::Private::moveToNextWord(bool simple)
@@ -2165,6 +2184,7 @@ void FakeVimHandler::Private::moveToNextWord(bool simple)
if (m_tc.position() == n) if (m_tc.position() == n)
break; break;
} }
setTargetColumn();
} }
void FakeVimHandler::Private::moveToMatchingParanthesis() void FakeVimHandler::Private::moveToMatchingParanthesis()
@@ -2178,6 +2198,7 @@ void FakeVimHandler::Private::moveToMatchingParanthesis()
if (m_submode == NoSubMode || m_submode == ZSubMode || m_submode == RegisterSubMode) if (m_submode == NoSubMode || m_submode == ZSubMode || m_submode == RegisterSubMode)
m_tc.movePosition(Left, KeepAnchor, 1); m_tc.movePosition(Left, KeepAnchor, 1);
} }
setTargetColumn();
} }
int FakeVimHandler::Private::cursorLineOnScreen() const int FakeVimHandler::Private::cursorLineOnScreen() const

View File

@@ -543,7 +543,7 @@ void FakeVimPluginPrivate::indentRegion(int *amount, int beginLine, int endLine,
void FakeVimPluginPrivate::quitFakeVim() void FakeVimPluginPrivate::quitFakeVim()
{ {
setUseFakeVim(false); theFakeVimSetting(ConfigUseFakeVim)->setValue(false);
} }
void FakeVimPluginPrivate::showCommandBuffer(const QString &contents) void FakeVimPluginPrivate::showCommandBuffer(const QString &contents)

View File

@@ -30,6 +30,8 @@
#include "applicationlauncher.h" #include "applicationlauncher.h"
#include "consoleprocess.h" #include "consoleprocess.h"
#include <coreplugin/icore.h>
#include <QtCore/QTimer> #include <QtCore/QTimer>
using namespace ProjectExplorer::Internal; using namespace ProjectExplorer::Internal;
@@ -52,6 +54,7 @@ ApplicationLauncher::ApplicationLauncher(QObject *parent)
this, SLOT(bringToForeground())); this, SLOT(bringToForeground()));
m_consoleProcess = new ConsoleProcess(this); m_consoleProcess = new ConsoleProcess(this);
m_consoleProcess->setSettings(Core::ICore::instance()->settings());
connect(m_consoleProcess, SIGNAL(processError(const QString&)), connect(m_consoleProcess, SIGNAL(processError(const QString&)),
this, SIGNAL(applicationError(const QString&))); this, SIGNAL(applicationError(const QString&)));
connect(m_consoleProcess, SIGNAL(processStopped()), connect(m_consoleProcess, SIGNAL(processStopped()),

View File

@@ -453,6 +453,7 @@ void Project::addRunConfiguration(QSharedPointer<RunConfiguration> runConfigurat
return; return;
} }
m_runConfigurations.push_back(runConfiguration); m_runConfigurations.push_back(runConfiguration);
emit addedRunConfiguration(runConfiguration->name());
} }
void Project::removeRunConfiguration(QSharedPointer<RunConfiguration> runConfiguration) void Project::removeRunConfiguration(QSharedPointer<RunConfiguration> runConfiguration)
@@ -461,13 +462,18 @@ void Project::removeRunConfiguration(QSharedPointer<RunConfiguration> runConfigu
qWarning()<<"Not removing runConfiguration"<<runConfiguration->name()<<"becasue it doesn't exist"; qWarning()<<"Not removing runConfiguration"<<runConfiguration->name()<<"becasue it doesn't exist";
return; return;
} }
m_runConfigurations.removeOne(runConfiguration);
if (m_activeRunConfiguration == runConfiguration) { if (m_activeRunConfiguration == runConfiguration) {
if (m_runConfigurations.isEmpty()) if (m_runConfigurations.size() <= 1)
setActiveRunConfiguration(QSharedPointer<RunConfiguration>(0)); setActiveRunConfiguration(QSharedPointer<RunConfiguration>(0));
else if (m_runConfigurations.at(0) == m_activeRunConfiguration)
setActiveRunConfiguration(m_runConfigurations.at(1));
else else
setActiveRunConfiguration(m_runConfigurations.at(0)); setActiveRunConfiguration(m_runConfigurations.at(0));
} }
m_runConfigurations.removeOne(runConfiguration);
emit removedRunConfiguration(runConfiguration->name());
} }
QSharedPointer<RunConfiguration> Project::activeRunConfiguration() const QSharedPointer<RunConfiguration> Project::activeRunConfiguration() const

View File

@@ -140,6 +140,8 @@ signals:
void fileListChanged(); void fileListChanged();
void activeBuildConfigurationChanged(); void activeBuildConfigurationChanged();
void activeRunConfigurationChanged(); 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 // This signal is jut there for updating the tree list in the buildsettings wizard
void buildConfigurationDisplayNameChanged(const QString &buildConfiguraiton); void buildConfigurationDisplayNameChanged(const QString &buildConfiguraiton);

View File

@@ -189,6 +189,15 @@ RunSettingsWidget::RunSettingsWidget(Project *project)
connect(m_ui->removeToolButton, SIGNAL(clicked(bool)), connect(m_ui->removeToolButton, SIGNAL(clicked(bool)),
this, SLOT(removeRunConfiguration())); 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(); initRunConfigurationComboBox();
const QList<QSharedPointer<RunConfiguration> > runConfigurations = m_project->runConfigurations(); const QList<QSharedPointer<RunConfiguration> > runConfigurations = m_project->runConfigurations();
for (int i=0; i<runConfigurations.size(); ++i) { for (int i=0; i<runConfigurations.size(); ++i) {
@@ -285,6 +294,14 @@ void RunSettingsWidget::activateRunConfiguration(int index)
m_ui->groupBox->layout()->addWidget(m_runConfigurationWidget); 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() void RunSettingsWidget::nameChanged()
{ {
RunConfiguration *rc = qobject_cast<RunConfiguration *>(sender()); RunConfiguration *rc = qobject_cast<RunConfiguration *>(sender());

View File

@@ -77,9 +77,9 @@ private slots:
void addRunConfiguration(); void addRunConfiguration();
void removeRunConfiguration(); void removeRunConfiguration();
void nameChanged(); void nameChanged();
private:
void initRunConfigurationComboBox(); void initRunConfigurationComboBox();
void activeRunConfigurationChanged();
private:
Project *m_project; Project *m_project;
RunConfigurationsModel *m_runConfigurationsModel; RunConfigurationsModel *m_runConfigurationsModel;
Ui::RunSettingsPropertiesPage *m_ui; Ui::RunSettingsPropertiesPage *m_ui;

View File

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

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

@@ -47,6 +47,12 @@
using namespace TextEditor; 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) #if defined (Q_OS_WIN)
# define NATIVE_LINE_TERMINATOR CRLFLineTerminator # define NATIVE_LINE_TERMINATOR CRLFLineTerminator
#else #else
@@ -140,8 +146,20 @@ bool BaseTextDocument::isReadOnly() const
return true; return true;
if (m_fileName.isEmpty()) //have no corresponding file, so editing is ok if (m_fileName.isEmpty()) //have no corresponding file, so editing is ok
return false; return false;
const QFileInfo fi(m_fileName); 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 bool BaseTextDocument::isModified() const
@@ -157,19 +175,9 @@ bool BaseTextDocument::open(const QString &fileName)
m_fileName = fi.absoluteFilePath(); m_fileName = fi.absoluteFilePath();
QFile file(fileName); QFile file(fileName);
if (!file.exists())
return false;
if (!fi.isReadable())
return false;
if (!fi.isWritable()) {
if (!file.open(QIODevice::ReadOnly)) if (!file.open(QIODevice::ReadOnly))
return false; return false;
} else {
if (!file.open(QIODevice::ReadWrite))
return false;
}
title = fi.fileName(); title = fi.fileName();
QByteArray buf = file.readAll(); QByteArray buf = file.readAll();

View File

@@ -213,9 +213,8 @@ HelpViewer::HelpViewer(QHelpEngine *engine, CentralWidget *parent)
: QWebView(parent), helpEngine(engine), parentWidget(parent) : QWebView(parent), helpEngine(engine), parentWidget(parent)
{ {
setPage(new HelpPage(parent, helpEngine, this)); setPage(new HelpPage(parent, helpEngine, this));
// Enable JavaScript and Plugins for embedded videos settings()->setAttribute(QWebSettings::PluginsEnabled, false);
settings()->setAttribute(QWebSettings::PluginsEnabled, true); settings()->setAttribute(QWebSettings::JavaEnabled, false);
settings()->setAttribute(QWebSettings::JavaEnabled, true);
page()->setNetworkAccessManager(new HelpNetworkAccessManager(engine, this)); page()->setNetworkAccessManager(new HelpNetworkAccessManager(engine, this));

View File

@@ -151,6 +151,8 @@ public:
QString m_pendingComment; QString m_pendingComment;
bool m_syntaxError; bool m_syntaxError;
bool m_contNextLine; bool m_contNextLine;
bool m_inQuote;
int m_parens;
/////////////// Evaluating pro file contents /////////////// Evaluating pro file contents
@@ -251,6 +253,8 @@ bool ProFileEvaluator::Private::read(ProFile *pro)
// Parser state // Parser state
m_block = 0; m_block = 0;
m_commentItem = 0; m_commentItem = 0;
m_inQuote = false;
m_parens = 0;
m_contNextLine = false; m_contNextLine = false;
m_syntaxError = false; m_syntaxError = false;
m_lineNo = 1; m_lineNo = 1;
@@ -274,32 +278,37 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0)
if (m_blockstack.isEmpty()) if (m_blockstack.isEmpty())
return false; return false;
ushort quote = 0; int parens = m_parens;
int parens = 0; bool inQuote = m_inQuote;
bool contNextLine = false; bool escaped = false;
QString line = line0.simplified(); QString line = line0.simplified();
for (int i = 0; !m_syntaxError && i < line.length(); ++i) { for (int i = 0; !m_syntaxError && i < line.length(); ++i) {
ushort c = line.at(i).unicode(); ushort c = line.at(i).unicode();
if (quote && c == quote) if (c == '#') { // Yep - no escaping possible
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)); insertComment(line.mid(i + 1));
contNextLine = m_contNextLine; escaped = m_contNextLine;
break; break;
} }
if (c == '\\' && i >= line.count() - 1) { if (!escaped) {
updateItem(); if (c == '\\') {
contNextLine = true; escaped = true;
m_proitem += c;
continue;
} else if (c == '"') {
inQuote = !inQuote;
m_proitem += c;
continue; 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 (m_block && (m_block->blockKind() & ProBlock::VariableKind)) {
if (c == ' ') if (c == ' ')
updateItem(); updateItem();
@@ -328,11 +337,17 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0)
continue; continue;
} }
} }
}
m_proitem += c; m_proitem += c;
} }
m_contNextLine = contNextLine; m_inQuote = inQuote;
m_parens = parens;
m_contNextLine = escaped;
if (escaped) {
m_proitem.chop(1);
return true;
} else {
if (!m_syntaxError) { if (!m_syntaxError) {
updateItem(); updateItem();
if (!m_contNextLine) if (!m_contNextLine)
@@ -340,6 +355,7 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0)
} }
return !m_syntaxError; return !m_syntaxError;
} }
}
void ProFileEvaluator::Private::finalizeBlock() void ProFileEvaluator::Private::finalizeBlock()
{ {
@@ -357,6 +373,9 @@ void ProFileEvaluator::Private::insertVariable(const QString &line, int *i)
{ {
ProVariable::VariableOperator opkind; ProVariable::VariableOperator opkind;
if (m_proitem.isEmpty()) // Line starting with '=', like a conflict marker
return;
switch (m_proitem.at(m_proitem.length() - 1).unicode()) { switch (m_proitem.at(m_proitem.length() - 1).unicode()) {
case '+': case '+':
m_proitem.chop(1); m_proitem.chop(1);
@@ -636,11 +655,11 @@ bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok); evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok);
evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"), &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); tmp.append(m_addUserConfigCmdArgs);
foreach(const QString &remove, m_removeUserConfigCmdArgs) foreach(const QString &remove, m_removeUserConfigCmdArgs)
tmp.removeAll(remove); tmp.removeAll(remove);
m_valuemap.insert("CONFIG", tmp); m_valuemap.insert(QLatin1String("CONFIG"), tmp);
m_cumulative = cumulative; m_cumulative = cumulative;
} }
@@ -2021,7 +2040,13 @@ ProFile *ProFileEvaluator::parsedProFile(const QString &fileName)
{ {
QFileInfo fi(fileName); QFileInfo fi(fileName);
if (fi.exists()) { 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)) if (d->read(pro))
return pro; return pro;
delete pro; delete pro;

View File

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

View File

@@ -30,6 +30,8 @@
#include "fakevimhandler.h" #include "fakevimhandler.h"
#include <QtCore/QSet> #include <QtCore/QSet>
#include <QtGui/QTextEdit>
#include <QtGui/QPlainTextEdit> #include <QtGui/QPlainTextEdit>
#include <QtTest/QtTest> #include <QtTest/QtTest>
@@ -37,13 +39,15 @@
using namespace FakeVim; using namespace FakeVim;
using namespace FakeVim::Internal; using namespace FakeVim::Internal;
#define EDITOR(s) (m_textedit ? m_textedit->s : m_plaintextedit->s)
class tst_FakeVim : public QObject class tst_FakeVim : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
tst_FakeVim(); tst_FakeVim(bool);
~tst_FakeVim();
public slots: public slots:
void changeStatusData(const QString &info) { m_statusData = info; } void changeStatusData(const QString &info) { m_statusData = info; }
@@ -51,14 +55,17 @@ public slots:
void changeExtraInformation(const QString &info) { m_infoMessage = info; } void changeExtraInformation(const QString &info) { m_infoMessage = info; }
private slots: private slots:
void commandI();
void commandDollar(); void commandDollar();
void commandDown(); void commandDown();
void commandLeft();
void commandRight();
void commandI();
void commandUp(); void commandUp();
void commandW();
private: private:
void setup(); 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 void sendEx(const QString &command); // send an ex command
bool checkContentsHelper(QString expected, const char* file, int line); bool checkContentsHelper(QString expected, const char* file, int line);
@@ -66,8 +73,9 @@ private:
const char* file, int line); const char* file, int line);
QString insertCursor(const QString &needle0); QString insertCursor(const QString &needle0);
QPlainTextEdit m_editor; QTextEdit *m_textedit;
FakeVimHandler m_handler; QPlainTextEdit *m_plaintextedit;
FakeVimHandler *m_handler;
QList<QTextEdit::ExtraSelection> m_selection; QList<QTextEdit::ExtraSelection> m_selection;
QString m_statusMessage; QString m_statusMessage;
@@ -79,6 +87,8 @@ private:
}; };
const QString tst_FakeVim::lines = const QString tst_FakeVim::lines =
/* 0 1 2 3 4 */
/* 0123456789012345678901234567890123457890 */
"\n" "\n"
"#include <QtCore>\n" "#include <QtCore>\n"
"#include <QtGui>\n" "#include <QtGui>\n"
@@ -92,46 +102,70 @@ const QString tst_FakeVim::lines =
const QString tst_FakeVim::escape = QChar(27); const QString tst_FakeVim::escape = QChar(27);
tst_FakeVim::tst_FakeVim() tst_FakeVim::tst_FakeVim(bool usePlainTextEdit)
: m_handler(&m_editor, this)
{ {
QObject::connect(&m_handler, SIGNAL(commandBufferChanged(QString)), if (usePlainTextEdit) {
this, SLOT(changeStatusMessage(QString))); m_textedit = 0;
QObject::connect(&m_handler, SIGNAL(extraInformationChanged(QString)), m_plaintextedit = new QPlainTextEdit;
this, SLOT(changeExtraInformation(QString))); } else {
QObject::connect(&m_handler, SIGNAL(statusDataChanged(QString)), m_textedit = new QTextEdit;
this, SLOT(changeStatusData(QString))); m_plaintextedit = 0;
}
m_handler = 0;
}
tst_FakeVim::~tst_FakeVim()
{
delete m_handler;
delete m_textedit;
delete m_plaintextedit;
} }
void tst_FakeVim::setup() void tst_FakeVim::setup()
{ {
delete m_handler;
m_handler = 0;
m_statusMessage.clear(); m_statusMessage.clear();
m_statusData.clear(); m_statusData.clear();
m_infoMessage.clear(); m_infoMessage.clear();
m_editor.setPlainText(lines); if (m_textedit) {
QTextCursor tc = m_editor.textCursor(); m_textedit->setPlainText(lines);
QTextCursor tc = m_textedit->textCursor();
tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
m_editor.setTextCursor(tc); m_textedit->setTextCursor(tc);
m_editor.setPlainText(lines); m_textedit->setPlainText(lines);
//m_editor.show(); m_handler = new FakeVimHandler(m_textedit);
//qApp->exec(); } else {
QCOMPARE(m_editor.toPlainText(), lines); 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) QObject::connect(m_handler, SIGNAL(commandBufferChanged(QString)),
{ this, SLOT(changeStatusMessage(QString)));
m_handler.handleCommand("normal " + command); 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) 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) bool tst_FakeVim::checkContentsHelper(QString want, const char* file, int line)
{ {
QString got = m_editor.toPlainText(); QString got = EDITOR(toPlainText());
int pos = m_editor.textCursor().position(); int pos = EDITOR(textCursor().position());
got = got.left(pos) + "@" + got.mid(pos); got = got.left(pos) + "@" + got.mid(pos);
QStringList wantlist = want.split('\n'); QStringList wantlist = want.split('\n');
QStringList gotlist = got.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__)) \ do { if (!checkHelper(false, cmd, expected, __FILE__, __LINE__)) \
return; } while (0) 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. // Runs an ex command and checks the result.
// Cursor position is marked by a '@' in the expected contents. // Cursor position is marked by a '@' in the expected contents.
#define checkEx(cmd, expected) \ #define checkEx(cmd, expected) \
@@ -183,14 +221,13 @@ QString tst_FakeVim::insertCursor(const QString &needle0)
QString needle = needle0; QString needle = needle0;
needle.remove('@'); needle.remove('@');
QString lines0 = lines; QString lines0 = lines;
lines0.replace(needle, needle0); int pos = lines0.indexOf(needle);
//qDebug() << "LINES: " << lines0; lines0.replace(pos, needle.size(), needle0);
return lines0; return lines0;
} }
void tst_FakeVim::commandI() void tst_FakeVim::commandI()
{ {
return;
setup(); setup();
// empty insertion at start of document // empty insertion at start of document
@@ -205,6 +242,8 @@ void tst_FakeVim::commandI()
check("ixxx" + escape, "xx@x" + lines); check("ixxx" + escape, "xx@x" + lines);
check("u", "@" + lines); check("u", "@" + lines);
return;
// combine insertions // combine insertions
check("ia" + escape, "@a" + lines); check("ia" + escape, "@a" + lines);
check("ibx" + escape, "b@xa" + lines); check("ibx" + escape, "b@xa" + lines);
@@ -219,28 +258,86 @@ void tst_FakeVim::commandI()
void tst_FakeVim::commandDollar() void tst_FakeVim::commandDollar()
{ {
setup(); setup();
check("j$", insertCursor("<QtCore>@")); move("j$", "<QtCore>@");
//check("j", insertCursor("<QtGui>@")); move("j$", "<QtGui>@");
move("2j", ")@");
} }
void tst_FakeVim::commandDown() void tst_FakeVim::commandDown()
{ {
setup(); setup();
check("j", insertCursor("@#include <QtCore")); move("j", "@#include <QtCore");
check("3j", insertCursor("@int main")); move("3j", "@int main");
check("4j", insertCursor("@ return app.exec()")); move("4j", "@ return app.exec()");
} }
void tst_FakeVim::commandUp() void tst_FakeVim::commandUp()
{ {
setup(); setup();
check("j", insertCursor("@#include <QtCore")); move("j", "@#include <QtCore");
check("3j", insertCursor("@int main")); move("3j", "@int main");
check("4j", insertCursor("@ return app.exec()")); 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" #include "main.moc"

View File

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