Merge remote-tracking branch 'origin/2.4'

Conflicts:
	qtcreator.pri
	src/libs/qmljs/qmljstypedescriptionreader.cpp
	tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp

Change-Id: Id032187023bb42f259a87545ceeb3c965dd01a32
This commit is contained in:
Eike Ziller
2011-10-17 14:22:32 +02:00
76 changed files with 5227 additions and 2121 deletions

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc

49
dist/changes-2.4.0 vendored
View File

@@ -8,10 +8,17 @@ git clone git://gitorious.org/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline v2.3.1...origin/2.4
General
* Showing more useful error dialog in case of plugin errors
* Reduce minimum size of preferences dialog
Editing
* Advanced search: Show more information about the search parameters
* Advanced search: Move the previously modal dialog into search results pane
* Advanced search: Keep a history of most recent searches and their results
* Code Style schemas implemented, you can reuse them in different projects now
Managing Projects
* Shared project settings support
Debugging
@@ -21,20 +28,62 @@ Analyzing Code
* Standalone qmlprofiler command line tool allows you to retrieve & store QML tracing data
C++ Support
* Add quick fix to synchronize function declarations and definitions
* Make 'insert definition from declaration' use minimally qualified names
and find a good insertion location next to surrounding declarations
* Fix completion for typedefs for templates in namespaces
* Use minimally qualified names in function signature completion
* Use minimally qualified names in 'insert local declaration' quick fix
* When switching between header/source, prefer files in the same directory
* Fix problem with encoding and quick fixes (QTCREATORBUG-6140)
* Fix preservation of indentation level in comments with tabs (QTCREATORBUG-6151)
* Improve performance for files with a huge number of literals
QML/JS Support
* Add 'Rename usages' functionality (QTCREATORBUG-3669)
* Add collection of static analysis messages with Ctrl-Shift-C
* Add semantic highlighting
* Significantly improve scanning of C++ documents for qmlRegisterType and
setContextProperty calls (QTCREATORBUG-3199)
* Add warning about inappropriate use of constructor functions
* Add warning about unreachable code
* Add support for .import directive in js files
* Add completion for XMLHttpRequest, DB API and JSON.
* Add 'length' property to functions
* Use mime types to distinguish qml and js files
* Show the function argument hint for signals
* When completing enums, add qualified names instead of strings
* Honor typeinfo lines in qmldir files
* Make string literals that contain file names into links (QTCREATORBUG-5701)
* Add warning about invalid types in 'property' declarations (QTCREATORBUG-3666)
* Fix highlighting of property types (QTCREATORBUG-6127)
* Fix 'follow symbol' for local variables (QTCREATORBUG-6094)
* Fix function argument hints on variables (QTCREATORBUG-5752)
* Fix completion for enums in a different scope
* Fix typing '/' triggering a global completion
* Fix handling of meta object revision in C++ QML plugins
* Fix indentation of block property initializers
* Fix indentation of labelled statements
* Fix scope for completion in code bindings
* Allow for different builtin type information per Qt version
* Update builtin type information and parser for Qt 5
Qt Quick Designer
* Adding breadcrumb navigation for components
* Adding layout functionality to context menu.
Help
Platform Specific
Mac
* "Run in Terminal" was not finding xterm by default
Linux (GNOME and KDE)
Windows
* Aborting the build now works properly. Qt Creator sends Ctrl-C to the
build process via the process_ctrlc_stub helper program.
Symbian Target

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -211,7 +211,8 @@
\title Semantic Highlighting
\QC understands the C++ and QML languages as code, not as plain text.
\QC understands the C++, QML, and JavaScript languages as code, not as plain
text.
It reads the source code, analyzes it, and highlights it based on the
semantic checks that it does for the following code elements:
@@ -231,7 +232,7 @@
\gui {Tools > Options > Text Editor > Fonts & Color}.
\QC supports syntax highlighting also for other types of files than
C++ or QML.
C++, QML, or JavaScript.
\section1 Generic Highlighting
@@ -346,6 +347,41 @@
\endlist
\section1 Checking JavaScript Syntax
You can run static checks on JavaScript to find common problems, such as:
\list
\o Duplicate or conflicting variable, function, and formal parameter
declarations
\o Variables and functions that are used before they are declared
\o Possibly unsafe uses of the == or != operators
\o Comma expressions, except in \c for statements
\o Expression statements, except function or method calls, assignments,
or \c delete
\o Assignments within conditions (such as, \c {if (a = b)})
\o Case blocks within a switch that do not end with a return, break,
continue, or throw and that are not empty
\o Nested block statements
\o \c with statements
\o \c void expressions
\endlist
To run the checks, select \gui {Tools > QML/JS > Run Checks} or press
\key Ctrl+Shift+C. The results are shown in the \gui {QML Analysis}
filter of the \gui {Issues} output pane.
*/
@@ -1122,17 +1158,19 @@
\section1 Finding Symbols
To find the use of a specific symbol in your Qt C++ or Qt Quick project:
To find the use of a specific symbol or \l{glossary-component}
{QML component} in your Qt C++ or Qt Quick project:
\list 1
\o In the editor, place the cursor on the symbol, and select:
\o In the editor, place the cursor on the symbol or component, and
select:
\list
\o \gui {Tools > C++ > Find Usages}
\o \gui {Tools > QML > Find Usages}
\o \gui {Tools > QML/JS > Find Usages}
\o \key Ctrl+Shift+U

View File

@@ -149,7 +149,7 @@
\o Switch to \gui Help mode
\o Ctrl+6
\row
\o Toggle \gui{Build Issues} pane
\o Toggle \gui{Issues} pane
\o Alt+1 (Cmd+1 on Mac OS X)
\row
\o Toggle \gui{Search Results} pane
@@ -350,6 +350,9 @@
\row
\o Turn selected text into uppercase
\o Alt+Shift+U
\row
\o Run static checks on JavaScript code to find common problems
\o Ctrl+Shift+C
\endtable
\section2 Debugging Keyboard Shortcuts

View File

@@ -31,7 +31,7 @@
\page creator-task-lists.html
\nextpage creator-cli.html
\title Showing Task List Files in the Build Issues Pane
\title Showing Task List Files in Issues Pane
Code scanning and analysis tools create report files in ASCII format.
Usually, the report files consist of lines that contain a file name, a line
@@ -40,7 +40,7 @@
manually navigating to them and correcting them, which is tedious.
\QC makes this very easy by providing a way to load these files into
the \gui{Build Issues} pane. You can navigate to the corresponding source
the \gui{Issues} pane. You can navigate to the corresponding source
code by clicking the error message. But first you must convert the files to
the \l{Task List File Format} by using conversion scripts that based on
standard text processing tools of the operating system.

View File

@@ -92,7 +92,7 @@
\list
\o \gui{Build Issues} pane Alt+1 (Cmd+1 on Mac OS X)
\o \gui{Issues} pane Alt+1 (Cmd+1 on Mac OS X)
\o \gui{Search Results} pane Alt+2 (Cmd+2 on Mac OS X)

View File

@@ -230,7 +230,7 @@
\list
\o \gui{Build Issues}
\o \gui{Issues}
\o \gui{Search Results}
@@ -256,26 +256,45 @@
To open the \gui{General Messages} and \gui{Version Control} panes, select
\gui {Window > Output Panes}.
\section2 Build Issues
\section2 Issues
The \gui{Build Issues} pane provides a list of errors and warnings
encountered during a build. The pane filters out irrelevant output from
the build tools and presents the issues in an organized way.
The \gui{Issues} pane provides lists of following types of issues:
\list
\o \gui Analyzer - Errors encountered while running the
\l{Analyzing Code}{Valgrind code analysis tools}.
\o \gui {Build System} - Errors and warnings encountered during a
build.
\o \gui Compile - Selected output from the compiler. Open the
\gui {Compile Output} pane for more detailed information.
\o \gui {My Tasks} - Entries from a task list file (.tasks) generated
by \l{Showing Task List Files in Issues Pane}
{code scanning and analysis tools}.
\o \gui QML - Errors in QML syntax.
\o \gui {QML Analysis} - Results of the JavaScript
\l{Checking JavaScript Syntax}{code syntax and validation checks}
\endlist
The pane filters out irrelevant output from the build tools and presents the
issues in an organized way. To further filter the output by type, select
\inlineimage qtcreator-filter.png
and then select a filter.
\image qtcreator-build-issues.png
Right-clicking on a line brings up a context menu with options to copy
the contents and to show a version control annotation view of the line
that causes the error message.
\image qtcreator-build-issues.png
To view task lists in the \gui{Build Issues} pane, click
\inlineimage qtcreator-filter.png
and select \gui{My Tasks}. Entries from a task list file (.tasks) are
imported to the pane. Press \key F6 and \key Shift+F6 to jump from one issue
to the next.
For more information about creating task files, see
\l{Showing Task List Files in the Build Issues Pane}.
To jump from one issue to the next or previous one, press \key F6 and
\key Shift+F6.
\section2 Search Results
@@ -301,7 +320,7 @@
The \gui{Compile Output} pane provides all output from the compiler.
The \gui{Compile Output} is a more detailed version of information
displayed in the \gui{Build Issues} pane.
displayed in the \gui{Issues} pane.
\image qtcreator-compile-pane.png

View File

@@ -62,7 +62,7 @@
\o \l{Using Maemo or MeeGo Harmattan Emulator}
\endif
\o \l{Editing MIME Types}
\o \l{Showing Task List Files in the Build Issues Pane}
\o \l{Showing Task List Files in Issues Pane}
\o \l{Using Command Line Options}
\o \l{Keyboard Shortcuts}
\o \l{Glossary}

View File

@@ -84,6 +84,21 @@
as build configurations, compatible tool chains, and supported
Qt versions) as targets to make cross-platform development
easier.
\row
\o
\raw HTML
Component
\endraw
\target glossary-component
\o A component is an instantiable QML definition, typically
contained in a .qml file. For instance, a Button component may
be defined in Button.qml. The QML runtime may instantiate this
Button component to create Button objects. Alternatively, a
component may be defined inside a
\l{http://doc.qt.nokia.com/4.7-snapshot/qmlreusablecomponents.html}
{Component} element.
\endtable
*/

View File

@@ -40,7 +40,7 @@
To check that the application code can be compiled and linked for a target,
you can build the project. The build errors and warnings are displayed in
the \gui {Build Issues} output pane. More detailed information is displayed
the \gui {Issues} output pane. More detailed information is displayed
in the \gui {Compile Output} pane.
To build an application:

View File

@@ -50,8 +50,7 @@
\image qtcreator-cmakeexecutable.png
\note Before you open a \c CMake project, you must modify the \c{PATH}
environment variable to include the bin folders of \c mingw and \QC in
the \QSDK.
environment variable to include the bin folders of \c mingw and Qt.
For instance, if the \QSDK is installed in \c {C:\SDK}, you would use the
following command to set the environment variables in the command line
@@ -96,7 +95,7 @@
\QC 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.
parsed and displayed in the \gui{Issues} output pane.
By default, \QC builds the \bold{all} target. You can specify which
targets to build in \gui{Project} mode, under \gui{Build Settings}.

View File

@@ -127,9 +127,8 @@
\o \c kind specifies the type of the wizard: \c project or
\c class.
\o \c class specifies the type of the project. Currently the only
available type is \c qt4project, which specifies a Qt console
project.
\o \c class specifies the type of the project. This attribute is
optional. Use the value \c qt4project to add Qt 4 specific pages.
\o \c firstpage specifies the place of the new page in the standard
project wizard. The value 10 ensures that the custom page

View File

@@ -167,7 +167,7 @@
\o \l{Using External Tools}
\o \l{Using Maemo or MeeGo Harmattan Emulator}
\o \l{Editing MIME Types}
\o \l{Showing Task List Files in the Build Issues Pane}
\o \l{Showing Task List Files in Issues Pane}
\o \l{Using Command Line Options}
\o \l{Keyboard Shortcuts}
\endlist

View File

@@ -183,6 +183,9 @@
allow you to create applications with a native look and feel for
that platform.
\note We recommend that you use \gui {Qt Quick Components for
MeeGo Harmattan} when you develop for MeeGo Harmattan devices.
You can also import an existing QML file in this dialog.
\o Click \gui{Next}.
@@ -1027,6 +1030,18 @@
extra type information for code completion and the semantic checks to work
correctly.
When you write a QML module or use QML from a C++ application you typically
register new types with
\l{http://doc.qt.nokia.com/4.8/qdeclarativeengine.html#qmlRegisterType}
{qmlRegisterType} or expose some class instances with
\l{http://doc.qt.nokia.com/4.8/qdeclarativecontext.html#setContextProperty}
{setContextProperty}. The \QC C++ code model now scans for these calls and
tells the QML code model about them. This means that properties are
displayed during code completion and the JavaScript code checker does not
complain about unknown types. However, this works only when the source code
is available, and therefore, you must explicitly generate type information
for QML modules with plugins before distributing them.
Ideally, QML modules have a \c{plugins.qmltypes} file in the same directory
as the \c qmldir file. The \c qmltypes file contains a description of the
components exported by the module's plugins and is loaded by \QC
@@ -1035,7 +1050,7 @@
For Qt 4.8 and later, one or more \c qmltypes files can be listed in the
\c qmldir file under the \c typeinfo header. These files will be read in addition
to \c{plugins.qmltypes}. For more information, see
\l{http://doc.qt.nokia.com/4.8-snapshot/qdeclarativemodules.html#writing-a-qmldir-file}{Writing a qmldir File}.
\l{http://doc.qt.nokia.com/4.8/qdeclarativemodules.html#writing-a-qmldir-file}{Writing a qmldir File}.
\section1 Generating qmltypes Files

View File

@@ -75,8 +75,11 @@ isEmpty(TEST):CONFIG(debug, debug|release) {
isEmpty(IDE_LIBRARY_BASENAME) {
IDE_LIBRARY_BASENAME = lib
}
DEFINES += IDE_LIBRARY_BASENAME=\\\"$$IDE_LIBRARY_BASENAME\\\"
win32-msvc* {
DEFINES += IDE_LIBRARY_BASENAME=\"$$IDE_LIBRARY_BASENAME\"
} else {
DEFINES += IDE_LIBRARY_BASENAME=\\\"$$IDE_LIBRARY_BASENAME\\\"
}
equals(TEST, 1) {
QT +=testlib

File diff suppressed because it is too large Load Diff

View File

@@ -87,16 +87,17 @@ PropertyFrame {
rightMargin: 0;
spacing: 0;
WidgetLoader {
id: specificsOne;
source: specificsUrl;
}
WidgetLoader {
id: specificsTwo;
baseUrl: globalBaseUrl;
qmlData: specificQmlData;
}
WidgetLoader {
id: specificsOne;
source: specificsUrl;
}
QScrollArea {
}
} // layout

View File

@@ -0,0 +1,70 @@
<!-- Aegis manifest declares the security credentials required by an
application to run correctly. By default, a manifest file will be
created or updated automatically as a part of build.
The detection of required credentials is based on static scan of
application binaries. In some cases, the scan may not be able to
detect the correct set of permissions. If this is the case, you must
declare the credentials required by your application in this file.
To create a manifest file automatically as a part of build (DEFAULT):
* You may leave this file as-is.
* Do not list any '<credential name="token" />' entries
outside of comments.
To provide a manifest yourself:
* List the correct credentials for the application in this file.
* Some commented-out examples of often required tokens are provided.
* Ensure the path to your application binary given in
'<for path="/path/to/app" />' is correct.
* Please do not request more credentials than what your application
actually requires.
To disable manifest file:
* Replace this file with a file starting with the string "NoAegisFile" (without quotes).
* Final application package will not contain a manifest.
-->
<aegis>
<request policy="add">
<!-- Make a GSM call, send text messages (SMS). -->
<!--
<credential name="Cellular" />
-->
<!-- Access Facebook social data. -->
<!--
<credential name="FacebookSocial" />
-->
<!-- Read access to data stored in tracker. -->
<!--
<credential name="TrackerReadAccess" />
-->
<!-- Read and write access to data stored in tracker. -->
<!--
<credential name="TrackerWriteAccess" />
-->
<!-- Read Location information. -->
<!--
<credential name="Location" />
-->
<!-- Access to Audio, Multimedia and Camera. -->
<!--
<credential name="GRP::pulse-access" />
<credential name="GRP::video" />
<credential name="GRP::audio" />
-->
</request>
<for path="/opt/%%PROJECTNAME%%/bin/%%PROJECTNAME%%" />
<for path="applauncherd-launcher::/usr/bin/applauncherd.bin" id="" />
</aegis>

File diff suppressed because it is too large Load Diff

View File

@@ -71,7 +71,7 @@ static const char fixedOptionsC[] =
" -help Display this help\n"
" -version Display program version\n"
" -client Attempt to connect to already running instance\n"
" -settingspath <path> Override the default path where user settings are stored.\n";
" -settingspath <path> Override the default path where user settings are stored\n";
static const char HELP_OPTION1[] = "-h";
static const char HELP_OPTION2[] = "-help";

View File

@@ -37,6 +37,7 @@
#define CPLUSPLUS_NO_DEBUG_RULE
#define MAX_EXPRESSION_DEPTH 100
#define MAX_STATEMENT_DEPTH 100
using namespace CPlusPlus;
@@ -181,7 +182,8 @@ Parser::Parser(TranslationUnit *unit)
_inFunctionBody(false),
_inObjCImplementationContext(false),
_inExpressionStatement(false),
_expressionDepth(0)
_expressionDepth(0),
_statementDepth(0)
{ }
Parser::~Parser()
@@ -3209,6 +3211,10 @@ bool Parser::parseCompoundStatement(StatementAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_LBRACE) {
if (_statementDepth > MAX_STATEMENT_DEPTH)
return false;
++_statementDepth;
CompoundStatementAST *ast = new (_pool) CompoundStatementAST;
ast->lbrace_token = consumeToken();
@@ -3233,6 +3239,7 @@ bool Parser::parseCompoundStatement(StatementAST *&node)
}
match(T_RBRACE, &ast->rbrace_token);
node = ast;
--_statementDepth;
return true;
}
return false;

View File

@@ -315,6 +315,7 @@ private:
bool _inObjCImplementationContext: 1;
bool _inExpressionStatement: 1;
int _expressionDepth;
int _statementDepth;
MemoryPool _expressionStatementTempPool;
std::map<unsigned, TemplateArgumentListEntry> _templateArgumentList;

View File

@@ -6,7 +6,11 @@ include(extensionsystem_dependencies.pri)
unix:!macx:!freebsd*:LIBS += -ldl
DEFINES += IDE_TEST_DIR=\\\"$$IDE_SOURCE_TREE\\\"
win32-msvc* {
DEFINES += IDE_TEST_DIR=\"$$IDE_SOURCE_TREE\"
} else {
DEFINES += IDE_TEST_DIR=\\\"$$IDE_SOURCE_TREE\\\"
}
HEADERS += pluginerrorview.h \
plugindetailsview.h \

View File

@@ -600,6 +600,11 @@ void PluginManager::formatOptions(QTextStream &str, int optionIndentation, int d
formatOption(str, QLatin1String(OptionsParser::PROFILE_OPTION),
QString(), QLatin1String("Profile plugin loading"),
optionIndentation, descriptionIndentation);
#ifdef WITH_TESTS
formatOption(str, QLatin1String(OptionsParser::TEST_OPTION),
QLatin1String("plugin|all"), QLatin1String("Run plugin's tests"),
optionIndentation, descriptionIndentation);
#endif
}
/*!

View File

@@ -259,6 +259,14 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
default: enter(expression); continue;
} break;
case ternary_op:
if (kind == Colon) {
enter(ternary_op_after_colon);
enter(expression_continuation);
break;
}
// fallthrough
case ternary_op_after_colon:
case expression:
if (tryInsideExpression())
break;
@@ -333,18 +341,6 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
default: leave(); continue;
} break;
case ternary_op:
if (tryInsideExpression())
break;
switch (kind) {
case RightParenthesis:
case RightBracket:
case RightBrace:
case Comma:
case Semicolon: leave(); continue;
case Colon: enter(expression); break; // entering expression makes maybe_continuation work
} break;
case jsblock_open:
case substatement_open:
if (tryStatement())
@@ -495,7 +491,8 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
// some states might be continued on the next line
if (topState == expression
|| topState == expression_or_objectdefinition
|| topState == objectliteral_assignment) {
|| topState == objectliteral_assignment
|| topState == ternary_op_after_colon) {
enter(expression_maybe_continuation);
}
// multi-line comment start?

View File

@@ -145,6 +145,7 @@ public: // must be public to make Q_GADGET introspection work
bracket_element_maybe_objectdefinition, // after an identifier in bracket_element_start
ternary_op, // The ? : operator
ternary_op_after_colon, // after the : in a ternary
jsblock_open,

View File

@@ -216,6 +216,7 @@ static void collectScopes(const QmlComponentChain *chain, QList<const ObjectValu
void ScopeChain::update() const
{
m_modified = false;
m_all.clear();
m_all += m_globalScope;
@@ -287,6 +288,8 @@ void ScopeChain::initializeRootScope()
if (bind->rootObjectValue())
m_jsScopes += bind->rootObjectValue();
}
m_modified = true;
}
void ScopeChain::makeComponentChain(

View File

@@ -121,7 +121,7 @@ private:
const JSImportScope *m_jsImports;
QList<const ObjectValue *> m_jsScopes;
bool m_modified;
mutable bool m_modified;
mutable QList<const ObjectValue *> m_all;
};

View File

@@ -146,12 +146,14 @@ void TypeDescriptionReader::readModule(UiObjectDefinition *ast)
for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) {
UiObjectMember *member = it->member;
UiObjectDefinition *component = dynamic_cast<UiObjectDefinition *>(member);
if (!component || toString(component->qualifiedTypeNameId) != "Component") {
addWarning(member->firstSourceLocation(), "Expected only 'Component' object definitions");
const QString typeName = toString(component->qualifiedTypeNameId);
if (!component || (typeName != "Component" && typeName != "ModuleApi")) {
addWarning(member->firstSourceLocation(), "Expected only 'Component' and 'ModuleApi' object definitions");
continue;
}
readComponent(component);
if (typeName == QLatin1String("Component"))
readComponent(component);
}
}

View File

@@ -60,18 +60,26 @@ FileInProjectFinder::FileInProjectFinder()
{
}
static QString stripTrailingSlashes(const QString &path)
{
QString newPath = path;
while (newPath.endsWith(QLatin1Char('/')))
newPath.remove(newPath.length() - 1, 1);
return newPath;
}
void FileInProjectFinder::setProjectDirectory(const QString &absoluteProjectPath)
{
QTC_ASSERT(QFileInfo(absoluteProjectPath).exists()
&& QFileInfo(absoluteProjectPath).isAbsolute(), return);
const QString newProjectPath = stripTrailingSlashes(absoluteProjectPath);
if (absoluteProjectPath == m_projectDir)
if (newProjectPath == m_projectDir)
return;
m_projectDir = absoluteProjectPath;
while (m_projectDir.endsWith(QLatin1Char('/')))
m_projectDir.remove(m_projectDir.length() - 1, 1);
const QFileInfo infoPath(newProjectPath);
QTC_CHECK(newProjectPath.isEmpty()
|| (infoPath.exists() && infoPath.isAbsolute()));
m_projectDir = newProjectPath;
m_cache.clear();
}
@@ -82,6 +90,9 @@ QString FileInProjectFinder::projectDirectory() const
void FileInProjectFinder::setProjectFiles(const QStringList &projectFiles)
{
if (m_projectFiles == projectFiles)
return;
m_projectFiles = projectFiles;
m_cache.clear();
}

View File

@@ -107,7 +107,7 @@ void SshKeyGenerator::generatePkcs8KeyString(const KeyPtr &key, bool privateKey,
d.setTextEchoMode(QLineEdit::Password);
d.setWindowTitle(tr("Password for Private Key"));
d.setLabelText(tr("It is recommended that you secure your private key\n"
"with a password, which you can can enter below."));
"with a password, which you can enter below."));
d.setOkButtonText(tr("Encrypt key file"));
d.setCancelButtonText(tr("Do not encrypt key file"));
int result = QDialog::Accepted;

View File

@@ -1203,27 +1203,10 @@ void MainWindow::readSettings()
QColor(Utils::StyleHelper::DEFAULT_BASE_COLOR)).value<QColor>());
}
// TODO compat for <= 2.1, remove later
if (m_settings->contains(QLatin1String(geometryKey))) {
const QVariant geom = m_settings->value(QLatin1String(geometryKey));
if (geom.isValid()) {
setGeometry(geom.toRect());
} else {
resize(1024, 700);
}
if (m_settings->value(QLatin1String(maxKey), false).toBool())
setWindowState(Qt::WindowMaximized);
setFullScreen(m_settings->value(QLatin1String(fullScreenKey), false).toBool());
m_settings->remove(QLatin1String(geometryKey));
m_settings->remove(QLatin1String(maxKey));
m_settings->remove(QLatin1String(fullScreenKey));
} else {
if (!restoreGeometry(m_settings->value(QLatin1String(windowGeometryKey)).toByteArray())) {
resize(1024, 700);
}
restoreState(m_settings->value(QLatin1String(windowStateKey)).toByteArray());
if (!restoreGeometry(m_settings->value(QLatin1String(windowGeometryKey)).toByteArray())) {
resize(1008, 700); // size without window decoration
}
restoreState(m_settings->value(QLatin1String(windowStateKey)).toByteArray());
m_settings->endGroup();

View File

@@ -271,7 +271,7 @@ void ManhattanStyle::polish(QWidget *widget)
QProxyStyle::polish(widget);
// OxygenStyle forces a rounded widget mask on toolbars and dock widgets
if (baseStyle()->inherits("OxygenStyle")) {
if (baseStyle()->inherits("OxygenStyle") || baseStyle()->inherits("Oxygen::Style")) {
if (qobject_cast<QToolBar*>(widget) || qobject_cast<QDockWidget*>(widget)) {
widget->removeEventFilter(baseStyle());
widget->setContentsMargins(0, 0, 0, 0);

View File

@@ -1,249 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** 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.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#include "rssfetcher.h"
#include "coreconstants.h"
#include <QtCore/QDebug>
#include <QtCore/QSysInfo>
#include <QtCore/QLocale>
#include <QtCore/QEventLoop>
#include <QtCore/QUrl>
#include <QtGui/QDesktopServices>
#include <QtGui/QLineEdit>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkProxyFactory>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkConfiguration>
#include <QtCore/QXmlStreamReader>
#ifdef Q_OS_UNIX
#include <sys/utsname.h>
#endif
namespace Core {
static const QString getOsString()
{
QString osString;
#if defined(Q_OS_WIN)
switch (QSysInfo::WindowsVersion) {
case (QSysInfo::WV_4_0):
osString += QLatin1String("WinNT4.0");
break;
case (QSysInfo::WV_5_0):
osString += QLatin1String("Windows NT 5.0");
break;
case (QSysInfo::WV_5_1):
osString += QLatin1String("Windows NT 5.1");
break;
case (QSysInfo::WV_5_2):
osString += QLatin1String("Windows NT 5.2");
break;
case (QSysInfo::WV_6_0):
osString += QLatin1String("Windows NT 6.0");
break;
case (QSysInfo::WV_6_1):
osString += QLatin1String("Windows NT 6.1");
break;
default:
osString += QLatin1String("Windows NT (Unknown)");
break;
}
#elif defined (Q_OS_MAC)
if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
osString += QLatin1String("PPC ");
else
osString += QLatin1String("Intel ");
osString += QLatin1String("Mac OS X ");
switch (QSysInfo::MacintoshVersion) {
case (QSysInfo::MV_10_3):
osString += QLatin1String("10_3");
break;
case (QSysInfo::MV_10_4):
osString += QLatin1String("10_4");
break;
case (QSysInfo::MV_10_5):
osString += QLatin1String("10_5");
break;
case (QSysInfo::MV_10_6):
osString += QLatin1String("10_6");
break;
default:
osString += QLatin1String("(Unknown)");
break;
}
#elif defined (Q_OS_UNIX)
struct utsname uts;
if (uname(&uts) == 0) {
osString += QLatin1String(uts.sysname);
osString += QLatin1Char(' ');
osString += QLatin1String(uts.release);
} else {
osString += QLatin1String("Unix (Unknown)");
}
#else
ossttring = QLatin1String("Unknown OS");
#endif
return osString;
}
RssFetcher::RssFetcher(int maxItems)
: QThread(0), m_maxItems(maxItems), m_items(0),
m_requestCount(0), m_networkAccessManager(0)
{
qRegisterMetaType<Core::RssItem>("Core::RssItem");
moveToThread(this);
}
RssFetcher::~RssFetcher()
{
}
void RssFetcher::run()
{
exec();
delete m_networkAccessManager;
}
void RssFetcher::fetch(const QUrl &url)
{
QString agentStr = QString::fromLatin1("Qt-Creator/%1 (QHttp %2; %3; %4; %5 bit)")
.arg(Core::Constants::IDE_VERSION_LONG).arg(qVersion())
.arg(getOsString()).arg(QLocale::system().name())
.arg(QSysInfo::WordSize);
QNetworkRequest req(url);
req.setRawHeader("User-Agent", agentStr.toLatin1());
if (!m_networkAccessManager) {
m_networkAccessManager = new QNetworkAccessManager;
m_networkAccessManager->setConfiguration(QNetworkConfiguration());
connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)),
SLOT(fetchingFinished(QNetworkReply*)));
}
m_requestCount++;
m_networkAccessManager->get(req);
}
void RssFetcher::fetchingFinished(QNetworkReply *reply)
{
const bool error = (reply->error() != QNetworkReply::NoError);
if (!error) {
parseXml(reply);
m_items = 0;
}
if (--m_requestCount == 0)
emit finished(error);
reply->deleteLater();
}
RssFetcher::TagElement RssFetcher::tagElement(const QStringRef &r, TagElement prev)
{
if (r == QLatin1String("item"))
return itemElement;
if (r == QLatin1String("title"))
return titleElement;
if (r == QLatin1String("category"))
return categoryElement;
if (r == QLatin1String("description"))
return descriptionElement;
if (r == QLatin1String("image"))
return imageElement;
if (r == QLatin1String("link")) {
if (prev == imageElement)
return imageLinkElement;
else
return linkElement;
}
return otherElement;
}
void RssFetcher::parseXml(QIODevice *device)
{
QXmlStreamReader xmlReader(device);
TagElement currentTag = otherElement;
RssItem item;
while (!xmlReader.atEnd()) {
switch (xmlReader.readNext()) {
case QXmlStreamReader::StartElement:
currentTag = tagElement(xmlReader.name(), currentTag);
if (currentTag == itemElement) {
item = RssItem();
}
break;
case QXmlStreamReader::EndElement:
if (xmlReader.name() == QLatin1String("item")) {
m_items++;
if ((uint)m_items > (uint)m_maxItems)
return;
emit newsItemReady(item.title, item.description, item.url);
emit rssItemReady(item);
}
break;
case QXmlStreamReader::Characters:
if (!xmlReader.isWhitespace()) {
switch (currentTag) {
case titleElement:
item.title += xmlReader.text().toString();
break;
case descriptionElement:
item.description += xmlReader.text().toString();
break;
case categoryElement:
item.category += xmlReader.text().toString();
break;
case linkElement:
item.url += xmlReader.text().toString();
break;
case imageLinkElement:
item.imagePath += xmlReader.text().toString();
break;
default:
break;
}
} // !xmlReader.isWhitespace()
break;
default:
break;
}
}
if (xmlReader.error() && xmlReader.error() != QXmlStreamReader::PrematureEndOfDocumentError) {
qWarning("Welcome::Internal::RSSFetcher: XML ERROR: %d: %s (%s)",
int(xmlReader.lineNumber()),
qPrintable(xmlReader.errorString()),
qPrintable(item.title));
}
}
} // namespace Core

View File

@@ -1,92 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** 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.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#ifndef RSSFETCHER_H
#define RSSFETCHER_H
#include "core_global.h"
#include <QtCore/QThread>
QT_BEGIN_NAMESPACE
class QUrl;
class QNetworkReply;
class QNetworkAccessManager;
class QIODevice;
QT_END_NAMESPACE
namespace Core {
class CORE_EXPORT RssItem
{
public:
QString title;
QString description;
QString category;
QString url;
QString imagePath;
};
class CORE_EXPORT RssFetcher : public QThread
{
Q_OBJECT
public:
explicit RssFetcher(int maxItems = -1);
virtual void run();
virtual ~RssFetcher();
signals:
void newsItemReady(const QString& title, const QString& desciption, const QString& url);
void rssItemReady(const Core::RssItem& item);
void finished(bool error);
public slots:
void fetchingFinished(QNetworkReply *reply);
void fetch(const QUrl &url);
private:
enum TagElement { itemElement, titleElement, descriptionElement, linkElement,
imageElement, imageLinkElement, categoryElement, otherElement };
static TagElement tagElement(const QStringRef &, TagElement prev);
void parseXml(QIODevice *);
const int m_maxItems;
int m_items;
int m_requestCount;
QNetworkAccessManager* m_networkAccessManager;
};
} // namespace Internal
#endif // RSSFETCHER_H

View File

@@ -436,7 +436,7 @@ static inline Utils::SavedAction *theAssemblerAction()
CdbEngine::CdbEngine(const DebuggerStartParameters &sp,
DebuggerEngine *masterEngine, const OptionsPtr &options) :
DebuggerEngine(sp, masterEngine),
DebuggerEngine(sp, CppLanguage, masterEngine),
m_creatorExtPrefix("<qtcreatorcdbext>|"),
m_tokenPrefix("<token>"),
m_options(options),

View File

@@ -139,11 +139,13 @@ class DebuggerEnginePrivate : public QObject
public:
DebuggerEnginePrivate(DebuggerEngine *engine,
DebuggerEngine *masterEngine,
DebuggerLanguages languages,
const DebuggerStartParameters &sp)
: m_engine(engine),
m_masterEngine(masterEngine),
m_runControl(0),
m_startParameters(sp),
m_languages(languages),
m_state(DebuggerNotReady),
m_lastGoodState(DebuggerNotReady),
m_targetState(DebuggerNotReady),
@@ -256,6 +258,7 @@ public:
DebuggerRunControl *m_runControl; // Not owned.
DebuggerStartParameters m_startParameters;
DebuggerLanguages m_languages;
// The current state.
DebuggerState m_state;
@@ -292,8 +295,9 @@ public:
//////////////////////////////////////////////////////////////////////
DebuggerEngine::DebuggerEngine(const DebuggerStartParameters &startParameters,
DebuggerLanguages languages,
DebuggerEngine *parentEngine)
: d(new DebuggerEnginePrivate(this, parentEngine, startParameters))
: d(new DebuggerEnginePrivate(this, parentEngine, languages, startParameters))
{
d->m_inferiorPid = 0;
}
@@ -1135,6 +1139,11 @@ DebuggerEngine *DebuggerEngine::masterEngine() const
return d->m_masterEngine;
}
DebuggerLanguages DebuggerEngine::languages() const
{
return d->m_languages;
}
bool DebuggerEngine::debuggerActionsEnabled() const
{
return debuggerActionsEnabled(d->m_state);

View File

@@ -144,6 +144,7 @@ class DEBUGGER_EXPORT DebuggerEngine : public QObject
public:
explicit DebuggerEngine(const DebuggerStartParameters &sp,
DebuggerLanguages languages,
DebuggerEngine *parentEngine = 0);
virtual ~DebuggerEngine();
@@ -263,7 +264,7 @@ public:
int timeout = -1) const;
Q_SLOT void showStatusMessage(const QString &msg, int timeout = -1) const;
void resetLocation();
virtual void resetLocation();
virtual void gotoLocation(const Internal::Location &location);
virtual void quitDebugger(); // called by DebuggerRunControl
@@ -272,6 +273,8 @@ public:
bool isMasterEngine() const;
DebuggerEngine *masterEngine() const;
DebuggerLanguages languages() const;
virtual bool setupQmlStep(bool /*on*/) { return false; }
virtual void readyToExecuteQmlStep() {}

View File

@@ -134,6 +134,7 @@ public:
DebuggerLanguages m_previousDebugLanguages;
DebuggerLanguages m_activeDebugLanguages;
DebuggerLanguages m_engineDebugLanguages;
ActionContainer *m_viewsMenu;
@@ -151,6 +152,7 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *mw)
, m_changingUI(false)
, m_previousDebugLanguages(AnyLanguage)
, m_activeDebugLanguages(AnyLanguage)
, m_engineDebugLanguages(AnyLanguage)
, m_viewsMenu(0)
{
createViewsMenuItems();
@@ -222,11 +224,15 @@ void DebuggerMainWindowPrivate::updateActiveLanguages()
{
DebuggerLanguages newLanguages = AnyLanguage;
if (m_previousRunConfiguration) {
if (m_previousRunConfiguration.data()->useCppDebugger())
newLanguages = CppLanguage;
if (m_previousRunConfiguration.data()->useQmlDebugger())
newLanguages |= QmlLanguage;
if (m_engineDebugLanguages != AnyLanguage)
newLanguages = m_engineDebugLanguages;
else {
if (m_previousRunConfiguration) {
if (m_previousRunConfiguration.data()->useCppDebugger())
newLanguages |= CppLanguage;
if (m_previousRunConfiguration.data()->useQmlDebugger())
newLanguages |= QmlLanguage;
}
}
if (newLanguages != m_activeDebugLanguages) {
@@ -269,6 +275,15 @@ DebuggerLanguages DebuggerMainWindow::activeDebugLanguages() const
return d->m_activeDebugLanguages;
}
void DebuggerMainWindow::setEngineDebugLanguages(DebuggerLanguages languages)
{
if (d->m_engineDebugLanguages == languages)
return;
d->m_engineDebugLanguages = languages;
d->updateActiveLanguages();
}
void DebuggerMainWindow::onModeChanged(IMode *mode)
{
d->m_inDebugMode = (mode && mode->id() == Constants::MODE_DEBUG);
@@ -555,31 +570,29 @@ void DebuggerMainWindow::readSettings()
settings->endGroup();
// Reset initial settings when there are none yet.
if (d->isQmlActive()) {
if (d->m_dockWidgetActiveStateQmlCpp.isEmpty()) {
d->m_activeDebugLanguages = DebuggerLanguage(QmlLanguage|CppLanguage);
d->setSimpleDockWidgetArrangement();
d->m_dockWidgetActiveStateCpp = saveSettings();
}
} else {
if (d->m_dockWidgetActiveStateCpp.isEmpty()) {
d->m_activeDebugLanguages = CppLanguage;
d->setSimpleDockWidgetArrangement();
d->m_dockWidgetActiveStateCpp = saveSettings();
}
if (d->m_dockWidgetActiveStateQmlCpp.isEmpty()) {
d->m_activeDebugLanguages = DebuggerLanguage(QmlLanguage|CppLanguage);
d->setSimpleDockWidgetArrangement();
d->m_dockWidgetActiveStateCpp = saveSettings();
}
if (d->m_dockWidgetActiveStateCpp.isEmpty()) {
d->m_activeDebugLanguages = CppLanguage;
d->setSimpleDockWidgetArrangement();
d->m_dockWidgetActiveStateCpp = saveSettings();
}
writeSettings();
}
void DebuggerMainWindowPrivate::resetDebuggerLayout()
{
m_activeDebugLanguages = DebuggerLanguage(QmlLanguage | CppLanguage);
setSimpleDockWidgetArrangement();
m_dockWidgetActiveStateQmlCpp = q->saveSettings();
if (isQmlActive())
m_dockWidgetActiveStateQmlCpp = q->saveSettings();
else
m_dockWidgetActiveStateCpp = q->saveSettings();
m_activeDebugLanguages = CppLanguage;
m_previousDebugLanguages = CppLanguage;
setSimpleDockWidgetArrangement();
// will save state in m_dockWidgetActiveStateCpp
updateActiveLanguages();
}
@@ -631,6 +644,7 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement()
dockWidget->hide();
}
QDockWidget *toolBarDock = q->toolBarDockWidget();
QDockWidget *breakDock = q->dockWidget(DOCKWIDGET_BREAK);
QDockWidget *stackDock = q->dockWidget(DOCKWIDGET_STACK);
QDockWidget *watchDock = q->dockWidget(DOCKWIDGET_WATCHERS);
@@ -649,62 +663,43 @@ void DebuggerMainWindowPrivate::setSimpleDockWidgetArrangement()
QTC_ASSERT(snapshotsDock, return);
QTC_ASSERT(threadsDock, return);
QTC_ASSERT(outputDock, return);
//QTC_ASSERT(qmlInspectorDock, return); // This is really optional.
QTC_ASSERT(scriptConsoleDock, return);
QTC_ASSERT(modulesDock, return);
QTC_ASSERT(registerDock, return);
QTC_ASSERT(sourceFilesDock, return);
if (m_activeDebugLanguages.testFlag(Debugger::CppLanguage)
&& m_activeDebugLanguages.testFlag(Debugger::QmlLanguage)) {
// make sure main docks are visible so that split equally divides the space
toolBarDock->show();
stackDock->show();
breakDock->show();
watchDock->show();
// cpp + qml
q->toolBarDockWidget()->show();
stackDock->show();
watchDock->show();
breakDock->show();
// toolBar
// --------------------------------------------------------------------------------
// stack,qmlinspector | breakpoints,modules,register,threads,sourceFiles,snapshots,scriptconsole
//
q->splitDockWidget(toolBarDock, stackDock, Qt::Vertical);
q->splitDockWidget(stackDock, breakDock, Qt::Horizontal);
if (qmlInspectorDock)
q->tabifyDockWidget(stackDock, qmlInspectorDock);
q->tabifyDockWidget(breakDock, modulesDock);
q->tabifyDockWidget(breakDock, registerDock);
q->tabifyDockWidget(breakDock, threadsDock);
q->tabifyDockWidget(breakDock, sourceFilesDock);
q->tabifyDockWidget(breakDock, snapshotsDock);
q->tabifyDockWidget(breakDock, scriptConsoleDock);
if (m_activeDebugLanguages.testFlag(Debugger::QmlLanguage)) {
if (qmlInspectorDock)
qmlInspectorDock->show();
q->splitDockWidget(q->toolBarDockWidget(), stackDock, Qt::Vertical);
q->splitDockWidget(stackDock, breakDock, Qt::Horizontal);
q->tabifyDockWidget(stackDock, snapshotsDock);
q->tabifyDockWidget(stackDock, threadsDock);
if (qmlInspectorDock)
q->splitDockWidget(stackDock, qmlInspectorDock, Qt::Horizontal);
} else {
q->toolBarDockWidget()->show();
stackDock->show();
breakDock->show();
watchDock->show();
// CPP only
threadsDock->show();
snapshotsDock->show();
if ((m_activeDebugLanguages.testFlag(CppLanguage)
&& !m_activeDebugLanguages.testFlag(QmlLanguage))
|| m_activeDebugLanguages == AnyLanguage) {
threadsDock->show();
snapshotsDock->show();
} else {
scriptConsoleDock->show();
//if (qmlInspectorDock)
// qmlInspectorDock->show();
}
q->splitDockWidget(q->toolBarDockWidget(), stackDock, Qt::Vertical);
q->splitDockWidget(stackDock, breakDock, Qt::Horizontal);
q->tabifyDockWidget(breakDock, modulesDock);
q->tabifyDockWidget(breakDock, registerDock);
q->tabifyDockWidget(breakDock, threadsDock);
q->tabifyDockWidget(breakDock, sourceFilesDock);
q->tabifyDockWidget(breakDock, snapshotsDock);
q->tabifyDockWidget(breakDock, scriptConsoleDock);
//if (qmlInspectorDock)
// q->splitDockWidget(breakDock, qmlInspectorDock, Qt::Horizontal);
}
breakDock->raise(); // Raise something sensible.
q->setTrackingEnabled(true);
q->update();
}

View File

@@ -62,6 +62,7 @@ public:
// Active languages to be debugged.
DebuggerLanguages activeDebugLanguages() const;
void setEngineDebugLanguages(DebuggerLanguages languages);
// Called when all dependent plugins have loaded.
void initialize();

View File

@@ -475,7 +475,7 @@ class DummyEngine : public DebuggerEngine
Q_OBJECT
public:
DummyEngine() : DebuggerEngine(DebuggerStartParameters()) {}
DummyEngine() : DebuggerEngine(DebuggerStartParameters(), AnyLanguage) {}
~DummyEngine() {}
void setupEngine() {}
@@ -1983,6 +1983,8 @@ void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine)
}
engine->watchHandler()->rebuildModel();
mainWindow()->setEngineDebugLanguages(engine->languages());
}
static void changeFontSize(QWidget *widget, qreal size)
@@ -2259,6 +2261,10 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
void DebuggerPluginPrivate::updateDebugActions()
{
//if we're currently debugging the actions are controlled by engine
if (m_currentEngine->state() != DebuggerNotReady)
return;
ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
Project *project = pe->startupProject();
const QString debugMode = _(Constants::DEBUGMODE);

View File

@@ -189,7 +189,7 @@ static QByteArray parsePlainConsoleStream(const GdbResponse &response)
GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: DebuggerEngine(startParameters, masterEngine)
: DebuggerEngine(startParameters, CppLanguage, masterEngine)
{
setObjectName(_("GdbEngine"));

View File

@@ -128,6 +128,9 @@ void LocalPlainGdbAdapter::shutdownAdapter()
void LocalPlainGdbAdapter::checkForReleaseBuild()
{
#ifndef Q_OS_MAC
// There is usually no objdump on Mac, and if there is,
// there are no .debug_info sections.
QString objDump = _("objdump");
// Windows: Locate objdump in the debuggee's (MinGW) environment
if (ProjectExplorer::Abi::hostAbi().os() == ProjectExplorer::Abi::WindowsOS
@@ -166,6 +169,7 @@ void LocalPlainGdbAdapter::checkForReleaseBuild()
tr("This does not seem to be a \"Debug\" build.\n"
"Setting breakpoints by file name and line number may fail."));
}
#endif
}
void LocalPlainGdbAdapter::interruptInferior()

View File

@@ -66,7 +66,7 @@ namespace Debugger {
namespace Internal {
IPCEngineHost::IPCEngineHost (const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
: DebuggerEngine(startParameters, CppLanguage)
, m_localGuest(0)
, m_nextMessagePayloadSize(0)
, m_cookie(1)

View File

@@ -90,7 +90,7 @@ namespace Internal {
///////////////////////////////////////////////////////////////////////
PdbEngine::PdbEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
: DebuggerEngine(startParameters, AnyLanguage)
{
setObjectName(QLatin1String("PdbEngine"));
}

View File

@@ -139,7 +139,7 @@ void QmlCppEnginePrivate::qmlStackChanged()
QmlCppEngine::QmlCppEngine(const DebuggerStartParameters &sp,
DebuggerEngineType slaveEngineType,
QString *errorMessage)
: DebuggerEngine(sp), d(new QmlCppEnginePrivate(this, sp))
: DebuggerEngine(sp, DebuggerLanguages(CppLanguage) | QmlLanguage), d(new QmlCppEnginePrivate(this, sp))
{
setObjectName(QLatin1String("QmlCppEngine"));
d->m_cppEngine = DebuggerRunControlFactory::createEngine(slaveEngineType, sp, this, errorMessage);
@@ -322,14 +322,18 @@ void QmlCppEngine::detachDebugger()
void QmlCppEngine::executeStep()
{
if (d->m_activeEngine == d->m_qmlEngine) {
QTC_CHECK(d->m_cppEngine->state() == InferiorRunOk);
if (d->m_cppEngine->setupQmlStep(true))
return; // Wait for callback to readyToExecuteQmlStep()
} else {
notifyInferiorRunRequested();
d->m_cppEngine->executeStep();
}
// TODO: stepping from qml -> cpp requires more thought
// if (d->m_activeEngine == d->m_qmlEngine) {
// QTC_CHECK(d->m_cppEngine->state() == InferiorRunOk);
// if (d->m_cppEngine->setupQmlStep(true))
// return; // Wait for callback to readyToExecuteQmlStep()
// } else {
// notifyInferiorRunRequested();
// d->m_cppEngine->executeStep();
// }
notifyInferiorRunRequested();
d->m_activeEngine->executeStep();
}
void QmlCppEngine::readyToExecuteQmlStep()
@@ -671,6 +675,14 @@ void QmlCppEngine::showMessage(const QString &msg, int channel, int timeout) con
DebuggerEngine::showMessage(msg, channel, timeout);
}
void QmlCppEngine::resetLocation()
{
if (d->m_qmlEngine)
d->m_qmlEngine->resetLocation();
if (d->m_cppEngine)
d->m_cppEngine->resetLocation();
}
DebuggerEngine *QmlCppEngine::cppEngine() const
{
return d->m_cppEngine;

View File

@@ -94,6 +94,7 @@ public:
void showMessage(const QString &msg, int channel = LogDebug,
int timeout = -1) const;
void resetLocation();
protected:
void detachDebugger();

View File

@@ -115,7 +115,7 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *q)
QmlEngine::QmlEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: DebuggerEngine(startParameters, masterEngine),
: DebuggerEngine(startParameters, QmlLanguage, masterEngine),
d(new QmlEnginePrivate(this))
{
setObjectName(QLatin1String("QmlEngine"));
@@ -210,6 +210,14 @@ void QmlEngine::beginConnection()
void QmlEngine::connectionStartupFailed()
{
if (isSlaveEngine()) {
if (masterEngine()->state() != InferiorRunOk) {
// we're right now debugging C++, just try longer ...
beginConnection();
return;
}
}
Core::ICore * const core = Core::ICore::instance();
QMessageBox *infoBox = new QMessageBox(core->mainWindow());
infoBox->setIcon(QMessageBox::Critical);
@@ -451,7 +459,6 @@ void QmlEngine::executeStep()
logMessage(LogSend, "STEPINTO");
d->m_adapter.activeDebuggerClient()->executeStep();
}
resetLocation();
notifyInferiorRunRequested();
notifyInferiorRunOk();
}
@@ -462,7 +469,6 @@ void QmlEngine::executeStepI()
logMessage(LogSend, "STEPINTO");
d->m_adapter.activeDebuggerClient()->executeStepI();
}
resetLocation();
notifyInferiorRunRequested();
notifyInferiorRunOk();
}
@@ -473,7 +479,6 @@ void QmlEngine::executeStepOut()
logMessage(LogSend, "STEPOUT");
d->m_adapter.activeDebuggerClient()->executeStepOut();
}
resetLocation();
notifyInferiorRunRequested();
notifyInferiorRunOk();
}
@@ -484,14 +489,13 @@ void QmlEngine::executeNext()
logMessage(LogSend, "STEPOVER");
d->m_adapter.activeDebuggerClient()->executeNext();
}
resetLocation();
notifyInferiorRunRequested();
notifyInferiorRunOk();
}
void QmlEngine::executeNextI()
{
SDEBUG("QmlEngine::executeNextI()");
executeNext();
}
void QmlEngine::executeRunToLine(const ContextData &data)

View File

@@ -205,7 +205,7 @@ void ScriptAgent::scriptUnload(qint64 scriptId)
///////////////////////////////////////////////////////////////////////
ScriptEngine::ScriptEngine(const DebuggerStartParameters &startParameters)
: DebuggerEngine(startParameters)
: DebuggerEngine(startParameters, AnyLanguage)
{
setObjectName(QLatin1String("ScriptEngine"));
}

View File

@@ -152,7 +152,7 @@ Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
if (index.row() == m_stackFrames.size())
return QAbstractTableModel::flags(index);
const StackFrame &frame = m_stackFrames.at(index.row());
const bool isValid = (frame.isUsable() && !frame.function.isEmpty())
const bool isValid = frame.isUsable()
|| debuggerCore()->boolSetting(OperateByInstruction);
return isValid && m_contentsValid
? QAbstractTableModel::flags(index) : Qt::ItemFlags(0);

View File

@@ -1483,11 +1483,11 @@ QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryUR
void GitClient::launchGitK(const QString &workingDirectory)
{
const QString gitBinDirectory = gitBinaryPath();
QDir foundBinDir(gitBinDirectory);
const QFileInfo binaryInfo(gitBinaryPath());
QDir foundBinDir(binaryInfo.dir());
const bool foundBinDirIsCmdDir = foundBinDir.dirName() == "cmd";
QProcessEnvironment env = processEnvironment();
if (tryLauchingGitK(env, workingDirectory, gitBinDirectory, foundBinDirIsCmdDir))
if (tryLauchingGitK(env, workingDirectory, foundBinDir.path(), foundBinDirIsCmdDir))
return;
if (!foundBinDirIsCmdDir)
return;

View File

@@ -375,17 +375,40 @@ bool MaemoDebianPackageCreationStep::copyDebianFiles(bool inSourceBuild)
QString newFileName = fileName;
if (newFileName == Qt4HarmattanTarget::aegisManifestFileName()) {
// If the user has touched the Aegis manifest file, we copy it for use
// by MADDE. Otherwise the required capabilities will be auto-detected.
// by MADDE. Otherwise the required capabilities will be auto-detected,
// unless the user explicitly requests that no manifest should be created.
if (QFileInfo(srcFile).size() == 0)
continue;
newFileName = maemoTarget()->packageName() + QLatin1String(".aegis");
}
const QString destFile = debianDirPath + QLatin1Char('/') + newFileName;
if (fileName == QLatin1String("rules")) {
if (!adaptRulesFile(srcFile, destFile))
return false;
} else if (!QFile::copy(srcFile, destFile)) {
raiseError(tr("Could not copy file '%1' to '%2'")
continue;
}
if (newFileName == maemoTarget()->packageName() + QLatin1String(".aegis")) {
Utils::FileReader reader;
if (!reader.fetch(srcFile)) {
raiseError(tr("Could not read manifest file '%1': %2.")
.arg(QDir::toNativeSeparators(srcFile), reader.errorString()));
return false;
}
if (reader.data().startsWith("NoAegisFile")) {
QFile targetFile(destFile);
if (!targetFile.open(QIODevice::WriteOnly)) {
raiseError(tr("Could not write manifest file '%1': %2.")
.arg(QDir::toNativeSeparators(destFile), targetFile.errorString()));
return false;
}
continue;
}
}
if (!QFile::copy(srcFile, destFile)) {
raiseError(tr("Could not copy file '%1' to '%2'.")
.arg(QDir::toNativeSeparators(srcFile), QDir::toNativeSeparators(destFile)));
return false;
}

View File

@@ -1143,9 +1143,24 @@ QString Qt4HarmattanTarget::aegisManifestFileName()
void Qt4HarmattanTarget::handleTargetAddedSpecial()
{
AbstractDebBasedQt4MaemoTarget::handleTargetAddedSpecial();
QFile aegisFile(debianDirPath() + QLatin1Char('/') + aegisManifestFileName());
if (!aegisFile.exists())
aegisFile.open(QIODevice::WriteOnly);
const QFile aegisFile(debianDirPath() + QLatin1Char('/') + aegisManifestFileName());
if (aegisFile.exists())
return;
Utils::FileReader reader;
if (!reader.fetch(Core::ICore::instance()->resourcePath()
+ QLatin1String("/templates/shared/") + aegisManifestFileName())) {
qDebug("Reading manifest template failed.");
return;
}
QString content = QString::fromUtf8(reader.data());
content.replace(QLatin1String("%%PROJECTNAME%%"), project()->displayName());
Utils::FileSaver writer(aegisFile.fileName(), QIODevice::WriteOnly);
writer.write(content.toUtf8());
if (!writer.finalize()) {
qDebug("Failure writing manifest file.");
return;
}
}
void Qt4HarmattanTarget::addAdditionalControlFileFields(QByteArray &controlContents)

View File

@@ -92,7 +92,7 @@
<item row="0" column="1">
<widget class="QSpinBox" name="logEntriesCount">
<property name="toolTip">
<string>The number of recent commit logs to show, choose 0 to see all enteries</string>
<string>The number of recent commit logs to show, choose 0 to see all entries.</string>
</property>
<property name="maximum">
<number>100</number>

View File

@@ -540,7 +540,7 @@ QVariantMap SettingsAccessor::restoreSettings(Project *project) const
QApplication::translate("ProjectExplorer::SettingsAccessor",
"Using Old Project Settings File"),
QApplication::translate("ProjectExplorer::SettingsAccessor",
"<html><head/><body><p>A versioned backup of the .user"
"<html><head/><body><p>A versioned backup of the .user "
"settings file will be used, because the non-versioned "
"file was created by an incompatible newer version of "
"Qt Creator.</p><p>Project settings changes made since "

View File

@@ -464,15 +464,17 @@ void TaskWindow::updateCategoriesMenu()
const QStringList filteredCategories = d->m_filter->filteredCategories();
foreach (const QString &categoryId, d->m_model->categoryIds()) {
const QString categoryName = d->m_model->categoryDisplayName(categoryId);
QMap<QString, QString> nameToIds;
foreach (const QString &categoryId, d->m_model->categoryIds())
nameToIds.insert(d->m_model->categoryDisplayName(categoryId), categoryId);
foreach (const QString &displayName, nameToIds.keys()) {
const QString categoryId = nameToIds.value(displayName);
QAction *action = new QAction(d->m_categoriesMenu);
action->setCheckable(true);
action->setText(categoryName);
action->setText(displayName);
action->setData(categoryId);
action->setChecked(!filteredCategories.contains(categoryId));
d->m_categoriesMenu->addAction(action);
}
}

View File

@@ -115,7 +115,7 @@ void MoveManipulator::synchronizeParent(const QList<FormEditorItem*> &itemList,
void MoveManipulator::synchronizeInstanceParent(const QList<FormEditorItem*> &itemList)
{
if (m_view->model() && !m_itemList.isEmpty())
if (m_view->model() && !m_itemList.isEmpty() && m_itemList.first()->qmlItemNode().instanceParent().isValid())
synchronizeParent(itemList, m_itemList.first()->qmlItemNode().instanceParent());
}

View File

@@ -576,6 +576,7 @@ void DesignDocumentController::loadCurrentModel()
d->formEditorView->crumblePath()->pushElement(simplfiedDisplayName(), createCrumbleBarInfo());
d->documentLoaded = true;
d->subComponentManager->update(d->searchPath, d->model->imports());
Q_ASSERT(d->masterModel);
QApplication::restoreOverrideCursor();
}

View File

@@ -631,6 +631,8 @@ QString templateGeneration(NodeMetaInfo type, NodeMetaInfo superType, const QmlO
orderedList = type.propertyNames();
qSort(orderedList);
bool emptyTemplate = true;
foreach (const QString &name, orderedList) {
if (name.startsWith(QLatin1String("__")))
@@ -649,32 +651,40 @@ QString templateGeneration(NodeMetaInfo type, NodeMetaInfo superType, const QmlO
qmlTemplate += QString(QLatin1String(
"IntEditor { backendValue: backendValues.%2\n caption: \"%1\"\nbaseStateFlag: isBaseState\nslider: false\n}"
)).arg(name).arg(properName);
emptyTemplate = false;
}
if (typeName == "real" || typeName == "double" || typeName == "qreal") {
qmlTemplate += QString(QLatin1String(
"DoubleSpinBoxAlternate {\ntext: \"%1\"\nbackendValue: backendValues.%2\nbaseStateFlag: isBaseState\n}\n"
)).arg(name).arg(properName);
emptyTemplate = false;
}
if (typeName == "string" || typeName == "QString" || typeName == "QUrl" || typeName == "url") {
qmlTemplate += QString(QLatin1String(
"QWidget {\nlayout: HorizontalLayout {\nLabel {\ntext: \"%1\"\ntoolTip: \"%1\"\n}\nLineEdit {\nbackendValue: backendValues.%2\nbaseStateFlag: isBaseState\n}\n}\n}\n"
)).arg(name).arg(properName);
emptyTemplate = false;
}
if (typeName == "bool") {
qmlTemplate += QString(QLatin1String(
"QWidget {\nlayout: HorizontalLayout {\nLabel {\ntext: \"%1\"\ntoolTip: \"%1\"\n}\nCheckBox {text: backendValues.%2.value\nbackendValue: backendValues.%2\nbaseStateFlag: isBaseState\ncheckable: true\n}\n}\n}\n"
)).arg(name).arg(properName);
emptyTemplate = false;
}
if (typeName == "color" || typeName == "QColor") {
qmlTemplate += QString(QLatin1String(
"ColorGroupBox {\ncaption: \"%1\"\nfinished: finishedNotify\nbackendColor: backendValues.%2\n}\n\n"
)).arg(name).arg(properName);
emptyTemplate = false;
}
}
}
qmlTemplate += QLatin1String("}\n"); //VerticalLayout
qmlTemplate += QLatin1String("}\n"); //GroupBox
if (emptyTemplate)
return QString();
return qmlTemplate;
}
@@ -697,14 +707,30 @@ void PropertyEditor::resetView()
QString specificsClassName;
QUrl qmlFile(qmlForNode(m_selectedNode, specificsClassName));
QUrl qmlSpecificsFile;
if (m_selectedNode.isValid())
qmlSpecificsFile = fileToUrl(locateQmlFile(fixTypeNameForPanes(m_selectedNode.type()) + "Specifics.qml"));
QString diffClassName;
if (m_selectedNode.isValid()) {
diffClassName = m_selectedNode.metaInfo().typeName();
QList<NodeMetaInfo> hierarchy;
hierarchy << m_selectedNode.metaInfo();
hierarchy << m_selectedNode.metaInfo().superClasses();
foreach (const NodeMetaInfo &info, hierarchy) {
if (QFileInfo(qmlSpecificsFile.toLocalFile()).exists())
break;
qmlSpecificsFile = fileToUrl(locateQmlFile(fixTypeNameForPanes(info.typeName()) + "Specifics.qml"));
diffClassName = info.typeName();
}
}
if (!QFileInfo(qmlSpecificsFile.toLocalFile()).exists())
diffClassName = specificsClassName;
QString specificQmlData;
if (m_selectedNode.isValid() && !QFileInfo(qmlSpecificsFile.toLocalFile()).exists() && m_selectedNode.metaInfo().isValid()) {
if (m_selectedNode.isValid() && m_selectedNode.metaInfo().isValid() && diffClassName != m_selectedNode.type()) {
//do magic !!
specificQmlData = templateGeneration(m_selectedNode.metaInfo(), model()->metaInfo(specificsClassName), m_selectedNode);
specificQmlData = templateGeneration(m_selectedNode.metaInfo(), model()->metaInfo(diffClassName), m_selectedNode);
}
NodeType *type = m_typeHash.value(qmlFile.toString());

View File

@@ -406,7 +406,7 @@ void ModelNodeContextMenu::execute(const QPoint &pos, bool selectionMenuBool)
if (!singleSelected && !selectionIsEmpty && layoutingIsPossible) {
ModelNodeAction *action = createModelNodeAction(tr("Layout in row"), layoutMenu, selectedModelNodes, ModelNodeAction::LayoutRow, true);
ModelNodeAction *action = createModelNodeAction(tr("Layout in Row"), layoutMenu, selectedModelNodes, ModelNodeAction::LayoutRow, true);
layoutMenu->addAction(action);
action = createModelNodeAction(tr("Layout in Column"), layoutMenu, selectedModelNodes, ModelNodeAction::LayoutColumn, true);
layoutMenu->addAction(action);
@@ -757,6 +757,55 @@ static inline void reparentTo(const ModelNode &node, const QmlItemNode &parent)
}
}
bool compareByX(const ModelNode &node1, const ModelNode &node2)
{
QmlItemNode itemNode1 = QmlItemNode(node1);
QmlItemNode itemNode2 = QmlItemNode(node2);
if (itemNode1.isValid() && itemNode2.isValid())
return itemNode1.instancePosition().x() < itemNode2.instancePosition().x();
return false;
}
bool compareByY(const ModelNode &node1, const ModelNode &node2)
{
QmlItemNode itemNode1 = QmlItemNode(node1);
QmlItemNode itemNode2 = QmlItemNode(node2);
if (itemNode1.isValid() && itemNode2.isValid())
return itemNode1.instancePosition().y() < itemNode2.instancePosition().y();
return false;
}
bool compareByGrid(const ModelNode &node1, const ModelNode &node2)
{
QmlItemNode itemNode1 = QmlItemNode(node1);
QmlItemNode itemNode2 = QmlItemNode(node2);
if (itemNode1.isValid() && itemNode2.isValid()) {
if ((itemNode1.instancePosition().y() + itemNode1.instanceSize().height()) < itemNode2.instancePosition().y())
return true;
if ((itemNode2.instancePosition().y() + itemNode2.instanceSize().height()) < itemNode1.instancePosition().y())
return false; //first sort y (rows)
return itemNode1.instancePosition().x() < itemNode2.instancePosition().x();
}
return false;
}
static inline QPoint getUpperLeftPosition(const QList<ModelNode> &modelNodeList)
{
QPoint p(INT_MAX, INT_MAX);
foreach (ModelNode modelNode, modelNodeList) {
QmlItemNode itemNode = QmlItemNode(modelNode);
if (itemNode.isValid()) {
if (itemNode.instancePosition().x() < p.x())
p.setX(itemNode.instancePosition().x());
if (itemNode.instancePosition().y() < p.y())
p.setY(itemNode.instancePosition().y());
}
}
return p;
}
void ModelNodeAction::layoutRow()
{
if (!m_view)
@@ -777,7 +826,15 @@ void ModelNodeAction::layoutRow()
{
RewriterTransaction transaction(m_view);
foreach (ModelNode modelNode, m_modelNodeList) {
QPoint pos = getUpperLeftPosition(m_modelNodeList);
row.variantProperty(QLatin1String("x")) = pos.x();
row.variantProperty(QLatin1String("y")) = pos.y();
QList<ModelNode> sortedList = m_modelNodeList;
qSort(sortedList.begin(), sortedList.end(), compareByX);
foreach (ModelNode modelNode, sortedList) {
reparentTo(modelNode, row);
modelNode.removeProperty(QLatin1String("x"));
modelNode.removeProperty(QLatin1String("y"));
@@ -805,7 +862,15 @@ void ModelNodeAction::layoutColumn()
{
RewriterTransaction transaction(m_view);
foreach (ModelNode modelNode, m_modelNodeList) {
QPoint pos = getUpperLeftPosition(m_modelNodeList);
column.variantProperty(QLatin1String("x")) = pos.x();
column.variantProperty(QLatin1String("y")) = pos.y();
QList<ModelNode> sortedList = m_modelNodeList;
qSort(sortedList.begin(), sortedList.end(), compareByY);
foreach (ModelNode modelNode, sortedList) {
reparentTo(modelNode, column);
modelNode.removeProperty(QLatin1String("x"));
modelNode.removeProperty(QLatin1String("y"));
@@ -834,7 +899,15 @@ void ModelNodeAction::layoutGrid()
{
RewriterTransaction transaction(m_view);
foreach (ModelNode modelNode, m_modelNodeList) {
QPoint pos = getUpperLeftPosition(m_modelNodeList);
grid.variantProperty(QLatin1String("x")) = pos.x();
grid.variantProperty(QLatin1String("y")) = pos.y();
QList<ModelNode> sortedList = m_modelNodeList;
qSort(sortedList.begin(), sortedList.end(), compareByGrid);
foreach (ModelNode modelNode, sortedList) {
reparentTo(modelNode, grid);
modelNode.removeProperty(QLatin1String("x"));
modelNode.removeProperty(QLatin1String("y"));
@@ -862,7 +935,15 @@ void ModelNodeAction::layoutFlow()
{
RewriterTransaction transaction(m_view);
foreach (ModelNode modelNode, m_modelNodeList) {
QPoint pos = getUpperLeftPosition(m_modelNodeList);
flow.variantProperty(QLatin1String("x")) = pos.x();
flow.variantProperty(QLatin1String("y")) = pos.y();
QList<ModelNode> sortedList = m_modelNodeList;
qSort(sortedList.begin(), sortedList.end(), compareByGrid);
foreach (ModelNode modelNode, sortedList) {
reparentTo(modelNode, flow);
modelNode.removeProperty(QLatin1String("x"));
modelNode.removeProperty(QLatin1String("y"));

View File

@@ -492,6 +492,7 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface
m_startPosition = assistInterface->position();
while (isIdentifierChar(m_interface->document()->characterAt(m_startPosition - 1), false, false))
--m_startPosition;
const bool onIdentifier = m_startPosition != assistInterface->position();
m_completions.clear();
@@ -512,7 +513,11 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface
const ContextPtr &context = semanticInfo.context;
const ScopeChain &scopeChain = semanticInfo.scopeChain(path);
// Search for the operator that triggered the completion.
// The completionOperator is the character under the cursor or directly before the
// identifier under cursor. Use in conjunction with onIdentifier. Examples:
// a + b<complete> -> ' '
// a +<complete> -> '+'
// a +b<complete> -> '+'
QChar completionOperator;
if (m_startPosition > 0)
completionOperator = m_interface->document()->characterAt(m_startPosition - 1);
@@ -590,15 +595,62 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface
// ### enum completion?
// completion gets triggered for / in string literals, if we don't
// return here, this will mean the snippet completion pops up for
// each / in a string literal that is not triggering file completion
return 0;
} else if (completionOperator.isSpace()
|| completionOperator.isNull()
|| isDelimiterChar(completionOperator)
|| (completionOperator == QLatin1Char('(')
&& m_startPosition != m_interface->position())) {
}
// member "a.bc<complete>" or function "foo(<complete>" completion
else if (completionOperator == QLatin1Char('.')
|| (completionOperator == QLatin1Char('(') && !onIdentifier)) {
// Look at the expression under cursor.
//QTextCursor tc = textWidget->textCursor();
QTextCursor tc(qmlInterface->document());
tc.setPosition(m_startPosition - 1);
QmlExpressionUnderCursor expressionUnderCursor;
QmlJS::AST::ExpressionNode *expression = expressionUnderCursor(tc);
if (expression != 0 && ! isLiteral(expression)) {
// Evaluate the expression under cursor.
ValueOwner *interp = context->valueOwner();
const Value *value =
interp->convertToObject(scopeChain.evaluate(expression));
//qDebug() << "type:" << interp->typeId(value);
if (value && completionOperator == QLatin1Char('.')) { // member completion
ProcessProperties processProperties(&scopeChain);
if (contextFinder.isInLhsOfBinding() && qmlScopeType) {
LhsCompletionAdder completionAdder(&m_completions, m_interface->symbolIcon(),
PropertyOrder, contextFinder.isAfterOnInLhsOfBinding());
processProperties.setEnumerateGeneratedSlots(true);
processProperties(value, &completionAdder);
} else {
CompletionAdder completionAdder(&m_completions, m_interface->symbolIcon(), SymbolOrder);
processProperties(value, &completionAdder);
}
} else if (value
&& completionOperator == QLatin1Char('(')
&& m_startPosition == m_interface->position()) {
// function completion
if (const FunctionValue *f = value->asFunctionValue()) {
QString functionName = expressionUnderCursor.text();
int indexOfDot = functionName.lastIndexOf(QLatin1Char('.'));
if (indexOfDot != -1)
functionName = functionName.mid(indexOfDot + 1);
QStringList signature;
for (int i = 0; i < f->argumentCount(); ++i)
signature.append(f->argumentName(i));
return createHintProposal(functionName.trimmed(), signature);
}
}
}
if (! m_completions.isEmpty())
return createContentProposal();
return 0;
}
// global completion
else if (onIdentifier || assistInterface->reason() == ExplicitlyInvoked) {
bool doGlobalCompletion = true;
bool doQmlKeywordCompletion = true;
@@ -698,68 +750,14 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const IAssistInterface
if (!doJsKeywordCompletion)
addCompletions(&m_completions, qmlWordsAlsoInJs, m_interface->keywordIcon(), KeywordOrder);
}
}
else if (completionOperator == QLatin1Char('.') || completionOperator == QLatin1Char('(')) {
// Look at the expression under cursor.
//QTextCursor tc = textWidget->textCursor();
QTextCursor tc(qmlInterface->document());
tc.setPosition(m_startPosition - 1);
QmlExpressionUnderCursor expressionUnderCursor;
QmlJS::AST::ExpressionNode *expression = expressionUnderCursor(tc);
if (expression != 0 && ! isLiteral(expression)) {
// Evaluate the expression under cursor.
ValueOwner *interp = context->valueOwner();
const Value *value =
interp->convertToObject(scopeChain.evaluate(expression));
//qDebug() << "type:" << interp->typeId(value);
if (value && completionOperator == QLatin1Char('.')) { // member completion
ProcessProperties processProperties(&scopeChain);
if (contextFinder.isInLhsOfBinding() && qmlScopeType) {
LhsCompletionAdder completionAdder(&m_completions, m_interface->symbolIcon(),
PropertyOrder, contextFinder.isAfterOnInLhsOfBinding());
processProperties.setEnumerateGeneratedSlots(true);
processProperties(value, &completionAdder);
} else {
CompletionAdder completionAdder(&m_completions, m_interface->symbolIcon(), SymbolOrder);
processProperties(value, &completionAdder);
}
} else if (value
&& completionOperator == QLatin1Char('(')
&& m_startPosition == m_interface->position()) {
// function completion
if (const FunctionValue *f = value->asFunctionValue()) {
QString functionName = expressionUnderCursor.text();
int indexOfDot = functionName.lastIndexOf(QLatin1Char('.'));
if (indexOfDot != -1)
functionName = functionName.mid(indexOfDot + 1);
QStringList signature;
for (int i = 0; i < f->argumentCount(); ++i)
signature.append(f->argumentName(i));
return createHintProposal(functionName.trimmed(), signature);
}
}
}
m_completions.append(m_snippetCollector.collect());
if (! m_completions.isEmpty())
return createContentProposal();
return 0;
}
if (isQmlFile
&& (completionOperator.isNull()
|| completionOperator.isSpace()
|| isDelimiterChar(completionOperator))) {
m_completions.append(m_snippetCollector.collect());
}
if (! m_completions.isEmpty())
return createContentProposal();
return 0;
}
@@ -858,9 +856,20 @@ bool QmlJSCompletionAssistProcessor::completeFileName(const QString &relativeBas
bool QmlJSCompletionAssistProcessor::completeUrl(const QString &relativeBasePath, const QString &urlString)
{
const QUrl url(urlString);
QString fileName = url.toLocalFile();
if (fileName.isEmpty())
QString fileName;
if (url.scheme().compare(QLatin1String("file"), Qt::CaseInsensitive) == 0) {
fileName = url.toLocalFile();
// should not trigger completion on 'file://'
if (fileName.isEmpty())
return false;
} else if (url.scheme().isEmpty()) {
// don't trigger completion while typing a scheme
if (urlString.endsWith(QLatin1String(":/")))
return false;
fileName = urlString;
} else {
return false;
}
return completeFileName(relativeBasePath, fileName);
}

View File

@@ -265,6 +265,12 @@ protected:
addUse(fullLocationForQualifiedId(localId), SemanticHighlighter::BindingNameType);
}
bool visit(UiImport *ast)
{
processName(ast->importId, ast->importIdToken);
return true;
}
bool visit(UiObjectDefinition *ast)
{
if (m_scopeChain.document()->bind()->isGroupedPropertyBinding(ast)) {

View File

@@ -139,18 +139,15 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
if (*indentDepth == tokenPosition) {
// expression_or_objectdefinition doesn't want the indent
// expression_or_label already has it
// ternary already adjusts indents nicely
if (parentState.type != expression_or_objectdefinition
&& parentState.type != expression_or_label
&& parentState.type != binding_assignment
&& parentState.type != ternary_op) {
&& parentState.type != binding_assignment) {
*indentDepth += 2*m_indentSize;
}
}
// expression_or_objectdefinition and expression_or_label have already consumed the first token
else if (parentState.type != expression_or_objectdefinition
&& parentState.type != expression_or_label
&& parentState.type != ternary_op) {
&& parentState.type != expression_or_label) {
*indentDepth = tokenPosition;
}
break;

View File

@@ -551,6 +551,7 @@ bool Qt4BuildConfiguration::removeQMLInspectorFromArguments(QString *args)
const QString arg = ait.value();
if (arg.contains(QLatin1String(Constants::QMAKEVAR_QMLJSDEBUGGER_PATH))
|| arg.contains(Constants::QMAKEVAR_DECLARATIVE_DEBUG)) {
ait.deleteArg();
removedArgument = true;
}
}

View File

@@ -43,6 +43,7 @@
#include "snippets/isnippetprovider.h"
#include <QtGui/QVBoxLayout>
#include <QtGui/QTextBlock>
#include <QtGui/QLabel>
using namespace TextEditor;
@@ -64,8 +65,14 @@ CodeStyleEditor::CodeStyleEditor(ICodeStylePreferencesFactory *factory,
ISnippetProvider *provider = factory->snippetProvider();
if (provider)
provider->decorateEditor(m_preview);
QLabel *label = new QLabel(
tr("Edit preview contents to see how the current settings "
"are applied to custom code snippets. Changes in the preview "
"do not affect the current settings."), this);
label->setWordWrap(true);
m_layout->addWidget(selector);
m_layout->addWidget(m_preview);
m_layout->addWidget(label);
connect(codeStyle, SIGNAL(currentTabSettingsChanged(TextEditor::TabSettings)),
this, SLOT(updatePreview()));
connect(codeStyle, SIGNAL(currentValueChanged(QVariant)),

View File

@@ -1,121 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** 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.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#include "communitywelcomepagewidget.h"
#include "ui_communitywelcomepagewidget.h"
#include <coreplugin/rssfetcher.h>
#include <QtCore/QMap>
#include <QtCore/QUrl>
#include <QtGui/QDesktopServices>
#include <QtGui/QTreeWidgetItem>
struct Site {
const char *description;
const char *url;
};
static const Site supportSites[] = {
{ QT_TRANSLATE_NOOP("Welcome::Internal::CommunityWelcomePageWidget",
"<b>Forum Nokia</b><br /><font color='gray'>Mobile application support</font>"),
"http://www.forum.nokia.com/Support/"},
{ QT_TRANSLATE_NOOP("Welcome::Internal::CommunityWelcomePageWidget",
"<b>Qt LGPL Support</b><br /><font color='gray'>Buy commercial Qt support</font>"),
"http://shop.qt.nokia.com/en/support.html"},
{ QT_TRANSLATE_NOOP("Welcome::Internal::CommunityWelcomePageWidget",
"<b>Qt DevNet</b><br /><font color='gray'>Qt Developer Resources</font>"),
"http://developer.qt.nokia.com" }
};
static const Site sites[] = {
{ QT_TRANSLATE_NOOP("Welcome::Internal::CommunityWelcomePageWidget",
"<b>Qt Home</b><br /><font color='gray'>Qt by Nokia on the web</font>"),
"http://qt.nokia.com" },
{ QT_TRANSLATE_NOOP("Welcome::Internal::CommunityWelcomePageWidget",
"<b>Qt Git Hosting</b><br /><font color='gray'>Participate in Qt development</font>"),
"http://qt.gitorious.org"},
{ QT_TRANSLATE_NOOP("Welcome::Internal::CommunityWelcomePageWidget",
"<b>Qt Apps</b><br /><font color='gray'>Find free Qt-based apps</font>"),
"http://www.qt-apps.org"}
};
namespace Welcome {
namespace Internal {
static inline void populateWelcomeTreeWidget(const Site *sites, int count, Utils::WelcomeModeTreeWidget *wt)
{
for (int s = 0; s < count; s++) {
const QString description = CommunityWelcomePageWidget::tr(sites[s].description);
const QString url = QLatin1String(sites[s].url);
wt->addItem(description, url, url);
}
}
CommunityWelcomePageWidget::CommunityWelcomePageWidget(QWidget *parent) :
QWidget(parent),
m_rssFetcher(new Core::RssFetcher(7)),
ui(new Ui::CommunityWelcomePageWidget)
{
ui->setupUi(this);
connect(ui->newsTreeWidget, SIGNAL(activated(QString)), SLOT(slotUrlClicked(QString)));
connect(ui->miscSitesTreeWidget, SIGNAL(activated(QString)), SLOT(slotUrlClicked(QString)));
connect(ui->supportSitesTreeWidget, SIGNAL(activated(QString)), SLOT(slotUrlClicked(QString)));
connect(m_rssFetcher, SIGNAL(newsItemReady(QString, QString, QString)),
ui->newsTreeWidget, SLOT(addNewsItem(QString, QString, QString)), Qt::QueuedConnection);
connect(this, SIGNAL(startRssFetching(QUrl)), m_rssFetcher, SLOT(fetch(QUrl)), Qt::QueuedConnection);
m_rssFetcher->start(QThread::LowestPriority);
//: Add localized feed here only if one exists
emit startRssFetching(QUrl(tr("http://labs.trolltech.com/blogs/feed")));
populateWelcomeTreeWidget(supportSites, sizeof(supportSites)/sizeof(Site), ui->supportSitesTreeWidget);
populateWelcomeTreeWidget(sites, sizeof(sites)/sizeof(Site), ui->miscSitesTreeWidget);
}
CommunityWelcomePageWidget::~CommunityWelcomePageWidget()
{
m_rssFetcher->exit();
m_rssFetcher->wait();
delete m_rssFetcher;
delete ui;
}
void CommunityWelcomePageWidget::slotUrlClicked(const QString &data)
{
QDesktopServices::openUrl(QUrl(data));
}
} // namespace Internal
} // namespace Welcome

View File

@@ -1,76 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** 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.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#ifndef COMMUNITYWELCOMEPAGEWIDGET_H
#define COMMUNITYWELCOMEPAGEWIDGET_H
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class QUrl;
QT_END_NAMESPACE
namespace Core{
class RssFetcher;
}
namespace Welcome {
namespace Internal {
namespace Ui {
class CommunityWelcomePageWidget;
}
class CommunityWelcomePageWidget : public QWidget
{
Q_OBJECT
public:
explicit CommunityWelcomePageWidget(QWidget *parent = 0);
~CommunityWelcomePageWidget();
signals:
void startRssFetching(const QUrl& url);
private slots:
void slotUrlClicked(const QString &data);
private:
Core::RssFetcher *m_rssFetcher;
Ui::CommunityWelcomePageWidget *ui;
};
} // namespace Internal
} // namespace Welcome
#endif // COMMUNITYWELCOMEPAGEWIDGET_H

View File

@@ -95,6 +95,7 @@ private Q_SLOTS:
void labelledStatements2();
void labelledStatements3();
void json1();
void multilineTernaryInProperty();
};
struct Line {
@@ -1226,6 +1227,29 @@ void tst_QMLCodeFormatter::json1()
checkIndent(data);
}
void tst_QMLCodeFormatter::multilineTernaryInProperty()
{
QList<Line> data;
data << Line("Item {")
<< Line(" property int a: 1 ?")
<< Line(" 2 :")
<< Line(" 3 +")
<< Line(" 4")
<< Line(" property int a: 1 ? 2")
<< Line(" : 3 +")
<< Line(" 4")
<< Line(" a: 1 ?")
<< Line(" 2 :")
<< Line(" 3")
<< Line(" a: 1 ? 2")
<< Line(" : 3 +")
<< Line(" 4")
<< Line(" ba: 1")
<< Line("}")
;
checkIndent(data);
}
QTEST_APPLESS_MAIN(tst_QMLCodeFormatter)
#include "tst_qmlcodeformatter.moc"

View File

@@ -2528,6 +2528,11 @@ void testMemoryView()
a[i] = i;
}
void testNullPointerDeref()
{
*(int *)0 = 0;
}
void testEndlessRecursion()
{
testEndlessRecursion();
@@ -3702,6 +3707,7 @@ int main(int argc, char *argv[])
qregion::testQRegion();
peekandpoke::testPeekAndPoke3();
anon::testAnonymous();
//testNullPointerDeref();
//testEndlessLoop();
//testEndlessRecursion();
testQStack();

View File

@@ -162,3 +162,55 @@ def createNewQtQuickApplication(workingDir, projectName = None, templateFile = N
clickButton(nextButton)
selectFromCombo(":addToVersionControlComboBox_QComboBox", "<None>")
clickButton(waitForObject("{type='QPushButton' text~='(Finish|Done)' visible='1'}", 20000))
def createNewQtQuickUI(workingDir):
invokeMenuItem("File", "New File or Project...")
clickItem(waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000), "Projects.Qt Quick Project", 5, 5, 0, Qt.LeftButton)
clickItem(waitForObject("{name='templatesView' type='QListView'}", 20000), "Qt Quick UI", 5, 5, 0, Qt.LeftButton)
clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000))
baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000)
if workingDir == None:
workingDir = tempDir()
replaceEditorContent(baseLineEd, workingDir)
stateLabel = findObject("{type='QLabel' name='stateLabel'}")
labelCheck = stateLabel.text=="" and stateLabel.styleSheet == ""
test.verify(labelCheck, "Project name and base directory without warning or error")
# make sure this is not set as default location
cbDefaultLocation = waitForObject("{type='QCheckBox' name='projectsDirectoryCheckBox' visible='1'}", 20000)
if cbDefaultLocation.checked:
clickButton(cbDefaultLocation)
# now there's the 'untitled' project inside a temporary directory - step forward...!
clickButton(waitForObject("{text~='(Next.*|Continue)' type='QPushButton' visible='1'}", 20000))
selectFromCombo(":addToVersionControlComboBox_QComboBox", "<None>")
clickButton(waitForObject("{type='QPushButton' text~='(Finish|Done)' visible='1'}", 20000))
def createNewQmlExtension(workingDir):
invokeMenuItem("File", "New File or Project...")
clickItem(waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000), "Projects.Qt Quick Project", 5, 5, 0, Qt.LeftButton)
clickItem(waitForObject("{name='templatesView' type='QListView'}", 20000), "Custom QML Extension Plugin", 5, 5, 0, Qt.LeftButton)
clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000))
baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000)
if workingDir == None:
workingDir = tempDir()
replaceEditorContent(baseLineEd, workingDir)
stateLabel = findObject("{type='QLabel' name='stateLabel'}")
labelCheck = stateLabel.text=="" and stateLabel.styleSheet == ""
test.verify(labelCheck, "Project name and base directory without warning or error")
# make sure this is not set as default location
cbDefaultLocation = waitForObject("{type='QCheckBox' name='projectsDirectoryCheckBox' visible='1'}", 20000)
if cbDefaultLocation.checked:
clickButton(cbDefaultLocation)
# now there's the 'untitled' project inside a temporary directory - step forward...!
nextButton = waitForObject("{text~='(Next.*|Continue)' type='QPushButton' visible='1'}", 20000)
clickButton(nextButton)
chooseTargets()
clickButton(nextButton)
nameLineEd = waitForObject("{buddy={type='QLabel' text='Object Class-name:' unnamed='1' visible='1'} "
"type='QLineEdit' unnamed='1' visible='1'}", 20000)
replaceEditorContent(nameLineEd, "TestItem")
uriLineEd = waitForObject("{buddy={type='QLabel' text='URI:' unnamed='1' visible='1'} "
"type='QLineEdit' unnamed='1' visible='1'}", 20000)
replaceEditorContent(uriLineEd, "com.nokia.test.qmlcomponents")
clickButton(nextButton)
selectFromCombo(":addToVersionControlComboBox_QComboBox", "<None>")
clickButton(waitForObject("{type='QPushButton' text~='(Finish|Done)' visible='1'}", 20000))

View File

@@ -21,11 +21,13 @@ source("../../shared/editor_utils.py")
def waitForCleanShutdown(timeOut=10):
appCtxt = currentApplicationContext()
shutdownDone = False
shutdownDone = (str(appCtxt)=="")
if platform.system() in ('Windows','Microsoft'):
endtime = datetime.utcnow() + timedelta(seconds=timeOut)
while not shutdownDone:
# following work-around because os.kill() works for win not until python 2.7
if appCtxt.pid==-1:
break
tasks = subprocess.Popen("tasklist /FI \"PID eq %d\"" % appCtxt.pid, shell=True,stdout=subprocess.PIPE)
output = tasks.communicate()[0]
tasks.stdout.close()
@@ -47,7 +49,7 @@ def waitForCleanShutdown(timeOut=10):
def __removeTmpSettingsDir__():
waitForCleanShutdown()
deleteDirIfExists(os.path.dirname(tmpSettingsDir))
deleteDirIfExists(os.path.dirname(os.path.dirname(tmpSettingsDir)))
if platform.system() in ('Windows', 'Microsoft'):
sdkPath = "C:\\QtSDK"
@@ -67,5 +69,5 @@ tmpSettingsDir = os.path.abspath(tmpSettingsDir+"/settings")
shutil.copytree(cwd, tmpSettingsDir)
# the following only doesn't work if the test ends in an exception
atexit.register(__removeTmpSettingsDir__)
SettingsPath = " -settingspath %s" % tmpSettingsDir
SettingsPath = ' -settingspath "%s"' % tmpSettingsDir

View File

@@ -119,8 +119,11 @@ def runAndCloseQtQuickUI():
# the following is currently a work-around for not using hooking into subprocesses
if (waitForObject(":Qt Creator_Core::Internal::OutputPaneToggleButton").checked!=True):
clickButton(":Qt Creator_Core::Internal::OutputPaneToggleButton")
clickButton(":Qt Creator.Stop_QToolButton")
stop = findObject(":Qt Creator.Stop_QToolButton")
waitFor("stop.enabled==True")
clickButton(stop)
if platform.system()=="Darwin":
waitFor("stop.enabled==False")
snooze(2)
nativeType("<Escape>")
return True

View File

@@ -32,11 +32,22 @@ def testRenameId():
model = navTree.model()
files = ["Core.ContextMenu\\.qml", "Core.GridMenu\\.qml", "Core.ListMenu\\.qml", "focus\\.qml"]
originalTexts = {}
editor = waitForObject("{type='QmlJSEditor::QmlJSTextEditorWidget' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", 20000)
# temporarily store editor content for synchronizing purpose
# usage of formerTxt is done because I couldn't get waitForSignal() to work
# it always stored a different object into the signalObjects map as it looked up afterwards
# although used objectMap.realName() for both
formerTxt = editor.plainText
for file in files:
doubleClickFile(navTree, file)
editor = waitForObject("{type='QmlJSEditor::QmlJSTextEditorWidget' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", 20000)
originalTexts.setdefault(file, "%s" % editor.plainText)
# wait until editor content switched to the double-clicked file
while formerTxt==editor.plainText:
editor = waitForObject("{type='QmlJSEditor::QmlJSTextEditorWidget' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", 20000)
# store content for next round
formerTxt = editor.plainText
originalTexts.setdefault(file, "%s" % formerTxt)
test.log("stored %s's content" % file.replace("Core.","").replace("\\",""))
# last opened file is the main file focus.qml
line = "FocusScope\s*\{"
@@ -52,21 +63,32 @@ def testRenameId():
"window=':Qt Creator_Core::Internal::MainWindow'}"), "renamedView")
clickButton(waitForObject("{text='Replace' type='QToolButton' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}"))
# store editor content for synchronizing purpose
formerTxt = editor.plainText
for file in files:
doubleClickFile(navTree, file)
editor = waitForObject("{type='QmlJSEditor::QmlJSTextEditorWidget' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", 20000)
modifiedText = "%s" % editor.plainText
# wait until editor content switched to double-clicked file
while formerTxt==editor.plainText:
editor = waitForObject("{type='QmlJSEditor::QmlJSTextEditorWidget' unnamed='1' visible='1' "
"window=':Qt Creator_Core::Internal::MainWindow'}", 20000)
# store content for next round
formerTxt = editor.plainText
originalText = originalTexts.get(file).replace("mainView", "renamedView")
test.compare(originalText,modifiedText)
test.compare(originalText,formerTxt, "Comparing %s" % file.replace("Core.","").replace("\\",""))
invokeMenuItem("File","Save All")
def doubleClickFile(navTree, file):
treeElement = ("untitled.QML.%s/qml.%s" %
(templateDir.replace("\\", "/").replace("_", "\\_").replace(".","\\."),file))
(maskSpecialCharsForProjectTree(templateDir),file))
waitForObjectItem(navTree, treeElement)
doubleClickItem(navTree, treeElement, 5, 5, 0, Qt.LeftButton)
def maskSpecialCharsForProjectTree(filename):
filename = filename.replace("\\", "/").replace("_", "\\_").replace(".","\\.")
# undoing mask operations on chars masked by mistake
filename = filename.replace("/?","\\?").replace("/*","\\*")
return filename
def cleanup():
global workingDir, templateDir
waitForCleanShutdown()

View File

@@ -7,32 +7,12 @@ def main():
startApplication("qtcreator" + SettingsPath)
# using a temporary directory won't mess up an eventually exisiting
workingDir = tempDir()
createNewQtQuickUI()
createNewQtQuickUI(workingDir)
test.log("Running project")
if runAndCloseQtQuickUI():
logApplicationOutput()
invokeMenuItem("File", "Exit")
def createNewQtQuickUI():
global workingDir
invokeMenuItem("File", "New File or Project...")
clickItem(waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000), "Projects.Qt Quick Project", 5, 5, 0, Qt.LeftButton)
clickItem(waitForObject("{name='templatesView' type='QListView'}", 20000), "Qt Quick UI", 5, 5, 0, Qt.LeftButton)
clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000))
baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000)
replaceEditorContent(baseLineEd, workingDir)
stateLabel = findObject("{type='QLabel' name='stateLabel'}")
labelCheck = stateLabel.text=="" and stateLabel.styleSheet == ""
test.verify(labelCheck, "Project name and base directory without warning or error")
# make sure this is not set as default location
cbDefaultLocation = waitForObject("{type='QCheckBox' name='projectsDirectoryCheckBox' visible='1'}", 20000)
if cbDefaultLocation.checked:
clickButton(cbDefaultLocation)
# now there's the 'untitled' project inside a temporary directory - step forward...!
clickButton(waitForObject("{text~='(Next.*|Continue)' type='QPushButton' visible='1'}", 20000))
selectFromCombo(":addToVersionControlComboBox_QComboBox", "<None>")
clickButton(waitForObject("{type='QPushButton' text~='(Finish|Done)' visible='1'}", 20000))
def cleanup():
global workingDir
# waiting for a clean exit - for a full-remove of the temp directory

View File

@@ -7,7 +7,7 @@ def main():
startApplication("qtcreator" + SettingsPath)
# using a temporary directory won't mess up an eventually exisiting
workingDir = tempDir()
createNewQmlExtension()
createNewQmlExtension(workingDir)
# wait for parsing to complete
waitForSignal("{type='CppTools::Internal::CppModelManager' unnamed='1'}", "sourceFilesRefreshed(QStringList)", 30000)
test.log("Building project")
@@ -17,36 +17,6 @@ def main():
checkLastBuild()
invokeMenuItem("File", "Exit")
def createNewQmlExtension():
global workingDir
invokeMenuItem("File", "New File or Project...")
clickItem(waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000), "Projects.Qt Quick Project", 5, 5, 0, Qt.LeftButton)
clickItem(waitForObject("{name='templatesView' type='QListView'}", 20000), "Custom QML Extension Plugin", 5, 5, 0, Qt.LeftButton)
clickButton(waitForObject("{text='Choose...' type='QPushButton' unnamed='1' visible='1'}", 20000))
baseLineEd = waitForObject("{type='Utils::BaseValidatingLineEdit' unnamed='1' visible='1'}", 20000)
replaceEditorContent(baseLineEd, workingDir)
stateLabel = findObject("{type='QLabel' name='stateLabel'}")
labelCheck = stateLabel.text=="" and stateLabel.styleSheet == ""
test.verify(labelCheck, "Project name and base directory without warning or error")
# make sure this is not set as default location
cbDefaultLocation = waitForObject("{type='QCheckBox' name='projectsDirectoryCheckBox' visible='1'}", 20000)
if cbDefaultLocation.checked:
clickButton(cbDefaultLocation)
# now there's the 'untitled' project inside a temporary directory - step forward...!
nextButton = waitForObject("{text~='(Next.*|Continue)' type='QPushButton' visible='1'}", 20000)
clickButton(nextButton)
chooseTargets()
clickButton(nextButton)
nameLineEd = waitForObject("{buddy={type='QLabel' text='Object Class-name:' unnamed='1' visible='1'} "
"type='QLineEdit' unnamed='1' visible='1'}", 20000)
replaceEditorContent(nameLineEd, "TestItem")
uriLineEd = waitForObject("{buddy={type='QLabel' text='URI:' unnamed='1' visible='1'} "
"type='QLineEdit' unnamed='1' visible='1'}", 20000)
replaceEditorContent(uriLineEd, "com.nokia.test.qmlcomponents")
clickButton(nextButton)
selectFromCombo(":addToVersionControlComboBox_QComboBox", "<None>")
clickButton(waitForObject("{type='QPushButton' text~='(Finish|Done)' visible='1'}", 20000))
def cleanup():
global workingDir
# waiting for a clean exit - for a full-remove of the temp directory