Merge commit 'origin/1.3'

Conflicts:
	src/plugins/debugger/gdb/gdbengine.cpp
	src/plugins/qt4projectmanager/qt4project.cpp
This commit is contained in:
con
2009-11-03 18:08:01 +01:00
50 changed files with 22332 additions and 1893 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

View File

@@ -180,7 +180,7 @@
/*! \contentspage index.html
\previouspage creator-quick-tour.html
\page creator-code-editor.html
\nextpage creator-build-settings.html
\nextpage creator-project-pane.html
\title The Code Editor
@@ -318,10 +318,10 @@
/*!
\contentspage index.html
\previouspage creator-code-editor.html
\page creator-build-settings.html
\page creator-project-pane.html
\nextpage creator-version-management.html
\title Build Settings
\title Project Settings
\table
\row
@@ -330,56 +330,63 @@
\l{CMake Support in Qt Creator}.
\endtable
To modify the build settings of your project, switch to the \gui{Projects}
mode using the mouse or with \key{Ctrl+4}.
To modify the project settings of your project, switch to the \gui{Projects}
mode using the mouse or \key{Ctrl+4}.
\image qtcreator-buildsettingstab.png
\image qtcreator-projectpane.png
Action items to create, clone, or delete build configurations can be found
at the bottom of the dialog. You can have as many build configurations as
needed. By default Qt Creator creates a \bold{debug} and \bold{release}
build configuration. Both these configurations use the
\l{glossary-default-qt}{Default Qt Version}.
The project pane is divided into two areas. At the top the currently active
settings are shown. The active build or run configuration for all projects
can be changed there. The bottom area allows you to quickly get an overview
of the build, run and editor settings as well as the dependencies between your
projects. It also allows you to edit those settings.
In the tree on the left, a list of build configurations and their settings
are displayed. The screenshot above shows the \bold{debug} and
\bold{release} configurations and their corresponding settings:
\bold{Build Environment} and \bold{Build Steps}.
\section1 Build Settings
When you select a build configuration in the tree, a configuration page for
general build settings will be displayed. Here you can specify which
\l{glossary-project-qt}{Qt version} to use to build your project, whether
Build configurations allow you to quickly switch between different build
settings. By default Qt Creator Qt Creator creates a \bold{debug} and
\bold{release} build configuration. Both these configurations use the
\l{glossary-default-qt}{Default Qt Version}. Action items to create, clone,
or delete build configurations can be found at the top. You can have as
many build configurations as needed. To edit settings click on the
\gui{Show Details} button. Here you can specify which
\l{glossary-project-qt}{Qt version} to use to build your project, or whether
to \l{glossary-shadow-build}{shadow build} the project, for instance.
\image qtcreator-buildenvironment.png
\image qtcreator-ppbuildsettings.png
In the \bold{Build Environment} page you can specify the environment used
The build system of Qt Creator is built on top of \c qmake and \c make. The
settings for \c qmake and \c make can be changed. Qt Creator will run the
make command using the correct Qt version.
In the \bold{Build Environment} section you can specify the environment used
for building. By default the environment in which Qt Creator was started
is used and modified to include the Qt version. Depending on the selected
Qt version, Qt Creator will automatically set the necessary environment
variables.
\image qtcreator-buildsteps.png
\section1 Run Settings
The build system of Qt Creator is built on top of \c qmake and \c make. The
settings for \c qmake and \c make can be changed in the
\bold{Build Settings} page. Qt Creator will run the make command using the
correct Qt version.
\image qtcreator-pprunsettings.png
Qt Creator automatically creates run configurations for your project.
These run configurations derive their executable
from the parsed .pro files. You can also create \bold{custom executable}
run configurations where you can freely set the executable to be run.
\section1 Dependencies
If you have multiple projects loaded in your session, you can configure
dependencies between them. This will affect the build order of your
projects. To do this, go the the \bold{Dependencies} tab after selecting
projects. To do this, go the the \bold{Dependencies} section after selecting
the project for which you want to configure the dependencies, and then use
the checkboxes to check which of the other projects is a dependency.
\note This is unrelated to the dependencies inside a qmake project.
*/
/*!
\contentspage index.html
\previouspage creator-build-settings.html
\previouspage creator-project-pane.html
\page creator-version-management.html
\nextpage creator-creating-project.html
@@ -1423,7 +1430,8 @@
\title CMake Support in Qt Creator
Since Qt Creator 1.1, support for \c CMake project files is available.
Qt Creator 1.3 supports the Microsoft Toolchain if the cmake version
is at least 2.8.
\section1 Opening CMake Projects
@@ -1446,9 +1454,9 @@
\section1 Building CMake Projects
Qt Creator builds \c CMake Projects by running \c make or \c mingw32-make,
depending on your platform. The build errors and warnings are parsed and
displayed in the \gui{Build Issues} output pane.
Qt Creator builds \c CMake Projects by running \c make, \c mingw32-make, or
\c nmake depending on your platform. The build errors and warnings are
parsed and displayed in the \gui{Build Issues} output pane.
By default Qt Creator builds the \e{all} target. You can specify which
targets to build in \gui{Project} mode, under \gui{Build Settings}.
@@ -1458,7 +1466,6 @@
Qt Creator supports multiple build configurations. Also, the build
directory can be modified after the initial import.
\section1 Running CMake Projects
Qt Creator automatically adds \gui{Run Configurations} for all targets
specified in the \c CMake project file.

View File

@@ -12575,12 +12575,12 @@ Installiere Anwendung auf &apos;%2&apos;...</translation>
<message>
<location filename="../../../src/plugins/qt4projectmanager/qt4project.cpp" line="+252"/>
<source>Using Default Qt Version</source>
<translation>Es wird die Vorgabe-Qt-Version benutzt</translation>
<translation>Vorgabe-Qt-Version verwenden</translation>
</message>
<message>
<location line="+4"/>
<source>Using Qt Version &quot;%1&quot;</source>
<translation>Es wird die Qt-Version &quot;%1&quot; benutzt</translation>
<translation>Qt-Version &quot;%1&quot; verwenden</translation>
</message>
<message>
<location line="+26"/>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
include(../../../qtcreator.pri)
LANGUAGES = de es fr it ja pl ru
LANGUAGES = de es fr it ja pl ru sl
# var, prepend, append
defineReplace(prependAll) {

View File

@@ -131,6 +131,11 @@ int BackwardsScanner::previousBlockState(const QTextBlock &block) const
return 0;
}
int BackwardsScanner::size() const
{
return _tokens.size();
}
int BackwardsScanner::startOfMatchingBrace(int index) const
{
const BackwardsScanner &tk = *this;

View File

@@ -69,6 +69,8 @@ public:
int previousBlockState(const QTextBlock &block) const;
int size() const;
private:
const SimpleToken &fetchToken(int i);

View File

@@ -122,6 +122,7 @@ NewClassWidget::NewClassWidget(QWidget *parent) :
m_d->m_ui.generateFormCheckBox->setChecked(true);
setFormInputCheckable(false, true);
setClassType(NoClassType);
}
NewClassWidget::~NewClassWidget()
@@ -172,17 +173,6 @@ void NewClassWidget::setBaseClassInputVisible(bool visible)
m_d->m_ui.baseClassComboBox->setVisible(visible);
}
void NewClassWidget::setQObjectCheckBoxVisible(bool visible)
{
m_d->m_qobjectCheckBoxVisible = visible;
m_d->m_ui.qobjectCheckBox->setVisible(visible);
}
bool NewClassWidget::isQObjectCheckBoxVisible() const
{
return m_d->m_qobjectCheckBoxVisible;
}
void NewClassWidget::setBaseClassEditable(bool editable)
{
m_d->m_ui.baseClassComboBox->setEditable(editable);
@@ -370,16 +360,6 @@ void NewClassWidget::setAllowDirectories(bool v)
}
}
bool NewClassWidget::inheritsQObject() const
{
return m_d->m_ui.qobjectCheckBox->isChecked();
}
void NewClassWidget::setInheritsQObject(bool v)
{
m_d->m_ui.qobjectCheckBox->setChecked(v);
}
bool NewClassWidget::lowerCaseFiles() const
{
return m_d->m_ui.classLineEdit->lowerCaseFileName();
@@ -390,6 +370,27 @@ void NewClassWidget::setLowerCaseFiles(bool v)
m_d->m_ui.classLineEdit->setLowerCaseFileName(v);
}
NewClassWidget::ClassType NewClassWidget::classType() const
{
return static_cast<ClassType>(m_d->m_ui.classTypeComboBox->currentIndex());
}
void NewClassWidget::setClassType(ClassType ct)
{
m_d->m_ui.classTypeComboBox->setCurrentIndex(ct);
}
bool NewClassWidget::isClassTypeComboVisible() const
{
return m_d->m_ui.classTypeLabel->isVisible();
}
void NewClassWidget::setClassTypeComboVisible(bool v)
{
m_d->m_ui.classTypeLabel->setVisible(v);
m_d->m_ui.classTypeComboBox->setVisible(v);
}
void NewClassWidget::slotValidChanged()
{
const bool newValid = isValid();

View File

@@ -57,7 +57,7 @@ class QTCREATOR_UTILS_EXPORT NewClassWidget : public QWidget
Q_PROPERTY(bool baseClassEditable READ isBaseClassEditable WRITE setBaseClassEditable DESIGNABLE false)
Q_PROPERTY(bool formInputVisible READ isFormInputVisible WRITE setFormInputVisible DESIGNABLE true)
Q_PROPERTY(bool pathInputVisible READ isPathInputVisible WRITE setPathInputVisible DESIGNABLE true)
Q_PROPERTY(bool qobjectCheckBoxVisible READ isQObjectCheckBoxVisible WRITE setQObjectCheckBoxVisible DESIGNABLE true)
Q_PROPERTY(bool classTypeComboVisible READ isClassTypeComboVisible WRITE setClassTypeComboVisible DESIGNABLE true)
Q_PROPERTY(QString className READ className WRITE setClassName DESIGNABLE true)
Q_PROPERTY(QString baseClassName READ baseClassName WRITE setBaseClassName DESIGNABLE true)
Q_PROPERTY(QString sourceFileName READ sourceFileName DESIGNABLE false)
@@ -71,11 +71,14 @@ class QTCREATOR_UTILS_EXPORT NewClassWidget : public QWidget
Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true)
Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true)
Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
Q_PROPERTY(bool inheritsQObject READ inheritsQObject WRITE setInheritsQObject)
Q_PROPERTY(bool lowerCaseFiles READ lowerCaseFiles WRITE setLowerCaseFiles)
Q_PROPERTY(ClassType classType READ classType WRITE setClassType)
// Utility "USER" property for wizards containing file names.
Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true)
Q_ENUMS(ClassType)
public:
enum ClassType { NoClassType, ClassInheritsQObject, ClassInheritsQWidget };
explicit NewClassWidget(QWidget *parent = 0);
~NewClassWidget();
@@ -84,7 +87,6 @@ public:
bool isBaseClassEditable() const;
bool isFormInputVisible() const;
bool isPathInputVisible() const;
bool isQObjectCheckBoxVisible() const;
bool formInputCheckable() const;
bool formInputChecked() const;
@@ -98,9 +100,10 @@ public:
QString sourceExtension() const;
QString headerExtension() const;
QString formExtension() const;
bool inheritsQObject() const;
bool allowDirectories() const;
bool lowerCaseFiles() const;
ClassType classType() const;
bool isClassTypeComboVisible() const;
bool isValid(QString *error = 0) const;
@@ -118,7 +121,6 @@ public slots:
void setPathInputVisible(bool visible);
void setFormInputCheckable(bool v);
void setFormInputChecked(bool v);
void setQObjectCheckBoxVisible(bool v);
/**
* The name passed into the new class widget will be reformatted to be a
@@ -131,9 +133,10 @@ public slots:
void setSourceExtension(const QString &e);
void setHeaderExtension(const QString &e);
void setFormExtension(const QString &e);
void setInheritsQObject(bool v);
void setAllowDirectories(bool v);
void setLowerCaseFiles(bool v);
void setClassType(ClassType ct);
void setClassTypeComboVisible(bool v);
/**
* Suggest a class name from the base class by stripping the leading 'Q'
@@ -153,7 +156,6 @@ private slots:
void classNameEdited();
void slotFormInputChecked();
private:
void setFormInputCheckable(bool checkable, bool force);

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>213</width>
<height>190</height>
<width>418</width>
<height>291</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@@ -44,6 +44,32 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="classTypeLabel">
<property name="text">
<string>Type information:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="classTypeComboBox">
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Inherits QObject</string>
</property>
</item>
<item>
<property name="text">
<string>Inherits QWidget</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
@@ -54,8 +80,8 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@@ -70,8 +96,8 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@@ -103,6 +129,13 @@
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="generateFormCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="formLabel">
<property name="text">
@@ -121,41 +154,27 @@
</widget>
</item>
<item row="8" column="1">
<widget class="Utils::PathChooser" name="pathChooser" native="true"/>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="generateFormCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="qobjectCheckBox">
<property name="text">
<string>Inherits QObject</string>
</property>
</widget>
<widget class="Utils::PathChooser" name="pathChooser"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">pathchooser.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Utils::ClassNameValidatingLineEdit</class>
<extends>QLineEdit</extends>
<header>classnamevalidatinglineedit.h</header>
<header location="global">utils/classnamevalidatinglineedit.h</header>
</customwidget>
<customwidget>
<class>Utils::FileNameValidatingLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">utils/filenamevalidatinglineedit.h</header>
</customwidget>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@@ -85,7 +85,6 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
setPage(CMakeRunPageId, new CMakeRunPage(this));
setStartId(startid);
setOption(QWizard::NoCancelButton);
init();
}
@@ -101,7 +100,6 @@ CMakeOpenProjectWizard::CMakeOpenProjectWizard(CMakeManager *cmakeManager, const
addPage(new CMakeRunPage(this, CMakeRunPage::Recreate, buildDirectory));
else
addPage(new CMakeRunPage(this, CMakeRunPage::Update, buildDirectory));
setOption(QWizard::NoCancelButton);
init();
}

View File

@@ -648,7 +648,8 @@ bool CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader
// and the cmake command line
CMakeOpenProjectWizard copw(m_manager, sourceDirectory(), ProjectExplorer::Environment::systemEnvironment());
copw.exec();
if (copw.exec() != QDialog::Accepted)
return false;
qDebug()<<"ccd.buildDirectory()"<<copw.buildDirectory();
@@ -690,7 +691,8 @@ bool CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader
buildDirectory(activeBC),
mode,
environment(activeBC));
copw.exec();
if (copw.exec() != QDialog::Accepted)
return false;
activeBC->setValue("msvcVersion", copw.msvcVersion());
}
}

View File

@@ -155,7 +155,7 @@ CppClassWizardParameters CppClassWizardDialog::parameters() const
rc.sourceFile = ncw->sourceFileName();
rc.baseClass = ncw->baseClassName();
rc.path = ncw->path();
rc.inheritsQObject = ncw->inheritsQObject();
rc.classType = ncw->classType();
return rc;
}
@@ -217,7 +217,8 @@ bool CppClassWizard::generateHeaderAndSource(const CppClassWizardParameters &par
QString *header, QString *source)
{
// TODO:
// Quite a bit of this code has been copied from FormClassWizardParameters::generateCpp.
// Quite a bit of this code has been copied from FormClassWizardParameters::generateCpp
// and is duplicated in the library wizard.
// Maybe more of it could be merged into Utils.
const QString indent = QString(4, QLatin1Char(' '));
@@ -239,10 +240,27 @@ bool CppClassWizard::generateHeaderAndSource(const CppClassWizardParameters &par
const QRegExp qtClassExpr(QLatin1String("^Q[A-Z3].+"));
QTC_ASSERT(qtClassExpr.isValid(), /**/);
const bool superIsQtClass = qtClassExpr.exactMatch(params.baseClass);
// Determine parent QObject type for Qt types. Provide base
// class in case the user did not specify one.
QString parentQObjectClass;
bool defineQObjectMacro = false;
switch(params.classType) {
case Utils::NewClassWidget::ClassInheritsQObject:
parentQObjectClass = QLatin1String("QObject");
defineQObjectMacro = true;
break;
case Utils::NewClassWidget::ClassInheritsQWidget:
parentQObjectClass = QLatin1String("QWidget");
defineQObjectMacro = true;
break;
}
const QString baseClass = params.baseClass.isEmpty()
&& params.classType != Utils::NewClassWidget::NoClassType ?
parentQObjectClass : params.baseClass;
const bool superIsQtClass = qtClassExpr.exactMatch(baseClass);
if (superIsQtClass) {
headerStr << '\n';
Utils::writeIncludeFileDirective(params.baseClass, true, headerStr);
Utils::writeIncludeFileDirective(baseClass, true, headerStr);
}
const QString namespaceIndent = Utils::writeOpeningNameSpaces(namespaceList, QString(), headerStr);
@@ -250,15 +268,24 @@ bool CppClassWizard::generateHeaderAndSource(const CppClassWizardParameters &par
// Class declaration
headerStr << '\n';
headerStr << namespaceIndent << "class " << unqualifiedClassName;
if (!params.baseClass.isEmpty())
headerStr << " : public " << params.baseClass << "\n";
if (!baseClass.isEmpty())
headerStr << " : public " << baseClass << "\n";
else
headerStr << "\n";
headerStr << namespaceIndent << "{\n";
if (params.inheritsQObject)
if (defineQObjectMacro)
headerStr << namespaceIndent << "Q_OBJECT\n";
headerStr << namespaceIndent << "public:\n"
<< namespaceIndent << indent << unqualifiedClassName << "();\n";
<< namespaceIndent << indent;
// Constructor
if (parentQObjectClass.isEmpty()) {
headerStr << unqualifiedClassName << "();\n";
} else {
headerStr << "explicit " << unqualifiedClassName << '(' << parentQObjectClass
<< " *parent = 0);\n";
}
if (defineQObjectMacro)
headerStr << '\n' << namespaceIndent << "signals:\n\n" << namespaceIndent << "public slots:\n\n";
headerStr << namespaceIndent << "};\n";
Utils::writeClosingNameSpaces(namespaceList, QString(), headerStr);
@@ -274,7 +301,15 @@ bool CppClassWizard::generateHeaderAndSource(const CppClassWizardParameters &par
Utils::writeOpeningNameSpaces(namespaceList, QString(), sourceStr);
// Constructor
sourceStr << '\n' << namespaceIndent << unqualifiedClassName << "::" << unqualifiedClassName << "()\n";
sourceStr << '\n' << namespaceIndent ;
if (parentQObjectClass.isEmpty()) {
sourceStr << unqualifiedClassName << "::" << unqualifiedClassName << "()\n";
} else {
sourceStr << unqualifiedClassName << "::" << unqualifiedClassName
<< '(' << parentQObjectClass << " *parent) :\n"
<< namespaceIndent << indent << baseClass << "(parent)\n";
}
sourceStr << namespaceIndent << "{\n" << namespaceIndent << "}\n";
Utils::writeClosingNameSpaces(namespaceList, QString(), sourceStr);

View File

@@ -74,7 +74,7 @@ struct CppClassWizardParameters
QString sourceFile;
QString baseClass;
QString path;
bool inheritsQObject;
int classType;
};
class CppClassWizardDialog : public QWizard

View File

@@ -1579,7 +1579,8 @@ void CPPEditor::indentBlock(QTextDocument *doc, QTextBlock block, QChar typedCha
tabSettings().indentLine(block, indent);
return;
} else if ((firstToken.is(T_PUBLIC) || firstToken.is(T_PROTECTED) || firstToken.is(T_PRIVATE) ||
firstToken.is(T_Q_SIGNALS) || firstToken.is(T_Q_SLOTS)) && tk[1].is(T_COLON)) {
firstToken.is(T_Q_SIGNALS) || firstToken.is(T_Q_SLOTS)) &&
tk.size() > 1 && tk[1].is(T_COLON)) {
const int startOfBlock = tk.startOfBlock(0);
if (startOfBlock != 0) {
const int indent = tk.indentation(startOfBlock);
@@ -1643,14 +1644,6 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
QMenu *menu = new QMenu();
// QMenu *menu = createStandardContextMenu();
//
// // Remove insert unicode control character
// QAction *lastAction = menu->actions().last();
// if (lastAction->menu() && QLatin1String(lastAction->menu()->metaObject()->className()) == QLatin1String("QUnicodeControlCharacterMenu"))
// menu->removeAction(lastAction);
Core::ActionManager *am = Core::ICore::instance()->actionManager();
Core::ActionContainer *mcontext = am->actionContainer(CppEditor::Constants::M_CONTEXT);
QMenu *contextMenu = mcontext->menu();
@@ -1661,6 +1654,8 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
const QList<QTextEdit::ExtraSelection> selections =
extraSelections(BaseTextEditor::CodeSemanticsSelection);
appendStandardContextMenuActions(menu);
menu->exec(e->globalPos());
delete menu;
}

View File

@@ -214,12 +214,21 @@ protected:
{ _item = newCompletionItem(name->unqualifiedNameId()); }
};
struct CompleteFunctionDeclaration
{
explicit CompleteFunctionDeclaration(Function *f = 0)
: function(f)
{}
Function *function;
};
} // namespace Internal
} // namespace CppTools
using namespace CppTools::Internal;
Q_DECLARE_METATYPE(CompleteFunctionDeclaration)
void FakeToolTipFrame::paintEvent(QPaintEvent *)
{
@@ -1074,19 +1083,14 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<TypeOfExpressi
Overview overview;
overview.setShowArgumentNames(true);
// get rid of parentheses and cv-qualifiers
QString completion = overview(f->type());
if (f->isVolatile() || f->isConst())
completion = completion.mid(1, completion.lastIndexOf(')') - 1);
else
completion = completion.mid(1, completion.size() - 2);
// gets: "parameter list) cv-spec",
QString completion = overview(f->type()).mid(1);
if (completion.size()) {
TextEditor::CompletionItem item(this);
item.text = completion;
item.data = QVariant::fromValue(CompleteFunctionDeclaration(f));
m_completions.append(item);
}
}
return true;
}
}
@@ -1567,6 +1571,14 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item)
}
}
}
if (m_autoInsertBrackets && item.data.canConvert<CompleteFunctionDeclaration>()) {
// everything from the closing parenthesis on are extra chars, to
// make sure an auto-inserted ")" gets replaced by ") const" if necessary
int closingParen = toInsert.lastIndexOf(QLatin1Char(')'));
extraChars = toInsert.mid(closingParen);
toInsert.truncate(closingParen);
}
}
// Avoid inserting characters that are already there

View File

@@ -57,6 +57,12 @@ const char * const DEBUGGER_SETTINGS_CATEGORY = QT_TRANSLATE_NOOP("Debugger", "D
namespace Internal {
enum { debug = 0 };
#ifdef Q_OS_MAC
const char * const LD_PRELOAD_ENV_VAR = "DYLD_INSERT_LIBRARIES";
#else
const char * const LD_PRELOAD_ENV_VAR = "LD_PRELOAD";
#endif
}
} // namespace Constants
@@ -75,9 +81,11 @@ enum DebuggerState
InferiorStartFailed,
InferiorRunningRequested, // Debuggee requested to run
InferiorRunningRequested_Kill, // Debuggee requested to run, but want to kill it
InferiorRunning, // Debuggee running
InferiorStopping, // Debuggee running, stop requested
InferiorStopping_Kill, // Debuggee running, stop requested, want to kill it
InferiorStopped, // Debuggee stopped
InferiorStopFailed, // Debuggee not stopped, will kill debugger

View File

@@ -192,9 +192,11 @@ const char *DebuggerManager::stateName(int s)
SN(InferiorStarting)
SN(InferiorStartFailed)
SN(InferiorRunningRequested)
SN(InferiorRunningRequested_Kill)
SN(InferiorRunning)
SN(InferiorUnrunnable)
SN(InferiorStopping)
SN(InferiorStopping_Kill)
SN(InferiorStopped)
SN(InferiorStopFailed)
SN(InferiorShuttingDown)
@@ -292,7 +294,8 @@ DebuggerManager *DebuggerManagerPrivate::instance = 0;
DebuggerManagerPrivate::DebuggerManagerPrivate(DebuggerManager *manager)
: m_startParameters(new DebuggerStartParameters),
m_disassemblerViewAgent(manager)
m_disassemblerViewAgent(manager),
m_engine(0)
{
m_inferiorPid = 0;
}
@@ -953,6 +956,8 @@ static IDebuggerEngine *determineDebuggerEngine(int /* pid */,
void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp)
{
if (d->m_state != DebuggerNotReady)
return;
d->m_startParameters = sp;
d->m_inferiorPid = d->m_startParameters->attachPID > 0
? d->m_startParameters->attachPID : 0;
@@ -1563,11 +1568,17 @@ static bool isAllowedTransition(int from, int to)
return to == EngineShuttingDown;
case InferiorRunningRequested:
return to == InferiorRunning || to == InferiorStopped
|| to == InferiorRunningRequested_Kill;
case InferiorRunningRequested_Kill:
return to == InferiorRunning || to == InferiorStopped;
case InferiorRunning:
return to == InferiorStopping;
case InferiorStopping:
return to == InferiorStopped || to == InferiorStopFailed
|| to == InferiorStopping_Kill;
case InferiorStopping_Kill:
return to == InferiorStopped || to == InferiorStopFailed;
case InferiorStopped:
return to == InferiorRunningRequested || to == InferiorShuttingDown;
@@ -1690,6 +1701,8 @@ bool DebuggerManager::debuggerActionsEnabled() const
case AdapterStarted:
case AdapterStartFailed:
case InferiorStartFailed:
case InferiorRunningRequested_Kill:
case InferiorStopping_Kill:
case InferiorStopFailed:
case InferiorShuttingDown:
case InferiorShutDown:

View File

@@ -48,6 +48,11 @@ class AbstractGdbAdapter : public QObject
Q_OBJECT
public:
enum DumperHandling { DumperNotAvailable,
DumperLoadedByAdapter,
DumperLoadedByGdbPreload,
DumperLoadedByGdb };
AbstractGdbAdapter(GdbEngine *engine, QObject *parent = 0);
virtual ~AbstractGdbAdapter();
@@ -61,7 +66,7 @@ public:
virtual void shutdown();
virtual const char *inferiorShutdownCommand() const;
virtual bool dumpersAvailable() const = 0;
virtual DumperHandling dumperHandling() const = 0;
static QString msgGdbStopFailed(const QString &why);
static QString msgInferiorStopFailed(const QString &why);

View File

@@ -48,7 +48,7 @@ class AttachGdbAdapter : public AbstractGdbAdapter
public:
AttachGdbAdapter(GdbEngine *engine, QObject *parent = 0);
bool dumpersAvailable() const { return true; }
virtual DumperHandling dumperHandling() const { return DumperLoadedByGdb; }
void startAdapter();
void startInferior();

View File

@@ -52,7 +52,7 @@ class CoreGdbAdapter : public AbstractGdbAdapter
public:
CoreGdbAdapter(GdbEngine *engine, QObject *parent = 0);
bool dumpersAvailable() const { return false; }
virtual DumperHandling dumperHandling() const { return DumperNotAvailable; }
void startAdapter();
void startInferior();

View File

@@ -115,8 +115,10 @@ static bool stateAcceptsGdbCommands(DebuggerState state)
case InferiorStarting:
case InferiorStartFailed:
case InferiorRunningRequested:
case InferiorRunningRequested_Kill:
case InferiorRunning:
case InferiorStopping:
case InferiorStopping_Kill:
case InferiorStopped:
case InferiorShuttingDown:
case InferiorShutDown:
@@ -596,7 +598,10 @@ void GdbEngine::handleResponse(const QByteArray &buff)
void GdbEngine::readGdbStandardError()
{
qWarning() << "Unexpected gdb stderr:" << m_gdbProc.readAllStandardError();
QByteArray err = m_gdbProc.readAllStandardError();
if (err == "Undefined command: \"bb\". Try \"help\".\n")
return;
qWarning() << "Unexpected gdb stderr:" << err;
}
void GdbEngine::readGdbStandardOutput()
@@ -646,6 +651,16 @@ void GdbEngine::interruptInferior()
m_gdbAdapter->interruptInferior();
}
void GdbEngine::interruptInferiorTemporarily()
{
interruptInferior();
foreach (const GdbCommand &cmd, m_commandsToRunOnTemporaryBreak)
if (cmd.flags & LosesChild) {
setState(InferiorStopping_Kill);
break;
}
}
void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
{
const qint64 pid = pid0.toLongLong();
@@ -727,9 +742,23 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
// Queue the commands that we cannot send at once.
debugMessage(_("QUEUING COMMAND ") + cmd.command);
m_commandsToRunOnTemporaryBreak.append(cmd);
if (state() != InferiorStopping) {
if (state() == InferiorStopping) {
if (cmd.flags & LosesChild)
setState(InferiorStopping_Kill);
debugMessage(_("CHILD ALREADY BEING INTERRUPTED"));
} else if (state() == InferiorStopping_Kill) {
debugMessage(_("CHILD ALREADY BEING INTERRUPTED (KILL PENDING)"));
} else if (state() == InferiorRunningRequested) {
if (cmd.flags & LosesChild)
setState(InferiorRunningRequested_Kill);
debugMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT"));
} else if (state() == InferiorRunningRequested_Kill) {
debugMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT (KILL PENDING)"));
} else if (state() == InferiorRunning) {
showStatusMessage(tr("Stopping temporarily."), 1000);
interruptInferior(); // FIXME: race condition between gdb and kill()
interruptInferiorTemporarily();
} else {
qDebug() << "ATTEMPTING TO QUEUE COMMAND IN INAPPROPRIATE STATE" << state();
}
}
} else if (!cmd.command.isEmpty()) {
@@ -737,6 +766,17 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
}
}
void GdbEngine::flushQueuedCommands()
{
showStatusMessage(tr("Processing queued commands."), 1000);
while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
debugMessage(_("RUNNING QUEUED COMMAND %1 %2")
.arg(cmd.command).arg(_(cmd.callbackName)));
flushCommand(cmd);
}
}
void GdbEngine::flushCommand(const GdbCommand &cmd0)
{
GdbCommand cmd = cmd0;
@@ -755,6 +795,9 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
gdbInputAvailable(LogInput, cmd.command);
m_gdbAdapter->write(cmd.command.toLatin1() + "\r\n");
if (cmd.flags & LosesChild)
setState(InferiorShuttingDown);
}
void GdbEngine::handleResultRecord(GdbResponse *response)
@@ -805,6 +848,8 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
debugMessage(_("APPLYING WORKAROUND #4"));
setState(InferiorStopping);
setState(InferiorStopped);
setState(InferiorShuttingDown);
setState(InferiorShutDown);
showStatusMessage(tr("Executable failed: %1")
.arg(QString::fromLocal8Bit(msg)));
shutdown();
@@ -861,6 +906,13 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
<< "LEAVES PENDING AT" << m_pendingRequests);
}
// Commands were queued, but we were in RunningRequested state, so the interrupt
// was postponed.
// This is done after the command callbacks so the running-requesting commands
// can assert on the right state.
if (state() == InferiorRunning && !m_commandsToRunOnTemporaryBreak.isEmpty())
interruptInferiorTemporarily();
// Continue only if there are no commands wire anymore, so this will
// be fully synchroneous.
// This is somewhat inefficient, as it makes the last command synchronous.
@@ -1054,17 +1106,16 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
}
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
QTC_ASSERT(state() == InferiorStopping, qDebug() << state())
QTC_ASSERT(state() == InferiorStopping || state() == InferiorStopping_Kill,
qDebug() << state())
setState(InferiorStopped);
showStatusMessage(tr("Processing queued commands."), 1000);
while (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
GdbCommand cmd = m_commandsToRunOnTemporaryBreak.takeFirst();
debugMessage(_("RUNNING QUEUED COMMAND %1 %2")
.arg(cmd.command).arg(_(cmd.callbackName)));
flushCommand(cmd);
}
flushQueuedCommands();
if (state() == InferiorStopped) {
QTC_ASSERT(m_commandsDoneCallback == 0, /**/);
m_commandsDoneCallback = &GdbEngine::autoContinueInferior;
} else {
QTC_ASSERT(state() == InferiorShuttingDown, qDebug() << state())
}
return;
}
@@ -1154,7 +1205,8 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
}
}
bool initHelpers = (m_debuggingHelperState == DebuggingHelperUninitialized);
bool initHelpers = m_debuggingHelperState == DebuggingHelperUninitialized
|| m_debuggingHelperState == DebuggingHelperLoadTried;
// Don't load helpers on stops triggered by signals unless it's
// an intentional trap.
if (initHelpers && reason == "signal-received") {
@@ -1311,10 +1363,18 @@ void GdbEngine::handleExecContinue(const GdbResponse &response)
// The "running" state is picked up in handleResponse()
QTC_ASSERT(state() == InferiorRunning, /**/);
} else {
if (state() == InferiorRunningRequested_Kill) {
setState(InferiorStopped);
m_commandsToRunOnTemporaryBreak.clear();
shutdown();
return;
}
QTC_ASSERT(state() == InferiorRunningRequested, /**/);
setState(InferiorStopped);
QByteArray msg = response.data.findChild("msg").data();
if (msg.startsWith("Cannot find bounds of current function")) {
if (!m_commandsToRunOnTemporaryBreak.isEmpty())
flushQueuedCommands();
showStatusMessage(tr("Stopped."), 5000);
//showStatusMessage(tr("No debug information available. "
// "Leaving function..."));
@@ -1322,6 +1382,7 @@ void GdbEngine::handleExecContinue(const GdbResponse &response)
} else {
showMessageBox(QMessageBox::Critical, tr("Execution Error"),
tr("Cannot continue debugged process:\n") + QString::fromLocal8Bit(msg));
m_commandsToRunOnTemporaryBreak.clear();
shutdown();
}
}
@@ -1357,6 +1418,8 @@ void GdbEngine::shutdown()
case EngineStarting: // We can't get here, really
case InferiorShuttingDown: // Will auto-trigger further shutdown steps
case EngineShuttingDown: // Do not disturb! :)
case InferiorRunningRequested_Kill:
case InferiorStopping_Kill:
break;
case AdapterStarting: // GDB is up, adapter is "doing something"
setState(AdapterStartFailed);
@@ -1376,8 +1439,7 @@ void GdbEngine::shutdown()
case InferiorStopped:
// FIXME set some timeout?
postCommand(_(m_gdbAdapter->inferiorShutdownCommand()),
NeedsStop, CB(handleInferiorShutdown));
setState(InferiorShuttingDown); // Do it after posting the command!
NeedsStop | LosesChild, CB(handleInferiorShutdown));
break;
case AdapterStarted: // We can't get here, really
case InferiorStartFailed:
@@ -1482,7 +1544,7 @@ AbstractGdbAdapter *GdbEngine::createAdapter(const DebuggerStartParametersPtr &s
case AttachCore:
return new CoreGdbAdapter(this);
case StartRemote:
return new RemoteGdbAdapter(this);
return new RemoteGdbAdapter(this, sp->toolChainType);
case AttachExternal:
return new AttachGdbAdapter(this);
default:
@@ -1509,7 +1571,7 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp)
m_gdbAdapter = createAdapter(sp);
connectAdapter();
if (startModeAllowsDumpers())
if (m_gdbAdapter->dumperHandling() != AbstractGdbAdapter::DumperNotAvailable)
connectDebuggingHelperActions();
m_gdbAdapter->startAdapter();
@@ -2722,7 +2784,7 @@ bool GdbEngine::hasDebuggingHelperForType(const QString &type) const
if (!theDebuggerBoolSetting(UseDebuggingHelpers))
return false;
if (!startModeAllowsDumpers()) {
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
// "call" is not possible in gdb when looking at core files
return type == __("QString") || type.endsWith(__("::QString"))
|| type == __("QStringList") || type.endsWith(__("::QStringList"));
@@ -2764,7 +2826,7 @@ void GdbEngine::runDirectDebuggingHelper(const WatchData &data, bool dumpChildre
void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
{
if (!startModeAllowsDumpers()) {
if (m_debuggingHelperState != DebuggingHelperAvailable) {
runDirectDebuggingHelper(data0, dumpChildren);
return;
}
@@ -3800,14 +3862,50 @@ void GdbEngine::assignValueInDebugger(const QString &expression, const QString &
postCommand(_("-var-assign assign ") + value, Discardable, CB(handleVarAssign));
}
QString GdbEngine::qtDumperLibraryName() const
{
return m_manager->qtDumperLibraryName();
}
bool GdbEngine::checkDebuggingHelpers()
{
if (!manager()->qtDumperLibraryEnabled())
return false;
const QString lib = qtDumperLibraryName();
//qDebug() << "DUMPERLIB:" << lib;
const QFileInfo fi(lib);
if (!fi.exists()) {
const QStringList &locations = manager()->qtDumperLibraryLocations();
const QString loc = locations.join(QLatin1String(", "));
const QString msg = tr("The debugging helper library was not found at %1.").arg(loc);
debugMessage(msg);
manager()->showQtDumperLibraryWarning(msg);
return false;
}
return true;
}
void GdbEngine::setDebuggingHelperState(DebuggingHelperState s)
{
m_debuggingHelperState = s;
}
void GdbEngine::tryLoadDebuggingHelpers()
{
if (isSynchroneous())
return;
if (m_debuggingHelperState != DebuggingHelperUninitialized)
switch (m_debuggingHelperState) {
case DebuggingHelperUninitialized:
break;
case DebuggingHelperLoadTried:
tryQueryDebuggingHelpers();
return;
if (!startModeAllowsDumpers()) {
case DebuggingHelperAvailable:
case DebuggingHelperUnavailable:
return;
}
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
// Load at least gdb macro based dumpers.
QFile file(_(":/gdb/gdbmacros.txt"));
file.open(QIODevice::ReadOnly);
@@ -3821,25 +3919,13 @@ void GdbEngine::tryLoadDebuggingHelpers()
PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS");
m_debuggingHelperState = DebuggingHelperUnavailable;
if (!manager()->qtDumperLibraryEnabled())
if (!checkDebuggingHelpers())
return;
const QString lib = manager()->qtDumperLibraryName();
const QStringList &locations = manager()->qtDumperLibraryLocations();
//qDebug() << "DUMPERLIB:" << lib;
// @TODO: same in CDB engine...
const QFileInfo fi(lib);
if (!fi.exists()) {
const QString loc = locations.join(QLatin1String(", "));
const QString msg = tr("The debugging helper library was not found at %1.").arg(loc);
debugMessage(msg);
manager()->showQtDumperLibraryWarning(msg);
return;
}
m_debuggingHelperState = DebuggingHelperLoadTried;
const QString dlopenLib =
(startParameters().startMode == StartRemote)
? startParameters().remoteDumperLib : lib;
? startParameters().remoteDumperLib : manager()->qtDumperLibraryName();
#if defined(Q_OS_WIN)
if (m_dumperInjectionLoad) {
/// Launch asynchronous remote thread to load.
@@ -3892,29 +3978,20 @@ void GdbEngine::tryLoadDebuggingHelpers()
void GdbEngine::tryQueryDebuggingHelpers()
{
#if !X
// retrieve list of dumpable classes
postCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"), EmbedToken);
postCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
#else
m_debuggingHelperState = DebuggingHelperUnavailable;
#endif
}
void GdbEngine::recheckDebuggingHelperAvailability()
{
if (startModeAllowsDumpers()) {
if (m_gdbAdapter->dumperHandling() != AbstractGdbAdapter::DumperNotAvailable) {
// retreive list of dumpable classes
postCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"), EmbedToken);
postCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
}
}
bool GdbEngine::startModeAllowsDumpers() const
{
return m_gdbAdapter->dumpersAvailable();
}
void GdbEngine::watchPoint(const QPoint &pnt)
{
//qDebug() << "WATCH " << pnt;
@@ -4272,7 +4349,15 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &gdb, const QStr
).arg(scriptFileName));
}
}
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperLoadedByGdbPreload
&& checkDebuggingHelpers()) {
QString cmd = _("set environment ");
cmd += _(Debugger::Constants::Internal::LD_PRELOAD_ENV_VAR);
cmd += _c(' ');
cmd += manager()->qtDumperLibraryName();
postCommand(cmd);
m_debuggingHelperState = DebuggingHelperLoadTried;
}
return true;
}

View File

@@ -176,8 +176,9 @@ private: ////////// Gdb Command Management //////////
RebuildModel = 4, // Trigger model rebuild when no such commands are pending any more
WatchUpdate = Discardable | RebuildModel,
EmbedToken = 8, // Expand %1 in the command to the command token
RunRequest = 16, // Callback expect GdbResultRunning instead of GdbResultDone
ExitRequest = 32 // Callback expect GdbResultExit instead of GdbResultDone
RunRequest = 16, // Callback expects GdbResultRunning instead of GdbResultDone
ExitRequest = 32, // Callback expects GdbResultExit instead of GdbResultDone
LosesChild = 64 // Auto-set inferior shutdown related states
};
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
private:
@@ -226,6 +227,7 @@ private: ////////// Gdb Command Management //////////
const char *callbackName,
const QVariant &cookie = QVariant());
void postCommandHelper(const GdbCommand &cmd);
void flushQueuedCommands();
void setTokenBarrier();
QHash<int, GdbCommand> m_cookieForToken;
@@ -282,6 +284,7 @@ private: ////////// Inferior Management //////////
void autoContinueInferior();
virtual void continueInferior();
virtual void interruptInferior();
void interruptInferiorTemporarily();
virtual void runToLineExec(const QString &fileName, int lineNumber);
virtual void runToFunctionExec(const QString &functionName);
@@ -446,8 +449,9 @@ private: ////////// View & Data Stuff //////////
QMap<QString, QString> m_varToType;
private: ////////// Dumper Management //////////
bool startModeAllowsDumpers() const;
QString qtDumperLibraryName() const;
bool checkDebuggingHelpers();
void setDebuggingHelperState(DebuggingHelperState);
void tryLoadDebuggingHelpers();
void tryQueryDebuggingHelpers();
Q_SLOT void recheckDebuggingHelperAvailability();

View File

@@ -58,6 +58,15 @@ PlainGdbAdapter::PlainGdbAdapter(GdbEngine *engine, QObject *parent)
engine, SLOT(readDebugeeOutput(QByteArray)));
}
AbstractGdbAdapter::DumperHandling PlainGdbAdapter::dumperHandling() const
{
#ifdef Q_OS_WIN
return DumperLoadedByGdb;
#else
return DumperLoadedByGdbPreload;
#endif
}
void PlainGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());

View File

@@ -50,7 +50,7 @@ class PlainGdbAdapter : public AbstractGdbAdapter
public:
PlainGdbAdapter(GdbEngine *engine, QObject *parent = 0);
bool dumpersAvailable() const { return true; }
virtual DumperHandling dumperHandling() const;
void startAdapter();
void startInferior();

View File

@@ -34,6 +34,7 @@
#include <utils/qtcassert.h>
#include <utils/fancymainwindow.h>
#include <projectexplorer/toolchain.h>
#include <QtCore/QFileInfo>
#include <QtGui/QMessageBox>
@@ -51,8 +52,9 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
RemoteGdbAdapter::RemoteGdbAdapter(GdbEngine *engine, QObject *parent)
: AbstractGdbAdapter(engine, parent)
RemoteGdbAdapter::RemoteGdbAdapter(GdbEngine *engine, int toolChainType, QObject *parent) :
AbstractGdbAdapter(engine, parent),
m_toolChainType(toolChainType)
{
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(uploadProcError(QProcess::ProcessError)));
@@ -62,6 +64,23 @@ RemoteGdbAdapter::RemoteGdbAdapter(GdbEngine *engine, QObject *parent)
this, SLOT(readUploadStandardError()));
}
AbstractGdbAdapter::DumperHandling RemoteGdbAdapter::dumperHandling() const
{
switch (m_toolChainType) {
case ProjectExplorer::ToolChain::MinGW:
case ProjectExplorer::ToolChain::MSVC:
case ProjectExplorer::ToolChain::WINCE:
case ProjectExplorer::ToolChain::WINSCW:
case ProjectExplorer::ToolChain::GCCE:
case ProjectExplorer::ToolChain::RVCT_ARMV5:
case ProjectExplorer::ToolChain::RVCT_ARMV6:
return DumperLoadedByGdb;
default:
break;
}
return DumperLoadedByGdbPreload;
}
void RemoteGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());

View File

@@ -46,9 +46,9 @@ class RemoteGdbAdapter : public AbstractGdbAdapter
Q_OBJECT
public:
RemoteGdbAdapter(GdbEngine *engine, QObject *parent = 0);
RemoteGdbAdapter(GdbEngine *engine, int toolChainType, QObject *parent = 0);
bool dumpersAvailable() const { return true; }
virtual DumperHandling dumperHandling() const;
void startAdapter();
void startInferior();
@@ -65,6 +65,8 @@ private:
void handleFileExecAndSymbols(const GdbResponse &response);
void handleTargetRemote(const GdbResponse &response);
const int m_toolChainType;
QProcess m_uploadProc;
};

View File

@@ -69,6 +69,15 @@ TermGdbAdapter::~TermGdbAdapter()
m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub
}
AbstractGdbAdapter::DumperHandling TermGdbAdapter::dumperHandling() const
{
#ifdef Q_OS_WIN
return DumperLoadedByGdb;
#else
return DumperLoadedByAdapter; // Handles loading itself via LD_PRELOAD
#endif
}
void TermGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
@@ -82,7 +91,17 @@ void TermGdbAdapter::startAdapter()
// m_stubProc.blockSignals(false);
m_stubProc.setWorkingDirectory(startParameters().workingDir);
m_stubProc.setEnvironment(startParameters().environment);
// Set environment + dumper preload.
QStringList environment = startParameters().environment;
if (dumperHandling() == DumperLoadedByGdbPreload
&& m_engine->checkDebuggingHelpers()) {
QString var = QLatin1String(Debugger::Constants::Internal::LD_PRELOAD_ENV_VAR);
var += QLatin1Char('=');
var += m_engine->qtDumperLibraryName();
environment.push_back(var);
m_engine->setDebuggingHelperState(DebuggingHelperLoadTried);
}
m_stubProc.setEnvironment(environment);
// FIXME: Starting the stub implies starting the inferior. This is
// fairly unclean as far as the state machine and error reporting go.
if (!m_stubProc.start(startParameters().executable,

View File

@@ -51,7 +51,7 @@ public:
TermGdbAdapter(GdbEngine *engine, QObject *parent = 0);
~TermGdbAdapter();
bool dumpersAvailable() const { return true; }
virtual DumperHandling dumperHandling() const;
void startAdapter();
void startInferior();

View File

@@ -164,7 +164,8 @@ public:
QIODevice::OpenMode mode = QIODevice::ReadWrite);
void write(const QByteArray &data);
bool isTrkAdapter() const { return true; }
bool dumpersAvailable() const { return false; }
virtual DumperHandling dumperHandling() const { return DumperNotAvailable; }
private:
void startAdapter();

View File

@@ -57,6 +57,7 @@ FormClassWizardPage::FormClassWizardPage(QWidget * parent) :
m_ui->newClassWidget->setBaseClassInputVisible(false);
m_ui->newClassWidget->setNamespacesEnabled(true);
m_ui->newClassWidget->setAllowDirectories(true);
m_ui->newClassWidget->setClassTypeComboVisible(false);
connect(m_ui->newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));
connect(m_ui->settingsToolButton, SIGNAL(clicked()), this, SLOT(slotSettings()));

View File

@@ -78,11 +78,6 @@
#include <climits>
// FIXME: Restrict this as soon the availableUndoSteps has been merged to Qt
//#if QT_VERSION < 0x040600
#define availableUndoSteps revision
//#endif
//#define DEBUG_KEY 1
#if DEBUG_KEY
# define KEY_DEBUG(s) qDebug() << s

View File

@@ -1559,6 +1559,8 @@ void ProjectExplorerPlugin::runProjectImpl(Project *pro)
d->m_buildManager->buildProjects(projects, configurations(projects));
}
} else {
// TODO this ignores RunConfiguration::isEnabled()
if (saveModifiedFiles())
executeRunConfiguration(pro->activeRunConfiguration(), ProjectExplorer::Constants::RUNMODE);
}
}
@@ -1584,6 +1586,8 @@ void ProjectExplorerPlugin::debugProject()
updateRunAction();
}
} else {
// TODO this ignores RunConfiguration::isEnabled()
if (saveModifiedFiles())
executeRunConfiguration(pro->activeRunConfiguration(), ProjectExplorer::Constants::DEBUGMODE);
}
}
@@ -2166,8 +2170,6 @@ BuildConfigDialog::BuildConfigDialog(Project *project, QWidget *parent)
));
descriptiveText->setWordWrap(true);
vlayout->addWidget(descriptiveText);
QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->addWidget(new QLabel(tr("Choose build configuration:")));
m_configCombo = new QComboBox;
QSharedPointer<RunConfiguration> activeRun = m_project->activeRunConfiguration();
foreach (BuildConfiguration *config, m_project->buildConfigurations()) {
@@ -2181,10 +2183,12 @@ BuildConfigDialog::BuildConfigDialog(Project *project, QWidget *parent)
m_changeBuildConfiguration->setEnabled(false);
}
hlayout->addWidget(m_configCombo);
hlayout->addStretch(10);
vlayout->addLayout(hlayout);
QFormLayout *formlayout = new QFormLayout;
formlayout->addRow(ActiveConfigurationWidget::tr("Active run configuration"),
// ^ avoiding a new translatable string for active run configuration
new QLabel(activeRun->name()));
formlayout->addRow(tr("Choose build configuration:"), m_configCombo);
vlayout->addLayout(formlayout);
vlayout->addWidget(buttonBox);
m_cancel->setDefault(true);
}

View File

@@ -295,6 +295,11 @@ void RunSettingsWidget::initRunConfigurationComboBox()
void RunSettingsWidget::showRunConfigurationWidget(int index)
{
Q_ASSERT(m_project);
if (index == -1) {
delete m_runConfigurationWidget;
m_runConfigurationWidget = 0;
return;
}
QSharedPointer<RunConfiguration> selectedRunConfiguration =
m_runConfigurationsModel->runConfigurations().at(index);

View File

@@ -343,7 +343,7 @@ QmlRunConfiguration::QmlRunConfiguration(QmlProject *pro)
+ Utils::SynchronousProcess::pathSeparator()
+ QCoreApplication::applicationDirPath()
;
m_qmlViewer = Utils::SynchronousProcess::locateBinary(searchPath, QLatin1String("qmlviewer"));
m_qmlViewerDefaultPath = Utils::SynchronousProcess::locateBinary(searchPath, QLatin1String("qmlviewer"));
}
QmlRunConfiguration::~QmlRunConfiguration()
@@ -357,8 +357,9 @@ QString QmlRunConfiguration::type() const
QString QmlRunConfiguration::executable() const
{
// No need to verify if the QML Viewer exists. The console will tell us anyway when we try to launch it.
return m_qmlViewer;
if (!m_qmlViewerCustomPath.isEmpty())
return m_qmlViewerCustomPath;
return m_qmlViewerDefaultPath;
}
QmlRunConfiguration::RunMode QmlRunConfiguration::runMode() const
@@ -469,7 +470,7 @@ void QmlRunConfiguration::setMainScript(const QString &scriptFile)
void QmlRunConfiguration::onQmlViewerChanged()
{
if (Utils::PathChooser *chooser = qobject_cast<Utils::PathChooser *>(sender())) {
m_qmlViewer = chooser->path();
m_qmlViewerCustomPath = chooser->path();
}
}
@@ -483,7 +484,7 @@ void QmlRunConfiguration::save(ProjectExplorer::PersistentSettingsWriter &writer
{
ProjectExplorer::LocalApplicationRunConfiguration::save(writer);
writer.saveValue(QLatin1String("qmlviewer"), m_qmlViewer);
writer.saveValue(QLatin1String("qmlviewer"), m_qmlViewerCustomPath);
writer.saveValue(QLatin1String("qmlviewerargs"), m_qmlViewerArgs);
writer.saveValue(QLatin1String("mainscript"), m_scriptFile);
}
@@ -492,24 +493,10 @@ void QmlRunConfiguration::restore(const ProjectExplorer::PersistentSettingsReade
{
ProjectExplorer::LocalApplicationRunConfiguration::restore(reader);
m_qmlViewer = reader.restoreValue(QLatin1String("qmlviewer")).toString();
m_qmlViewerCustomPath = reader.restoreValue(QLatin1String("qmlviewer")).toString();
m_qmlViewerArgs = reader.restoreValue(QLatin1String("qmlviewerargs")).toString();
m_scriptFile = reader.restoreValue(QLatin1String("mainscript")).toString();
if (m_qmlViewer.isEmpty()) {
// first see if there is a bundled qmlviewer
#ifdef Q_OS_WIN32
const QLatin1String qmlViewerExe("qmlviewer.exe");
#else
const QLatin1String qmlViewerExe("qmlviewer");
#endif
const QFileInfo info(QCoreApplication::applicationDirPath(), qmlViewerExe);
if (info.exists() && info.isExecutable())
m_qmlViewer = info.absoluteFilePath();
else // if not, then try to locate it elsewhere
m_qmlViewer = Utils::SynchronousProcess::locateBinary(QLatin1String("qmlviewer"));
}
if (m_scriptFile.isEmpty())
m_scriptFile = tr("<Current File>");
}

View File

@@ -175,7 +175,8 @@ private:
private:
QmlProject *m_project;
QString m_scriptFile;
QString m_qmlViewer;
QString m_qmlViewerCustomPath;
QString m_qmlViewerDefaultPath;
QString m_qmlViewerArgs;
QLatin1String m_type;
};

View File

@@ -79,7 +79,10 @@ QString GCCEToolChain::makeCommand() const
bool GCCEToolChain::equals(ToolChain *other) const
{
GCCEToolChain *otherGCCE = static_cast<GCCEToolChain *>(other);
return (other->type() == type()
&& m_deviceId == static_cast<GCCEToolChain *>(other)->m_deviceId
&& m_deviceName == static_cast<GCCEToolChain *>(other)->m_deviceName);
&& m_deviceId == otherGCCE->m_deviceId
&& m_deviceName == otherGCCE->m_deviceName
&& m_deviceRoot == otherGCCE->m_deviceRoot
&& m_gcceCommand == otherGCCE->m_gcceCommand);
}

View File

@@ -115,7 +115,10 @@ QString WINSCWToolChain::makeCommand() const
bool WINSCWToolChain::equals(ToolChain *other) const
{
WINSCWToolChain *otherWINSCW = static_cast<WINSCWToolChain *>(other);
return (other->type() == type()
&& m_deviceId == static_cast<WINSCWToolChain *>(other)->m_deviceId
&& m_deviceName == static_cast<WINSCWToolChain *>(other)->m_deviceName);
&& m_deviceId == otherWINSCW->m_deviceId
&& m_deviceName == otherWINSCW->m_deviceName
&& m_deviceRoot == otherWINSCW->m_deviceRoot
&& m_carbidePath == otherWINSCW->m_carbidePath);
}

View File

@@ -535,6 +535,8 @@ void Qt4Project::updateCodeModel()
if (debug)
qDebug()<<"Qt4Project::updateCodeModel()";
// TODO figure out the correct ordering of #include directories
CppTools::CppModelManagerInterface *modelmanager =
ExtensionSystem::PluginManager::instance()
->getObject<CppTools::CppModelManagerInterface>();
@@ -568,7 +570,7 @@ void Qt4Project::updateCodeModel()
const QHash<QString, QString> versionInfo = qtVersion(activeBuildConfiguration())->versionInfo();
const QString newQtIncludePath = versionInfo.value(QLatin1String("QT_INSTALL_HEADERS"));
predefinedIncludePaths.append(newQtIncludePath);
predefinedIncludePaths.prepend(newQtIncludePath);
QDir dir(newQtIncludePath);
foreach (QFileInfo info, dir.entryInfoList(QDir::Dirs)) {
const QString path = info.fileName();
@@ -576,7 +578,7 @@ void Qt4Project::updateCodeModel()
if (path == QLatin1String("Qt"))
continue; // skip $QT_INSTALL_HEADERS/Qt. There's no need to include it.
else if (path.startsWith(QLatin1String("Qt")) || path == QLatin1String("phonon"))
predefinedIncludePaths.append(info.absoluteFilePath());
predefinedIncludePaths.prepend(info.absoluteFilePath());
}
FindQt4ProFiles findQt4ProFiles;
@@ -587,13 +589,13 @@ void Qt4Project::updateCodeModel()
#ifdef Q_OS_MAC
const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS"));
allFrameworkPaths.append(newQtLibsPath);
allFrameworkPaths.prepend(newQtLibsPath);
// put QtXXX.framework/Headers directories in include path since that qmake's behavior
QDir frameworkDir(newQtLibsPath);
foreach (QFileInfo info, frameworkDir.entryInfoList(QDir::Dirs)) {
if (! info.fileName().startsWith(QLatin1String("Qt")))
continue;
allIncludePaths.append(info.absoluteFilePath()+"/Headers");
allIncludePaths.prepend(info.absoluteFilePath()+"/Headers");
}
#endif
@@ -630,9 +632,9 @@ void Qt4Project::updateCodeModel()
const QStringList proIncludePaths = pro->variableValue(IncludePathVar);
foreach (const QString &includePath, proIncludePaths) {
if (!allIncludePaths.contains(includePath))
allIncludePaths.append(includePath);
allIncludePaths.prepend(includePath);
if (!info.includes.contains(includePath))
info.includes.append(includePath);
info.includes.prepend(includePath);
}
{ // Pkg Config support
@@ -644,13 +646,13 @@ void Qt4Project::updateCodeModel()
process.waitForFinished();
QString result = process.readAllStandardOutput();
foreach(const QString &part, result.trimmed().split(' ', QString::SkipEmptyParts)) {
info.includes.append(part.mid(2)); // Chop off "-I"
info.includes.prepend(part.mid(2)); // Chop off "-I"
}
}
}
// Add mkspec directory
info.includes.append(qtVersion(activeBuildConfiguration())->mkspecPath());
info.includes.prepend(qtVersion(activeBuildConfiguration())->mkspecPath());
info.frameworkPaths = allFrameworkPaths;
@@ -664,7 +666,7 @@ void Qt4Project::updateCodeModel()
}
// Add mkspec directory
allIncludePaths.append(qtVersion(activeBuildConfiguration())->mkspecPath());
allIncludePaths.prepend(qtVersion(activeBuildConfiguration())->mkspecPath());
// Dump things out
// This is debugging output...

View File

@@ -185,5 +185,15 @@ void FilesPage::setLowerCaseFiles(bool l)
m_newClassWidget->setLowerCaseFiles(l);
}
bool FilesPage::isClassTypeComboVisible() const
{
return m_newClassWidget->isClassTypeComboVisible();
}
void FilesPage::setClassTypeComboVisible(bool v)
{
m_newClassWidget->setClassTypeComboVisible(v);
}
} // namespace Internal
} // namespace Qt4ProjectManager

View File

@@ -67,6 +67,7 @@ public:
bool formInputChecked() const;
QStringList baseClassChoices() const;
bool lowerCaseFiles() const;
bool isClassTypeComboVisible() const;
void setSuffixes(const QString &header, const QString &source, const QString &form = QString());
@@ -79,6 +80,7 @@ public slots:
void setFormInputCheckable(bool checkable);
void setFormInputChecked(bool checked);
void setLowerCaseFiles(bool l);
void setClassTypeComboVisible(bool v);
private:
Utils::NewClassWidget *m_newClassWidget;

View File

@@ -74,6 +74,7 @@ GuiAppWizardDialog::GuiAppWizardDialog(const QString &templateName,
setPage(ModulesPageId, m_modulesPage);
m_filesPage->setFormInputCheckable(true);
m_filesPage->setClassTypeComboVisible(false);
setPage(FilesPageId, m_filesPage);
foreach (QWizardPage *p, extensionPages)

View File

@@ -169,6 +169,7 @@ LibraryWizardDialog::LibraryWizardDialog(const QString &templateName,
m_filesPage->setNamespacesEnabled(true);
m_filesPage->setFormFileInputVisible(false);
m_filesPage->setClassTypeComboVisible(false);
setPage(FilePageId, m_filesPage);
connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(slotCurrentIdChanged(int)));

View File

@@ -43,6 +43,8 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/manhattanstyle.h>
#include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <extensionsystem/pluginmanager.h>
#include <find/basetextfind.h>
#include <utils/stylehelper.h>
@@ -646,6 +648,9 @@ void BaseTextEditor::slotSelectionChanged()
d->m_blockSelectionExtraX = 0;
if (!d->m_selectBlockAnchor.isNull() && !textCursor().hasSelection())
d->m_selectBlockAnchor = QTextCursor();
// Clear any link which might be showing when the selection changes
clearLink();
}
void BaseTextEditor::gotoBlockStart()
@@ -1468,7 +1473,7 @@ BaseTextEditorPrivate::BaseTextEditorPrivate()
m_requestMarkEnabled(true),
m_lineSeparatorsAllowed(false),
m_visibleWrapColumn(0),
m_showingLink(false),
m_linkPressed(false),
m_editable(0),
m_actionHack(0),
m_inBlockSelectionMode(false),
@@ -2862,35 +2867,11 @@ void BaseTextEditorPrivate::clearVisibleCollapsedBlock()
}
}
void BaseTextEditor::mouseMoveEvent(QMouseEvent *e)
{
d->m_lastEventWasBlockSelectionEvent = (e->modifiers() & Qt::AltModifier);
bool linkFound = false;
if (d->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.isValid()) {
showLink(link);
linkFound = true;
}
}
if (!linkFound)
clearLink();
updateLink(e);
if (e->buttons() == Qt::NoButton) {
const QTextBlock collapsedBlock = collapsedBlockAt(e->pos());
@@ -2934,16 +2915,23 @@ void BaseTextEditor::mousePressEvent(QMouseEvent *e)
toggleBlockVisible(collapsedBlock);
viewport()->setCursor(Qt::IBeamCursor);
}
updateLink(e);
if (d->m_currentLink.isValid())
d->m_linkPressed = true;
}
QPlainTextEdit::mousePressEvent(e);
}
void BaseTextEditor::mouseReleaseEvent(QMouseEvent *e)
{
if (d->m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier
if (d->m_mouseNavigationEnabled
&& d->m_linkPressed
&& e->modifiers() & Qt::ControlModifier
&& !(e->modifiers() & Qt::ShiftModifier)
&& e->button() == Qt::LeftButton) {
&& e->button() == Qt::LeftButton
) {
const QTextCursor cursor = cursorForPosition(e->pos());
if (openLink(findLinkAt(cursor))) {
clearLink();
@@ -3459,8 +3447,39 @@ bool BaseTextEditor::openLink(const Link &link)
return openEditorAt(link.fileName, link.line, link.column);
}
void BaseTextEditor::updateLink(QMouseEvent *e)
{
bool linkFound = false;
if (d->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.isValid()) {
showLink(link);
linkFound = true;
}
}
if (!linkFound)
clearLink();
}
void BaseTextEditor::showLink(const Link &link)
{
if (d->m_currentLink == link)
return;
QTextEdit::ExtraSelection sel;
sel.cursor = textCursor();
sel.cursor.setPosition(link.pos);
@@ -3469,25 +3488,26 @@ void BaseTextEditor::showLink(const Link &link)
sel.format.setFontUnderline(true);
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel);
viewport()->setCursor(Qt::PointingHandCursor);
d->m_showingLink = true;
d->m_currentLink = link;
d->m_linkPressed = false;
}
void BaseTextEditor::clearLink()
{
if (!d->m_showingLink)
if (!d->m_currentLink.isValid())
return;
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>());
viewport()->setCursor(Qt::IBeamCursor);
d->m_showingLink = false;
d->m_currentLink = Link();
d->m_linkPressed = false;
}
void BaseTextEditorPrivate::updateMarksBlock(const QTextBlock &block)
{
if (const TextBlockUserData *userData = TextEditDocumentLayout::testUserData(block))
foreach (ITextMark *mrk, userData->marks()) {
foreach (ITextMark *mrk, userData->marks())
mrk->updateBlock(block);
}
}
void BaseTextEditorPrivate::updateMarksLineNumber()
@@ -4711,6 +4731,23 @@ BaseTextEditorEditable::BaseTextEditorEditable(BaseTextEditor *editor)
connect(editor, SIGNAL(cursorPositionChanged()), this, SLOT(updateCursorPosition()));
}
void BaseTextEditor::appendStandardContextMenuActions(QMenu *menu)
{
menu->addSeparator();
Core::ActionManager *am = Core::ICore::instance()->actionManager();
QAction *a = am->command(Core::Constants::CUT)->action();
if (a && a->isEnabled())
menu->addAction(a);
a = am->command(Core::Constants::COPY)->action();
if (a && a->isEnabled())
menu->addAction(a);
a = am->command(Core::Constants::PASTE)->action();
if (a && a->isEnabled())
menu->addAction(a);
}
BaseTextEditorEditable::~BaseTextEditorEditable()
{
delete m_toolBar;

View File

@@ -321,6 +321,8 @@ public:
void setMimeType(const QString &mt);
void appendStandardContextMenuActions(QMenu *menu);
// Works only in conjunction with a syntax highlighter that puts
// parentheses into text block user data
void setParenthesesMatchingEnabled(bool b);
@@ -536,6 +538,9 @@ protected:
bool isValid() const
{ return !(pos == -1 || length == -1); }
bool operator==(const Link &other) const
{ return pos == other.pos && length == other.length; }
int pos; // Link position
int length; // Link length
@@ -591,6 +596,7 @@ private:
QTextBlock collapsedBlockAt(const QPoint &pos, QRect *box = 0) const;
void updateLink(QMouseEvent *e);
void showLink(const Link &);
void clearLink();

View File

@@ -204,7 +204,8 @@ public:
int m_visibleWrapColumn;
QTextCharFormat m_linkFormat;
bool m_showingLink;
BaseTextEditor::Link m_currentLink;
bool m_linkPressed;
QTextCharFormat m_ifdefedOutFormat;

File diff suppressed because it is too large Load Diff