Commit 8aa139ea authored by ck's avatar ck
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 6f5cea2a ffaa42e5
......@@ -500,7 +500,7 @@ void CMakeProject::setUserEnvironmentChanges(const QString &buildConfig, const Q
QStringList list = EnvironmentItem::toStringList(diff);
if (list == value(buildConfig, "userEnvironmentChanges"))
return;
setValue(buildConfig, "userEnvironmentChanges", EnvironmentItem::toStringList(diff));
setValue(buildConfig, "userEnvironmentChanges", list);
emit environmentChanged(buildConfig);
}
......
......@@ -527,8 +527,6 @@ CPPEditorEditable::CPPEditorEditable(CPPEditor *editor)
CPPEditor::CPPEditor(QWidget *parent)
: TextEditor::BaseTextEditor(parent)
, m_mouseNavigationEnabled(true)
, m_showingLink(false)
, m_currentRenameSelection(-1)
, m_inRename(false)
{
......@@ -1073,7 +1071,7 @@ void CPPEditor::switchDeclarationDefinition()
}
CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
bool lookupDefinition)
bool resolveTarget)
{
Link link;
......@@ -1153,7 +1151,7 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
if (Symbol *symbol = result.second) {
Symbol *def = 0;
if (lookupDefinition && !lastSymbol->isFunction())
if (resolveTarget && !lastSymbol->isFunction())
def = findDefinition(symbol);
link = linkToSymbol(def ? def : symbol);
......@@ -1190,7 +1188,7 @@ CPPEditor::Link CPPEditor::findLinkAt(const QTextCursor &cursor,
void CPPEditor::jumpToDefinition()
{
openCppEditorAt(findLinkAt(textCursor()));
openLink(findLinkAt(textCursor()));
}
Symbol *CPPEditor::findDefinition(Symbol *symbol)
......@@ -1342,68 +1340,6 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
delete menu;
}
void CPPEditor::mouseMoveEvent(QMouseEvent *e)
{
bool linkFound = false;
if (m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier) {
// Link emulation behaviour for 'go to definition'
const QTextCursor cursor = cursorForPosition(e->pos());
// Check that the mouse was actually on the text somewhere
bool onText = cursorRect(cursor).right() >= e->x();
if (!onText) {
QTextCursor nextPos = cursor;
nextPos.movePosition(QTextCursor::Right);
onText = cursorRect(nextPos).right() >= e->x();
}
const Link link = findLinkAt(cursor, false);
if (onText && !link.fileName.isEmpty()) {
showLink(link);
linkFound = true;
}
}
if (!linkFound)
clearLink();
TextEditor::BaseTextEditor::mouseMoveEvent(e);
}
void CPPEditor::mouseReleaseEvent(QMouseEvent *e)
{
if (m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier
&& !(e->modifiers() & Qt::ShiftModifier)
&& e->button() == Qt::LeftButton) {
const QTextCursor cursor = cursorForPosition(e->pos());
if (openCppEditorAt(findLinkAt(cursor))) {
clearLink();
e->accept();
return;
}
}
TextEditor::BaseTextEditor::mouseReleaseEvent(e);
}
void CPPEditor::leaveEvent(QEvent *e)
{
clearLink();
TextEditor::BaseTextEditor::leaveEvent(e);
}
void CPPEditor::keyReleaseEvent(QKeyEvent *e)
{
// Clear link emulation when Ctrl is released
if (e->key() == Qt::Key_Control)
clearLink();
TextEditor::BaseTextEditor::keyReleaseEvent(e);
}
void CPPEditor::keyPressEvent(QKeyEvent *e)
{
if (m_currentRenameSelection == -1) {
......@@ -1491,29 +1427,6 @@ void CPPEditor::keyPressEvent(QKeyEvent *e)
TextEditor::BaseTextEditor::keyPressEvent(e);
}
void CPPEditor::showLink(const Link &link)
{
QTextEdit::ExtraSelection sel;
sel.cursor = textCursor();
sel.cursor.setPosition(link.pos);
sel.cursor.setPosition(link.pos + link.length, QTextCursor::KeepAnchor);
sel.format = m_linkFormat;
sel.format.setFontUnderline(true);
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel);
viewport()->setCursor(Qt::PointingHandCursor);
m_showingLink = true;
}
void CPPEditor::clearLink()
{
if (!m_showingLink)
return;
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>());
viewport()->setCursor(Qt::IBeamCursor);
m_showingLink = false;
}
QList<int> CPPEditorEditable::context() const
{
return m_context;
......@@ -1557,17 +1470,10 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs)
highlighter->setFormats(formats.constBegin(), formats.constEnd());
highlighter->rehighlight();
m_linkFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_LINK));
m_occurrencesFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES));
m_occurrenceRenameFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES_RENAME));
}
void CPPEditor::setDisplaySettings(const TextEditor::DisplaySettings &ds)
{
TextEditor::BaseTextEditor::setDisplaySettings(ds);
m_mouseNavigationEnabled = ds.m_mouseNavigation;
}
void CPPEditor::unCommentSelection()
{
Core::Utils::unCommentSelection(this);
......
......@@ -193,7 +193,6 @@ public:
public Q_SLOTS:
virtual void setFontSettings(const TextEditor::FontSettings &);
virtual void setDisplaySettings(const TextEditor::DisplaySettings &);
void setSortedMethodOverview(bool sort);
void switchDeclarationDefinition();
void jumpToDefinition();
......@@ -208,10 +207,6 @@ public Q_SLOTS:
protected:
bool event(QEvent *e);
void contextMenuEvent(QContextMenuEvent *);
void mouseMoveEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
void leaveEvent(QEvent *);
void keyReleaseEvent(QKeyEvent *);
void keyPressEvent(QKeyEvent *);
TextEditor::BaseTextEditorEditable *createEditableInterface();
......@@ -261,36 +256,11 @@ private:
const QString &text = QString());
void abortRename();
struct Link
{
Link(const QString &fileName = QString(),
int line = 0,
int column = 0)
: pos(-1)
, length(-1)
, fileName(fileName)
, line(line)
, column(column)
{}
int pos; // Link position
int length; // Link length
QString fileName; // Target file
int line; // Target line
int column; // Target column
};
void showLink(const Link &);
void clearLink();
Link findLinkAt(const QTextCursor &, bool lookupDefinition = true);
static Link linkToSymbol(CPlusPlus::Symbol *symbol);
Link findLinkAt(const QTextCursor &, bool resolveTarget = true);
bool openLink(const Link &link) { return openCppEditorAt(link); }
bool openCppEditorAt(const Link &);
bool m_mouseNavigationEnabled;
bool m_showingLink;
QTextCharFormat m_linkFormat;
static Link linkToSymbol(CPlusPlus::Symbol *symbol);
CppTools::CppModelManagerInterface *m_modelManager;
......
......@@ -73,6 +73,8 @@ void CppHighlighter::highlightBlock(const QString &text)
userData->setCollapseMode(TextBlockUserData::NoCollapse);
}
TextEditDocumentLayout::clearParentheses(currentBlock());
if (text.length()) // the empty line can still contain whitespace
setFormat(0, text.length(), visualSpaceFormat);
return;
}
......@@ -171,7 +173,7 @@ void CppHighlighter::highlightBlock(const QString &text)
}
// mark the trailing white spaces
if (! tokens.isEmpty()) {
{
const SimpleToken tk = tokens.last();
const int lastTokenEnd = tk.position() + tk.length();
if (text.length() > lastTokenEnd)
......
......@@ -87,5 +87,7 @@ include(cdb/cdb.pri)
include(gdb/gdb.pri)
include(script/script.pri)
include(tcf/tcf.pri)
include(symbian/symbian.pri)
include(shared/shared.pri)
OTHER_FILES += Debugger.pluginspec
......@@ -103,6 +103,8 @@ namespace Internal {
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *);
IDebuggerEngine *createSymbianEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *);
QDebug operator<<(QDebug str, const DebuggerStartParameters &p)
{
QDebug nospace = str.nospace();
......
......@@ -144,7 +144,7 @@ static QByteArray parsePlainConsoleStream(const GdbResultRecord &record)
//
///////////////////////////////////////////////////////////////////////
GdbEngine::GdbEngine(DebuggerManager *parent) :
GdbEngine::GdbEngine(DebuggerManager *parent, GdbProcessBase *gdbProc) :
#ifdef Q_OS_WIN // Do injection loading with MinGW (call loading does not work with 64bit)
m_dumperInjectionLoad(true),
#else
......@@ -153,6 +153,7 @@ GdbEngine::GdbEngine(DebuggerManager *parent) :
q(parent),
qq(parent->engineInterface())
{
m_gdbProc = gdbProc;
m_stubProc.setMode(Core::Utils::ConsoleProcess::Debug);
#ifdef Q_OS_UNIX
m_stubProc.setSettings(Core::ICore::instance()->settings());
......@@ -164,19 +165,20 @@ GdbEngine::GdbEngine(DebuggerManager *parent) :
GdbEngine::~GdbEngine()
{
// prevent sending error messages afterwards
m_gdbProc.disconnect(this);
m_gdbProc->disconnect(this);
delete m_gdbProc;
}
void GdbEngine::initializeConnections()
{
// Gdb Process interaction
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
connect(m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(gdbProcError(QProcess::ProcessError)));
connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
connect(m_gdbProc, SIGNAL(readyReadStandardOutput()),
this, SLOT(readGdbStandardOutput()));
connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
connect(m_gdbProc, SIGNAL(readyReadStandardError()),
this, SLOT(readGdbStandardError()));
connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
connect(m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
q, SLOT(exitDebugger()));
connect(&m_stubProc, SIGNAL(processError(QString)),
......@@ -614,7 +616,7 @@ void GdbEngine::stubError(const QString &msg)
void GdbEngine::readGdbStandardError()
{
qWarning() << "Unexpected gdb stderr:" << m_gdbProc.readAllStandardError();
qWarning() << "Unexpected gdb stderr:" << m_gdbProc->readAllStandardError();
}
void GdbEngine::readGdbStandardOutput()
......@@ -622,7 +624,7 @@ void GdbEngine::readGdbStandardOutput()
int newstart = 0;
int scan = m_inbuffer.size();
m_inbuffer.append(m_gdbProc.readAllStandardOutput());
m_inbuffer.append(m_gdbProc->readAllStandardOutput());
while (newstart < m_inbuffer.size()) {
int start = newstart;
......@@ -651,7 +653,7 @@ void GdbEngine::interruptInferior()
{
qq->notifyInferiorStopRequested();
if (m_gdbProc.state() == QProcess::NotRunning) {
if (m_gdbProc->state() == QProcess::NotRunning) {
debugMessage(_("TRYING TO INTERRUPT INFERIOR WITHOUT RUNNING GDB"));
qq->notifyInferiorExited();
return;
......@@ -698,7 +700,7 @@ void GdbEngine::postCommand(const QString &command, GdbCommandFlags flags,
GdbCommandCallback callback, const char *callbackName,
const QVariant &cookie)
{
if (m_gdbProc.state() == QProcess::NotRunning) {
if (m_gdbProc->state() == QProcess::NotRunning) {
debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + command);
return;
}
......@@ -742,7 +744,7 @@ void GdbEngine::flushCommand(GdbCommand &cmd)
if (cmd.flags & EmbedToken)
cmd.command = cmd.command.arg(currentToken());
m_gdbProc.write(cmd.command.toLatin1() + "\r\n");
m_gdbProc->write(cmd.command.toLatin1() + "\r\n");
//emit gdbInputAvailable(QString(), " " + currentTime());
//emit gdbInputAvailable(QString(), "[" + currentTime() + "] " + cmd.command);
emit gdbInputAvailable(LogInput, cmd.command);
......@@ -829,12 +831,12 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record)
void GdbEngine::executeDebuggerCommand(const QString &command)
{
if (m_gdbProc.state() == QProcess::NotRunning) {
if (m_gdbProc->state() == QProcess::NotRunning) {
debugMessage(_("NO GDB PROCESS RUNNING, PLAIN CMD IGNORED: ") + command);
return;
}
m_gdbProc.write(command.toLocal8Bit() + "\r\n");
m_gdbProc->write(command.toLocal8Bit() + "\r\n");
}
void GdbEngine::handleTargetCore(const GdbResultRecord &, const QVariant &)
......@@ -1434,15 +1436,15 @@ void GdbEngine::detachDebugger()
void GdbEngine::exitDebugger()
{
debugMessage(_("GDBENGINE EXITDEBUGGER: %1").arg(m_gdbProc.state()));
if (m_gdbProc.state() == QProcess::Starting) {
debugMessage(_("GDBENGINE EXITDEBUGGER: %1").arg(m_gdbProc->state()));
if (m_gdbProc->state() == QProcess::Starting) {
debugMessage(_("WAITING FOR GDB STARTUP TO SHUTDOWN: %1")
.arg(m_gdbProc.state()));
m_gdbProc.waitForStarted();
.arg(m_gdbProc->state()));
m_gdbProc->waitForStarted();
}
if (m_gdbProc.state() == QProcess::Running) {
if (m_gdbProc->state() == QProcess::Running) {
debugMessage(_("WAITING FOR RUNNING GDB TO SHUTDOWN: %1")
.arg(m_gdbProc.state()));
.arg(m_gdbProc->state()));
if (q->status() != DebuggerInferiorStopped
&& q->status() != DebuggerProcessStartingUp) {
QTC_ASSERT(q->status() == DebuggerInferiorRunning,
......@@ -1455,17 +1457,17 @@ void GdbEngine::exitDebugger()
postCommand(_("kill"));
postCommand(_("-gdb-exit"), CB(handleExit));
// 20s can easily happen when loading webkit debug information
if (!m_gdbProc.waitForFinished(20000)) {
if (!m_gdbProc->waitForFinished(20000)) {
debugMessage(_("FORCING TERMINATION: %1")
.arg(m_gdbProc.state()));
m_gdbProc.terminate();
m_gdbProc.waitForFinished(20000);
.arg(m_gdbProc->state()));
m_gdbProc->terminate();
m_gdbProc->waitForFinished(20000);
}
}
if (m_gdbProc.state() != QProcess::NotRunning) {
if (m_gdbProc->state() != QProcess::NotRunning) {
debugMessage(_("PROBLEM STOPPING DEBUGGER: STATE %1")
.arg(m_gdbProc.state()));
m_gdbProc.kill();
.arg(m_gdbProc->state()));
m_gdbProc->kill();
}
m_outputCollector.shutdown();
......@@ -1487,9 +1489,9 @@ bool GdbEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
QStringList gdbArgs;
if (m_gdbProc.state() != QProcess::NotRunning) {
debugMessage(_("GDB IS ALREADY RUNNING, STATE: %1").arg(m_gdbProc.state()));
m_gdbProc.kill();
if (m_gdbProc->state() != QProcess::NotRunning) {
debugMessage(_("GDB IS ALREADY RUNNING, STATE: %1").arg(m_gdbProc->state()));
m_gdbProc->kill();
return false;
}
......@@ -1529,16 +1531,16 @@ bool GdbEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
gdbArgs.prepend(_("--tty=") + m_outputCollector.serverName());
if (!sp->workingDir.isEmpty())
m_gdbProc.setWorkingDirectory(sp->workingDir);
m_gdbProc->setWorkingDirectory(sp->workingDir);
if (!sp->environment.isEmpty())
m_gdbProc.setEnvironment(sp->environment);
m_gdbProc->setEnvironment(sp->environment);
}
#if 0
qDebug() << "Command:" << q->settings()->m_gdbCmd;
qDebug() << "WorkingDirectory:" << m_gdbProc.workingDirectory();
qDebug() << "WorkingDirectory:" << m_gdbProc->workingDirectory();
qDebug() << "ScriptFile:" << q->settings()->m_scriptFile;
qDebug() << "Environment:" << m_gdbProc.environment();
qDebug() << "Environment:" << m_gdbProc->environment();
qDebug() << "Arguments:" << gdbArgs;
qDebug() << "BuildDir:" << sp->buildDir;
qDebug() << "ExeFile:" << sp->executable;
......@@ -1546,10 +1548,10 @@ bool GdbEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
QString loc = theDebuggerStringSetting(GdbLocation);
q->showStatusMessage(tr("Starting Debugger: ") + loc + _c(' ') + gdbArgs.join(_(" ")));
m_gdbProc.start(loc, gdbArgs);
if (!m_gdbProc.waitForStarted()) {
m_gdbProc->start(loc, gdbArgs);
if (!m_gdbProc->waitForStarted()) {
QMessageBox::critical(q->mainWindow(), tr("Debugger Startup Failure"),
tr("Cannot start debugger: %1").arg(m_gdbProc.errorString()));
tr("Cannot start debugger: %1").arg(m_gdbProc->errorString()));
m_outputCollector.shutdown();
m_stubProc.blockSignals(true);
m_stubProc.stop();
......@@ -4198,7 +4200,7 @@ void GdbEngine::handleFetchDisassemblerByAddress0(const GdbResultRecord &record,
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts)
{
opts->push_back(new GdbOptionsPage);
return new GdbEngine(parent);
return new GdbEngine(parent, new GdbProcess);
}
} // namespace Internal
......
......@@ -32,6 +32,7 @@
#include "idebuggerengine.h"
#include "gdbmi.h"
#include "gdbprocessbase.h"
#include "outputcollector.h"
#include "watchutils.h"
......@@ -56,6 +57,7 @@ QT_END_NAMESPACE
namespace Debugger {
namespace Internal {
class DebuggerManager;
class IDebuggerManagerAccessForEngines;
class GdbResultRecord;
......@@ -72,13 +74,46 @@ enum DebuggingHelperState
DebuggingHelperUnavailable,
};
class GdbProcess : public GdbProcessBase
{
public:
GdbProcess(QObject *parent = 0)
: GdbProcessBase(parent)
{
connect(&m_proc, SIGNAL(error(QProcess::ProcessError)),
this, SIGNAL(error(QProcess::ProcessError)));
connect(&m_proc, SIGNAL(readyReadStandardOutput()),
this, SIGNAL(readyReadStandardOutput()));
connect(&m_proc, SIGNAL(readyReadStandardError()),
this, SIGNAL(readyReadStandardError()));
connect(&m_proc, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SIGNAL(finished(int, QProcess::ExitStatus)));
}
void start(const QString &program, const QStringList &args,
QIODevice::OpenMode mode) { m_proc.start(program, args, mode); }
void kill() { m_proc.kill(); }
void terminate() { m_proc.terminate(); }
bool waitForStarted(int msecs) { return m_proc.waitForStarted(msecs); }
bool waitForFinished(int msecs) { return m_proc.waitForFinished(msecs); }
QProcess::ProcessState state() const { return m_proc.state(); }
QString errorString() const { return m_proc.errorString(); }
QByteArray readAllStandardError() { return m_proc.readAllStandardError(); }
QByteArray readAllStandardOutput() { return m_proc.readAllStandardOutput(); }
qint64 write(const char *data) { return m_proc.write(data); }
void setWorkingDirectory(const QString &dir) { m_proc.setWorkingDirectory(dir); }
void setEnvironment(const QStringList &env) { m_proc.setEnvironment(env); }
private:
QProcess m_proc;
};
class GdbEngine : public IDebuggerEngine
{
Q_OBJECT
public:
GdbEngine(DebuggerManager *parent);
GdbEngine(DebuggerManager *parent, GdbProcessBase *gdbProc);
~GdbEngine();
signals:
......@@ -251,7 +286,7 @@ private:
QByteArray m_inbuffer;
QProcess m_gdbProc;
GdbProcessBase *m_gdbProc;
QProcess m_uploadProc;
Core::Utils::ConsoleProcess m_stubProc;
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef DEBUGGER_PROCESSBASE_H
#define DEBUGGER_PROCESSBASE_H
#include <QtCore/QObject>
#include <QtCore/QProcess>
namespace Debugger {
namespace Internal {
// GdbProcessBase is inherited by GdbProcess and the gdb/trk Adapter.
// In the GdbProcess case it's just a wrapper around a QProcess running
// gdb, in the Adapter case it's the interface to the gdb process in
// the whole rfomm/gdb/gdbserver combo.
class GdbProcessBase : public QObject
{
Q_OBJECT
public:
GdbProcessBase(QObject *parent = 0) : QObject(parent) {}
virtual void start(const QString &program, const QStringList &args,
QIODevice::OpenMode mode = QIODevice::ReadWrite) = 0;
virtual void kill() = 0;
virtual void terminate() = 0;
virtual bool waitForStarted(int msecs = 30000) = 0;
virtual bool waitForFinished(int msecs = 30000) = 0;
virtual QProcess::ProcessState state() const = 0;
virtual QString errorString() const = 0;
virtual QByteArray readAllStandardError() = 0;
virtual QByteArray readAllStandardOutput() = 0;
virtual qint64 write(const char *data) = 0;
virtual void setWorkingDirectory(const QString &dir) = 0;
virtual void setEnvironment(const QStringList &env) = 0;
signals: