diff --git a/README b/README index b366ad1c1c2..ee54db57bac 100644 --- a/README +++ b/README @@ -107,7 +107,7 @@ SDK (release builds of Qt using MinGW and Visual C++ 2008). For the Visual C++ compilers, it is recommended to use the tool 'jom'. It is a replacement for nmake that utilizes all CPU cores and thus speeds up compilation significantly. Download it from - ftp://ftp.qt.nokia.com/jom/ and add the executable to the path. + http://releases.qt-project.org/jom/ and add the executable to the path. 8. For convenience, we recommend creating shell prompts with the correct environment. This can be done by creating a .bat-file diff --git a/dist/installer/ifw/config/config-linux.xml.in b/dist/installer/ifw/config/config-linux.xml.in new file mode 100644 index 00000000000..4bc8a0c5398 --- /dev/null +++ b/dist/installer/ifw/config/config-linux.xml.in @@ -0,0 +1,24 @@ + + + Qt Creator + {version} + Qt Creator {version} + Qt Creator Maintenance + Qt Project + http://qt-project.org + + logo.png + watermark.png + QtCreatorUninstaller + + @homeDir@/qtcreator-{version} + /opt/qtcreator-{version} + + + + I have read and understood the terms contained in the above license agreements. + I do not accept the terms contained in the above license agreements. + + + + diff --git a/dist/installer/ifw/config/config.xml.in b/dist/installer/ifw/config/config-windows.xml.in similarity index 85% rename from dist/installer/ifw/config/config.xml.in rename to dist/installer/ifw/config/config-windows.xml.in index 39fe7f4f00f..0d9d8e87c19 100644 --- a/dist/installer/ifw/config/config.xml.in +++ b/dist/installer/ifw/config/config-windows.xml.in @@ -2,7 +2,7 @@ Qt Creator {version} - Qt Creator + Qt Creator {version} Qt Creator Maintenance Qt Project http://qt-project.org @@ -11,8 +11,7 @@ watermark.png QtCreatorUninstaller - @homeDir@/QtCreator - /opt/QtCreator + @rootDir@/Qt/qtcreator-{version} diff --git a/dist/installer/ifw/packages/org.qtproject.qtcreator.application/meta/installscript.qs b/dist/installer/ifw/packages/org.qtproject.qtcreator.application/meta/installscript.qs index f9fb76c34f0..a9bd1debda0 100644 --- a/dist/installer/ifw/packages/org.qtproject.qtcreator.application/meta/installscript.qs +++ b/dist/installer/ifw/packages/org.qtproject.qtcreator.application/meta/installscript.qs @@ -31,6 +31,7 @@ function Component() { installer.finishButtonClicked.connect(this, Component.prototype.installationFinished); + installer.setDefaultPageVisible(QInstaller.ComponentSelection, false); } Component.prototype.beginInstallation = function() @@ -120,7 +121,7 @@ Component.prototype.createOperations = function() "@TargetDir@\\bin\\qtcreator.exe", "@StartMenuDir@/Qt Creator.lnk", "workingDirectory=@homeDir@" ); - component.addElevatedOperation("Execute", "{0,3010}", "@TargetDir@\\lib\\vcredist_msvc2010\\vcredist_x86.exe", "/q"); + component.addElevatedOperation("Execute", "{0,3010}", "@TargetDir@\\lib\\vcredist_msvc2010\\vcredist_x86.exe", "/norestart", "/q"); registerWindowsFileTypeExtensions(); } if ( installer.value("os") == "x11" ) diff --git a/doc/images/qmldesigner-import-project.png b/doc/images/qmldesigner-import-project.png index 7856d70f772..393196b23db 100644 Binary files a/doc/images/qmldesigner-import-project.png and b/doc/images/qmldesigner-import-project.png differ diff --git a/doc/images/qmldesigner-new-app-project-mobile-options.png b/doc/images/qmldesigner-new-app-project-mobile-options.png deleted file mode 100644 index 98cd1853e47..00000000000 Binary files a/doc/images/qmldesigner-new-app-project-mobile-options.png and /dev/null differ diff --git a/doc/images/qmldesigner-new-project-harmattan-options.png b/doc/images/qmldesigner-new-project-harmattan-options.png deleted file mode 100644 index be0238480ce..00000000000 Binary files a/doc/images/qmldesigner-new-project-harmattan-options.png and /dev/null differ diff --git a/doc/images/qmldesigner-new-project-location.png b/doc/images/qmldesigner-new-project-location.png deleted file mode 100644 index dd3f9bc1611..00000000000 Binary files a/doc/images/qmldesigner-new-project-location.png and /dev/null differ diff --git a/doc/images/qmldesigner-new-project-qt-versions.png b/doc/images/qmldesigner-new-project-qt-versions.png deleted file mode 100644 index 8937e959263..00000000000 Binary files a/doc/images/qmldesigner-new-project-qt-versions.png and /dev/null differ diff --git a/doc/images/qmldesigner-new-project-summary.png b/doc/images/qmldesigner-new-project-summary.png deleted file mode 100644 index bf0e2ebc8b4..00000000000 Binary files a/doc/images/qmldesigner-new-project-summary.png and /dev/null differ diff --git a/doc/images/qmldesigner-new-ui-project-location.png b/doc/images/qmldesigner-new-ui-project-location.png deleted file mode 100644 index 4439abf87d3..00000000000 Binary files a/doc/images/qmldesigner-new-ui-project-location.png and /dev/null differ diff --git a/doc/images/qmldesigner-new-ui-project-summary.png b/doc/images/qmldesigner-new-ui-project-summary.png deleted file mode 100644 index 299b2adf34a..00000000000 Binary files a/doc/images/qmldesigner-new-ui-project-summary.png and /dev/null differ diff --git a/doc/images/qtcreator-kit-selector.png b/doc/images/qtcreator-kit-selector.png index 06c691a5810..4319cb32a40 100644 Binary files a/doc/images/qtcreator-kit-selector.png and b/doc/images/qtcreator-kit-selector.png differ diff --git a/doc/images/qtcreator-pprunsettings.png b/doc/images/qtcreator-pprunsettings.png index 35528c761ae..12d7652f5ab 100644 Binary files a/doc/images/qtcreator-pprunsettings.png and b/doc/images/qtcreator-pprunsettings.png differ diff --git a/doc/src/howto/qtcreator-faq.qdoc b/doc/src/howto/qtcreator-faq.qdoc index 0ca18778d3a..979ca054ea8 100644 --- a/doc/src/howto/qtcreator-faq.qdoc +++ b/doc/src/howto/qtcreator-faq.qdoc @@ -167,7 +167,7 @@ On Windows, nmake does not support the \c{-j} parameter. Instead, we provide a drop-in replacement called jom. You can download a precompiled - version of jom from \l{ftp://ftp.qt.nokia.com/jom/}{Qt FTP server}. + version of jom from \l{http://releases.qt-project.org/jom/}{Qt Project Release server}. Put jom.exe in a location in the %PATH%. Go to the \gui {Build Settings} and set jom.exe as the make command. diff --git a/doc/src/projects/creator-projects-settings-run-desktop.qdocinc b/doc/src/projects/creator-projects-settings-run-desktop.qdocinc index 06b680927f2..c2d81a21eca 100644 --- a/doc/src/projects/creator-projects-settings-run-desktop.qdocinc +++ b/doc/src/projects/creator-projects-settings-run-desktop.qdocinc @@ -10,6 +10,14 @@ \image qtcreator-pprunsettings.png + The \gui {Use debug version of frameworks (DYLD_IMAGE_SUFFIX=_debug)} option + (available on Mac OS, only) enables you to debug (for example, step into) + linked frameworks, such as the Qt framework itself. You do not need this + option for debugging your application code. If you select this option, a + crash might occur when debugging applications on Mac OS X Snow Leopard. For + more information, see + \l{Application Crashes when Debugging on Mac OS X Snow Leopard}. + You can also create custom executable run configurations where you can set the executable to be run. For more information, see \l{Specifying a Custom Executable to Run}. diff --git a/doc/src/qtquick/qtquick-creating.qdoc b/doc/src/qtquick/qtquick-creating.qdoc index 906dacb3181..00588530eef 100644 --- a/doc/src/qtquick/qtquick-creating.qdoc +++ b/doc/src/qtquick/qtquick-creating.qdoc @@ -77,32 +77,8 @@ \section1 Creating Qt Quick UI Projects - \list 1 - - \o Select \gui {File > New File or Project > Applications > - Qt Quick UI > Choose}. - - The \gui{Introduction and Project Location} dialog opens. - - \image qmldesigner-new-ui-project-location.png "Introduction and Project Location dialog" - - \o In the \gui Name field, give a name to the project. - - Do not use spaces and special characters in the project name and - path. - - \o In the \gui {Create in} field, enter the path for the project files. - For example, \c {C:\Qt\examples}. To select the path from a - directory tree, click \gui Browse. - - \o Click \gui{Next}. - - \image qmldesigner-new-ui-project-summary.png "Project Management dialog" - - \o Review the project settings, and click \gui{Finish} to create the - project. - - \endlist + Select \gui {File > New File or Project > Applications > Qt Quick UI > + Choose} and follow the instructions of the wizard. \QC creates the following files: @@ -127,78 +103,19 @@ \section1 Creating Qt Quick Applications - \list 1 + Select \gui File > \gui {New File or Project} > \gui Applications > + \gui {Qt Quick Application 1 (Built-in Elements)} or \gui {Qt Quick + Application 2 (Built-in Elements)} > \gui Choose, and follow the + instructions of the wizard. - \o Select \gui {File > New File or Project > Applications > - Qt Quick Application (Built-in Elements) > Choose}. - - \note We recommend that you use the \gui {Qt Quick Application for - MeeGo Harmattan} template when you develop for MeeGo Harmattan - devices. - - The \gui{Introduction and Project Location} dialog opens. - - \image qmldesigner-new-project-location.png "Introduction and Project Location dialog" - - \o In the \gui Name field, give a name to the project. - - Do not use spaces and special characters in the project name and - path. - - \o In the \gui {Create in} field, enter the path for the project files. - For example, \c {C:\Qt\examples}. To select the path from a - directory tree, click \gui Browse. - - \o Click \gui{Next}. - - The \gui {Kit Selection} dialog opens. - - \image qmldesigner-new-project-qt-versions.png "Kit Selection dialog" - - \o Select build and run \l{glossary-buildandrun-kit}{kits} for your project, - and then click \gui{Next}. - - \note If only one kit is specified in \gui Tools > \gui Options > - \gui {Build & Run} > \gui Kits, this dialog is skipped. - - The \gui {Mobile Options} dialog opens. - - \image qmldesigner-new-app-project-mobile-options.png "Mobile Options dialog" - - \o In the \gui {Orientation behavior} field, determine how the - application behaves when the orientation of the device display - rotates between portrait and landscape, and then click \gui Next. - - \note This dialog opens only if you select a \l{glossary-buildandrun-kit}{kit} - with \gui Maemo5 device type in the \gui {Kit Selection} dialog. On - Harmattan, the Qt Quick Components for MeeGo provide native-looking - rotation. - - \o Click \gui Next. - - The \gui {Harmattan Specific} dialog opens. - - \image qmldesigner-new-project-harmattan-options.png "Harmattan Specific dialog" - - \o In the \gui {Application icon} field, select the application - icon to use on Maemo or Harmattan devices, or use the default icon. - - The \gui {Project Management} dialog opens. - - \image qmldesigner-new-project-summary.png "Project Management dialog" - - \o In the \gui {Add to project} field, you can add this project to - another project as a subproject. - - \o In the \gui {Add to version control} field, you can add the project - to a version control system. - - \o Click \gui Finish to create the project. - - \endlist + \note The SDK for a particular target platform might install additional + templates for that platform. For example, the \gui {Qt Quick Application for + MeeGo Harmattan} template is installed as part of the MeeGo Harmattan tool + chain and the QNX templates are installed as part of the BlackBerry NDK or + the QNX SDK. \QC creates the necessary boilerplate files. Some of the files are - specific to the Maemo or MeeGo Harmattan platform. + specific to a particular target platform. \section1 Importing QML Applications diff --git a/doc/templates/scripts/functions.js b/doc/templates/scripts/functions.js index 32cc901fe93..1b1f8732931 100644 --- a/doc/templates/scripts/functions.js +++ b/doc/templates/scripts/functions.js @@ -53,7 +53,7 @@ var articleCount = 0; var exampleCount = 0; var qturl = ""; // change from "http://doc.qt.nokia.com/4.6/" to 0 so we can have relative links -function processNokiaData(response){ +function processData(response){ var propertyTags = response.getElementsByTagName('page'); for (var i=0; i< propertyTags.length; i++) { @@ -180,7 +180,7 @@ else $('.searching').remove(); $('#pageType').removeClass('loading'); $('.list ul').prepend(''); - processNokiaData(response); + processData(response); } }); diff --git a/scripts/packageIfw.py b/scripts/packageIfw.py index 82bddc7b72d..c6f55bc2652 100755 --- a/scripts/packageIfw.py +++ b/scripts/packageIfw.py @@ -86,8 +86,15 @@ def main(): raise Exception('Archive not specified (--archive)!') installer_name = args[0] + config_postfix = '' if sys.platform == 'darwin': installer_name = installer_name + '.dmg' + if sys.platform.startswith('win'): + config_postfix = '-windows' + if sys.platform.startswith('linux'): + config_postfix = '-linux' + + config_name = 'config' + config_postfix + '.xml' try: temp_dir = tempfile.mkdtemp() @@ -121,7 +128,7 @@ def main(): os.makedirs(data_path) shutil.copy(archive, data_path) - ifw_call = [os.path.join(ifw_location, 'bin', 'binarycreator'), '-c', os.path.join(out_config_dir, 'config.xml'), '-p', out_packages_dir, installer_name, '--offline-only' ] + ifw_call = [os.path.join(ifw_location, 'bin', 'binarycreator'), '-c', os.path.join(out_config_dir, config_name), '-p', out_packages_dir, installer_name, '--offline-only' ] subprocess.check_call(ifw_call, stderr=subprocess.STDOUT) finally: print 'Cleaning up...' diff --git a/share/qtcreator/templates/wizards/bb-bardescriptor/bar-descriptor.xml b/share/qtcreator/templates/wizards/bb-bardescriptor/bar-descriptor.xml index c5cc31166bb..f1a18771abc 100644 --- a/share/qtcreator/templates/wizards/bb-bardescriptor/bar-descriptor.xml +++ b/share/qtcreator/templates/wizards/bb-bardescriptor/bar-descriptor.xml @@ -16,8 +16,6 @@ - -platform - blackberry -style qnxlight diff --git a/share/qtcreator/templates/wizards/bb-guiapp/bar-descriptor.xml b/share/qtcreator/templates/wizards/bb-guiapp/bar-descriptor.xml index 5727904396c..96071e6ba63 100644 --- a/share/qtcreator/templates/wizards/bb-guiapp/bar-descriptor.xml +++ b/share/qtcreator/templates/wizards/bb-guiapp/bar-descriptor.xml @@ -15,8 +15,6 @@ - -platform - blackberry run_native %ProjectName% diff --git a/share/qtcreator/templates/wizards/bb-quickapp/bar-descriptor.xml b/share/qtcreator/templates/wizards/bb-quickapp/bar-descriptor.xml index 8f0a09e6115..eef7a876738 100644 --- a/share/qtcreator/templates/wizards/bb-quickapp/bar-descriptor.xml +++ b/share/qtcreator/templates/wizards/bb-quickapp/bar-descriptor.xml @@ -15,8 +15,6 @@ - -platform - blackberry run_native %ProjectName% diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 90385f8c91f..3cd02f334c9 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -7774,7 +7774,7 @@ konnte dem Projekt '%2' nicht hinzugefügt werden. <a href="qthelp://com.nokia.qtcreator/doc/creator-project-managing-sessions.html">What is a Session?</a> - <a href="qthelp://com.nokia.qtcreator/doc/creator-project-managing-sessions.htm">Was ist eine Sitzung?</a> + <a href="qthelp://com.nokia.qtcreator/doc/creator-project-managing-sessions.html">Was ist eine Sitzung?</a> Automatically restore the last session when Qt Creator is started. diff --git a/src/libs/3rdparty/cplusplus/Name.cpp b/src/libs/3rdparty/cplusplus/Name.cpp index 6c1240b279e..8fec45f5c07 100644 --- a/src/libs/3rdparty/cplusplus/Name.cpp +++ b/src/libs/3rdparty/cplusplus/Name.cpp @@ -18,10 +18,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include "Literals.h" #include "Name.h" #include "Names.h" #include "NameVisitor.h" +#include + using namespace CPlusPlus; Name::Name() @@ -65,4 +68,16 @@ void Name::accept(const Name *name, NameVisitor *visitor) name->accept(visitor); } +bool Name::Compare::operator()(const Name *name, const Name *other) const +{ + if (name == 0) + return other != 0; + if (other == 0) + return false; + if (name == other) + return false; + const Identifier *id = name->identifier(); + const Identifier *otherId = other->identifier(); + return std::strcmp(id->chars(), otherId->chars()) < 0; +} diff --git a/src/libs/3rdparty/cplusplus/Name.h b/src/libs/3rdparty/cplusplus/Name.h index 8a34b364790..43dcf3d35cc 100644 --- a/src/libs/3rdparty/cplusplus/Name.h +++ b/src/libs/3rdparty/cplusplus/Name.h @@ -23,6 +23,7 @@ #include "CPlusPlusForwardDeclarations.h" +#include namespace CPlusPlus { @@ -55,6 +56,11 @@ public: void accept(NameVisitor *visitor) const; static void accept(const Name *name, NameVisitor *visitor); +public: + struct Compare: std::binary_function { + bool operator()(const Name *name, const Name *other) const; + }; + protected: virtual void accept0(NameVisitor *visitor) const = 0; }; diff --git a/src/libs/3rdparty/cplusplus/Templates.cpp b/src/libs/3rdparty/cplusplus/Templates.cpp index 095fa010a93..3cf6ff62bea 100644 --- a/src/libs/3rdparty/cplusplus/Templates.cpp +++ b/src/libs/3rdparty/cplusplus/Templates.cpp @@ -514,10 +514,12 @@ Symbol *Clone::instantiate(Template *templ, const FullySpecifiedType *const args // // substitutions // + + FullySpecifiedType Subst::apply(const Name *name) const { if (name) { - std::map::const_iterator it = _map.find(name); + std::map::const_iterator it = _map.find(name); if (it != _map.end()) return it->second; else if (_previous) diff --git a/src/libs/3rdparty/cplusplus/Templates.h b/src/libs/3rdparty/cplusplus/Templates.h index 0057d7fcbfc..04064a89067 100644 --- a/src/libs/3rdparty/cplusplus/Templates.h +++ b/src/libs/3rdparty/cplusplus/Templates.h @@ -24,6 +24,7 @@ #include "CPlusPlusForwardDeclarations.h" #include "TypeVisitor.h" #include "FullySpecifiedType.h" +#include "Name.h" #include "NameVisitor.h" #include "SymbolVisitor.h" #include @@ -56,7 +57,7 @@ public: private: Control *_control; Subst *_previous; - std::map _map; + std::map _map; }; class CPLUSPLUS_EXPORT CloneType: protected TypeVisitor diff --git a/src/libs/cplusplus/LookupContext.cpp b/src/libs/cplusplus/LookupContext.cpp index 51efb92a29c..1fbe5c5e601 100644 --- a/src/libs/cplusplus/LookupContext.cpp +++ b/src/libs/cplusplus/LookupContext.cpp @@ -120,21 +120,12 @@ bool compareFullyQualifiedName(const QList &path, const QListidentifier(); - const Identifier *otherId = other->identifier(); - return strcmp(id->chars(), otherId->chars()) < 0; -} - ///////////////////////////////////////////////////////////////////// // LookupContext ///////////////////////////////////////////////////////////////////// LookupContext::LookupContext() : _control(new Control()) + , m_expandTemplates(false) { } LookupContext::LookupContext(Document::Ptr thisDocument, @@ -142,7 +133,8 @@ LookupContext::LookupContext(Document::Ptr thisDocument, : _expressionDocument(Document::create("")), _thisDocument(thisDocument), _snapshot(snapshot), - _control(new Control()) + _control(new Control()), + m_expandTemplates(false) { } @@ -152,7 +144,8 @@ LookupContext::LookupContext(Document::Ptr expressionDocument, : _expressionDocument(expressionDocument), _thisDocument(thisDocument), _snapshot(snapshot), - _control(new Control()) + _control(new Control()), + m_expandTemplates(false) { } @@ -161,7 +154,8 @@ LookupContext::LookupContext(const LookupContext &other) _thisDocument(other._thisDocument), _snapshot(other._snapshot), _bindings(other._bindings), - _control(other._control) + _control(other._control), + m_expandTemplates(other.m_expandTemplates) { } LookupContext &LookupContext::operator = (const LookupContext &other) @@ -171,6 +165,7 @@ LookupContext &LookupContext::operator = (const LookupContext &other) _snapshot = other._snapshot; _bindings = other._bindings; _control = other._control; + m_expandTemplates = other.m_expandTemplates; return *this; } @@ -227,8 +222,10 @@ const Name *LookupContext::minimalName(Symbol *symbol, ClassOrNamespace *target, QSharedPointer LookupContext::bindings() const { - if (! _bindings) + if (! _bindings) { _bindings = QSharedPointer(new CreateBindings(_thisDocument, _snapshot, control())); + _bindings->setExpandTemplates(m_expandTemplates); + } return _bindings; } @@ -728,7 +725,6 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac instantiation->_instantiationOrigin = origin; // The instantiation should have all symbols, enums, and usings from the reference. - instantiation->_symbols.append(reference->symbols()); instantiation->_enums.append(reference->enums()); instantiation->_usings.append(reference->usings()); @@ -736,6 +732,28 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac // now must worry about dependent names in base classes. if (Template *templ = referenceClass->enclosingTemplate()) { const unsigned argumentCount = templId->templateArgumentCount(); + + if (_factory->expandTemplates()) { + Subst subst(_control.data()); + for (unsigned i = 0, ei = std::min(argumentCount, templ->templateParameterCount()); i < ei; ++i) { + const TypenameArgument *tParam = templ->templateParameterAt(i)->asTypenameArgument(); + if (!tParam) + continue; + const Name *name = tParam->name(); + if (!name) + continue; + const FullySpecifiedType &ty = templId->templateArgumentAt(i); + subst.bind(name, ty); + } + + Clone cloner(_control.data()); + foreach (Symbol *s, reference->symbols()) { + instantiation->_symbols.append(cloner.symbol(s, &subst)); + } + } else { + instantiation->_symbols.append(reference->symbols()); + } + QHash templParams; for (unsigned i = 0; i < templ->templateParameterCount(); ++i) templParams.insert(templ->templateParameterAt(i)->name(), i); @@ -794,6 +812,8 @@ ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name, ClassOrNamespac if (baseBinding && !knownUsings.contains(baseBinding)) instantiation->addUsing(baseBinding); } + } else { + instantiation->_symbols.append(reference->symbols()); } _alreadyConsideredTemplates.clear(templId); @@ -907,7 +927,7 @@ ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name, ClassOrNa } CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot, QSharedPointer control) - : _snapshot(snapshot), _control(control) + : _snapshot(snapshot), _control(control), _expandTemplates(false) { _globalNamespace = allocClassOrNamespace(/*parent = */ 0); _currentClassOrNamespace = _globalNamespace; diff --git a/src/libs/cplusplus/LookupContext.h b/src/libs/cplusplus/LookupContext.h index 41b5ee9999a..c7b556de432 100644 --- a/src/libs/cplusplus/LookupContext.h +++ b/src/libs/cplusplus/LookupContext.h @@ -119,12 +119,7 @@ private: ClassOrNamespace *nestedType(const Name *name, ClassOrNamespace *origin); private: - struct CompareName: std::binary_function { - bool operator()(const Name *name, const Name *other) const; - }; - -private: - typedef std::map Table; + typedef std::map Table; CreateBindings *_factory; ClassOrNamespace *_parent; QList _symbols; @@ -163,6 +158,11 @@ public: /// \internal QSharedPointer control() const; + bool expandTemplates() const + { return _expandTemplates; } + void setExpandTemplates(bool expandTemplates) + { _expandTemplates = expandTemplates; } + /// Searches in \a scope for symbols with the given \a name. /// Store the result in \a results. /// \internal @@ -223,6 +223,7 @@ private: QList _entities; ClassOrNamespace *_globalNamespace; ClassOrNamespace *_currentClassOrNamespace; + bool _expandTemplates; }; class CPLUSPLUS_EXPORT LookupContext @@ -265,6 +266,9 @@ public: static const Name *minimalName(Symbol *symbol, ClassOrNamespace *target, Control *control); + void setExpandTemplates(bool expandTemplates) + { m_expandTemplates = expandTemplates; } + private: // The current expression. Document::Ptr _expressionDocument; @@ -279,6 +283,8 @@ private: mutable QSharedPointer _bindings; QSharedPointer _control; + + bool m_expandTemplates; }; bool CPLUSPLUS_EXPORT compareName(const Name *name, const Name *other); diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp index e8deecd5aec..379388de214 100644 --- a/src/libs/cplusplus/TypeOfExpression.cpp +++ b/src/libs/cplusplus/TypeOfExpression.cpp @@ -41,7 +41,8 @@ using namespace CPlusPlus; TypeOfExpression::TypeOfExpression(): m_ast(0), - m_scope(0) + m_scope(0), + m_expandTemplates(false) { } @@ -107,6 +108,7 @@ QList TypeOfExpression::operator()(ExpressionAST *expression, m_lookupContext = LookupContext(document, m_thisDocument, m_snapshot); m_lookupContext.setBindings(m_bindings); + m_lookupContext.setExpandTemplates(m_expandTemplates); ResolveExpression resolve(m_lookupContext); const QList items = resolve(m_ast, scope); @@ -127,6 +129,7 @@ QList TypeOfExpression::reference(ExpressionAST *expression, m_lookupContext = LookupContext(document, m_thisDocument, m_snapshot); m_lookupContext.setBindings(m_bindings); + m_lookupContext.setExpandTemplates(m_expandTemplates); ResolveExpression resolve(m_lookupContext); const QList items = resolve.reference(m_ast, scope); diff --git a/src/libs/cplusplus/TypeOfExpression.h b/src/libs/cplusplus/TypeOfExpression.h index fb425db08b6..d0cf07da989 100644 --- a/src/libs/cplusplus/TypeOfExpression.h +++ b/src/libs/cplusplus/TypeOfExpression.h @@ -123,6 +123,9 @@ public: ExpressionAST *expressionAST() const; QByteArray preprocessedExpression(const QByteArray &utf8code) const; + void setExpandTemplates(bool expandTemplates) + { m_expandTemplates = expandTemplates; } + private: void processEnvironment(Document::Ptr doc, Environment *env, @@ -137,6 +140,8 @@ private: Scope *m_scope; LookupContext m_lookupContext; mutable QSharedPointer m_environment; + + bool m_expandTemplates; }; ExpressionAST CPLUSPLUS_EXPORT *extractExpressionAST(Document::Ptr doc); diff --git a/src/libs/ssh/sshchannelmanager.cpp b/src/libs/ssh/sshchannelmanager.cpp index 005f87094d0..b430a0d9ce1 100644 --- a/src/libs/ssh/sshchannelmanager.cpp +++ b/src/libs/ssh/sshchannelmanager.cpp @@ -188,9 +188,15 @@ void SshChannelManager::insertChannel(AbstractSshChannel *priv, int SshChannelManager::closeAllChannels(CloseAllMode mode) { - const int count = m_channels.count(); - for (ChannelIterator it = m_channels.begin(); it != m_channels.end(); ++it) - it.value()->closeChannel(); + int count = 0; + for (ChannelIterator it = m_channels.begin(); it != m_channels.end(); ++it) { + AbstractSshChannel * const channel = it.value(); + QSSH_ASSERT(channel->channelState() != AbstractSshChannel::Closed); + if (channel->channelState() != AbstractSshChannel::CloseRequested) { + channel->closeChannel(); + ++count; + } + } if (mode == CloseAllAndReset) { m_channels.clear(); m_sessions.clear(); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 865471b9656..7304c17662a 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -51,6 +51,7 @@ using namespace Internal; namespace { const char BUILD_DIRECTORY_KEY[] = "CMakeProjectManager.CMakeBuildConfiguration.BuildDirectory"; +const char USE_NINJA_KEY[] = "CMakeProjectManager.CMakeBuildConfiguration.UseNinja"; } // namespace CMakeBuildConfiguration::CMakeBuildConfiguration(ProjectExplorer::Target *parent) : @@ -74,6 +75,7 @@ QVariantMap CMakeBuildConfiguration::toMap() const { QVariantMap map(ProjectExplorer::BuildConfiguration::toMap()); map.insert(QLatin1String(BUILD_DIRECTORY_KEY), m_buildDirectory); + map.insert(QLatin1String(USE_NINJA_KEY), m_useNinja); return map; } @@ -83,6 +85,7 @@ bool CMakeBuildConfiguration::fromMap(const QVariantMap &map) return false; m_buildDirectory = map.value(QLatin1String(BUILD_DIRECTORY_KEY)).toString(); + m_useNinja = map.value(QLatin1String(USE_NINJA_KEY), false).toBool(); return true; } diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp index 559788e4d6b..72438d114bb 100644 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ b/src/plugins/cpptools/cppcompletion_test.cpp @@ -228,6 +228,78 @@ void CppToolsPlugin::test_completion_template_1() QVERIFY(!completions.contains("func")); } +void CppToolsPlugin::test_completion_template_2() +{ + TestData data; + data.srcText = "\n" + "template \n" + "struct List\n" + "{\n" + " T &at(int);\n" + "};\n" + "\n" + "struct Tupple { int a; int b; };\n" + "\n" + "void func() {\n" + " List l;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("l.at(0)."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 3); + QVERIFY(completions.contains("Tupple")); + QVERIFY(completions.contains("a")); + QVERIFY(completions.contains("b")); +} + +void CppToolsPlugin::test_completion_template_3() +{ + TestData data; + data.srcText = "\n" + "template \n" + "struct List\n" + "{\n" + " T t;\n" + "};\n" + "\n" + "struct Tupple { int a; int b; };\n" + "\n" + "void func() {\n" + " List l;\n" + " @\n" + " // padding so we get the scope right\n" + "}"; + + setup(&data); + + Utils::ChangeSet change; + QString txt = QLatin1String("l.t."); + change.insert(data.pos, txt); + QTextCursor cursor(data.doc); + change.apply(&cursor); + data.pos += txt.length(); + + QStringList completions = getCompletions(data); + + QCOMPARE(completions.size(), 3); + QVERIFY(completions.contains("Tupple")); + QVERIFY(completions.contains("a")); + QVERIFY(completions.contains("b")); + QVERIFY(completions.contains("a")); + QVERIFY(completions.contains("b")); +} + void CppToolsPlugin::test_completion() { QFETCH(QByteArray, code); diff --git a/src/plugins/cpptools/cppcompletionassist.cpp b/src/plugins/cpptools/cppcompletionassist.cpp index a316429baee..8dd911aac85 100644 --- a/src/plugins/cpptools/cppcompletionassist.cpp +++ b/src/plugins/cpptools/cppcompletionassist.cpp @@ -102,7 +102,9 @@ public: , m_completionOperator(T_EOF_SYMBOL) , m_replaceDotForArrow(false) , m_typeOfExpression(new TypeOfExpression) - {} + { + m_typeOfExpression->setExpandTemplates(true); + } virtual bool isSortable(const QString &prefix) const; virtual IAssistProposalItem *proposalItem(int index) const; @@ -831,7 +833,8 @@ int CppCompletionAssistProcessor::startOfOperator(int pos, else if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT) || (tk.isLiteral() && (*kind != T_STRING_LITERAL && *kind != T_ANGLE_STRING_LITERAL - && *kind != T_SLASH))) { + && *kind != T_SLASH + && *kind != T_DOT))) { *kind = T_EOF_SYMBOL; start = pos; } @@ -858,7 +861,8 @@ int CppCompletionAssistProcessor::startOfOperator(int pos, } } // Check for include preprocessor directive - else if (*kind == T_STRING_LITERAL || *kind == T_ANGLE_STRING_LITERAL || *kind == T_SLASH) { + else if (*kind == T_STRING_LITERAL || *kind == T_ANGLE_STRING_LITERAL|| *kind == T_SLASH + || (*kind == T_DOT && (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)))) { bool include = false; if (tokens.size() >= 3) { if (tokens.at(0).is(T_POUND) && tokens.at(1).is(T_IDENTIFIER) && (tokens.at(2).is(T_STRING_LITERAL) || @@ -877,6 +881,14 @@ int CppCompletionAssistProcessor::startOfOperator(int pos, if (!include) { *kind = T_EOF_SYMBOL; start = pos; + } else { + if (*kind == T_DOT) { + start = findStartOfName(start); + const QChar ch4 = start > -1 ? m_interface->characterAt(start - 1) : QChar(); + const QChar ch5 = start > 0 ? m_interface->characterAt(start - 2) : QChar(); + const QChar ch6 = start > 1 ? m_interface->characterAt(start - 3) : QChar(); + start = start - CppCompletionAssistProvider::activationSequenceChar(ch4, ch5, ch6, kind, wantFunctionCall); + } } } } @@ -943,7 +955,7 @@ int CppCompletionAssistProcessor::startCompletionHelper() QTextCursor c(m_interface->textDocument()); c.setPosition(endOfExpression); if (completeInclude(c)) - m_startPosition = startOfName; + m_startPosition = endOfExpression + 1; return m_startPosition; } diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index 80b05ba63f1..6bc1ddef44a 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -93,6 +93,8 @@ private slots: void test_completion_forward_declarations_present(); void test_completion_basic_1(); void test_completion_template_1(); + void test_completion_template_2(); + void test_completion_template_3(); void test_completion_template_as_base(); void test_completion_template_as_base_data(); void test_completion_use_global_identifier_as_base_class(); diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp index cd9506de5ae..1b93b187f8b 100644 --- a/src/plugins/debugger/loadcoredialog.cpp +++ b/src/plugins/debugger/loadcoredialog.cpp @@ -191,9 +191,8 @@ void SelectRemoteFileDialog::handleRemoteError(const QString &errorMessage) void SelectRemoteFileDialog::selectFile() { - const QModelIndexList indexes = - m_fileSystemView->selectionModel()->selectedIndexes(); - if (indexes.empty()) + QModelIndex idx = m_model.mapToSource(m_fileSystemView->currentIndex()); + if (!idx.isValid()) return; m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); @@ -208,7 +207,6 @@ void SelectRemoteFileDialog::selectFile() m_localFile = localFile.fileName(); } - QModelIndex idx = indexes.at(0); idx = idx.sibling(idx.row(), 1); m_remoteFile = m_fileSystemModel.data(idx, SftpFileSystemModel::PathRole).toString(); m_sftpJobId = m_fileSystemModel.downloadFile(idx, m_localFile); @@ -297,9 +295,11 @@ AttachCoreDialog::AttachCoreDialog(QWidget *parent) connect(d->selectRemoteCoreButton, SIGNAL(clicked()), SLOT(selectRemoteCoreFile())); connect(d->remoteCoreFileName, SIGNAL(textChanged(QString)), SLOT(changed())); + connect(d->localCoreFileName, SIGNAL(changed(QString)), SLOT(changed())); connect(d->kitChooser, SIGNAL(activated(int)), SLOT(changed())); connect(d->buttonBox, SIGNAL(rejected()), SLOT(reject())); connect(d->buttonBox, SIGNAL(accepted()), SLOT(accept())); + changed(); } AttachCoreDialog::~AttachCoreDialog() @@ -321,19 +321,22 @@ bool AttachCoreDialog::isLocal() const void AttachCoreDialog::changed() { - bool isValid = d->kitChooser->currentIndex() >= 0 - && !localCoreFile().isEmpty(); - d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid); + bool isValid = d->kitChooser->currentIndex() >= 0 && d->localExecFileName->isValid(); if (isLocal()) { d->localCoreFileName->setVisible(true); d->remoteCoreFileName->setVisible(false); d->selectRemoteCoreButton->setVisible(false); + if (isValid) + isValid = d->localCoreFileName->isValid(); } else { d->remoteCoreFileName->setVisible(true); d->selectRemoteCoreButton->setVisible(true); d->localCoreFileName->setVisible(false); + if (isValid) + isValid = !remoteCoreFile().isEmpty(); } + d->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(isValid); } void AttachCoreDialog::selectRemoteCoreFile() diff --git a/src/plugins/debugger/localsandexpressionswindow.cpp b/src/plugins/debugger/localsandexpressionswindow.cpp index 5e1d8630aba..0211c3c6cad 100644 --- a/src/plugins/debugger/localsandexpressionswindow.cpp +++ b/src/plugins/debugger/localsandexpressionswindow.cpp @@ -41,7 +41,8 @@ namespace Internal { LocalsAndExpressionsWindow::LocalsAndExpressionsWindow( QWidget *locals, QWidget *inspector, QWidget *returnWidget, QWidget *watchers, QWidget *parent) - : QWidget(parent) + : QWidget(parent), + m_showLocals(false) { QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); @@ -62,11 +63,23 @@ LocalsAndExpressionsWindow::LocalsAndExpressionsWindow( m_splitter->setStretchFactor(0, 3); m_splitter->setStretchFactor(2, 1); m_splitter->setStretchFactor(3, 1); + + // Timer is to prevent flicker when switching between Inpector and Locals + // when debugger engine changes states. + m_timer.setSingleShot(true); + m_timer.setInterval(500); // TODO: remove the magic number! + connect(&m_timer, SIGNAL(timeout()), SLOT(showLocals())); } void LocalsAndExpressionsWindow::setShowLocals(bool showLocals) { - m_localsAndInspector->setCurrentIndex(showLocals ? 0 : 1); + m_showLocals = showLocals; + m_timer.start(); +} + +void LocalsAndExpressionsWindow::showLocals() +{ + m_localsAndInspector->setCurrentIndex(m_showLocals ? 0 : 1); } } // namespace Internal diff --git a/src/plugins/debugger/localsandexpressionswindow.h b/src/plugins/debugger/localsandexpressionswindow.h index 93bff1311ac..bf59a2618fe 100644 --- a/src/plugins/debugger/localsandexpressionswindow.h +++ b/src/plugins/debugger/localsandexpressionswindow.h @@ -31,6 +31,7 @@ #define LOCALSANDEXPRESSIONSWINDOW_H #include +#include QT_BEGIN_NAMESPACE class QSplitter; @@ -50,9 +51,14 @@ public: void setShowLocals(bool showLocals); +private slots: + void showLocals(); + private: QSplitter *m_splitter; QStackedWidget *m_localsAndInspector; + QTimer m_timer; + bool m_showLocals; }; } // namespace Internal diff --git a/src/plugins/debugger/qml/baseqmldebuggerclient.h b/src/plugins/debugger/qml/baseqmldebuggerclient.h index 1d74acb6e9b..a93792cd224 100644 --- a/src/plugins/debugger/qml/baseqmldebuggerclient.h +++ b/src/plugins/debugger/qml/baseqmldebuggerclient.h @@ -91,6 +91,7 @@ public: signals: void newStatus(QmlDebug::ClientStatus status); + void stackFrameCompleted(); protected: virtual void statusChanged(QmlDebug::ClientStatus status); diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index fa841c170fd..d1c22ef1c72 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -1014,9 +1014,8 @@ void QmlEngine::updateWatchData(const WatchData &data, synchronizeWatchers(); } - if (!data.isSomethingNeeded()) - watchHandler()->insertIncompleteData(data); + watchHandler()->insertData(data); } void QmlEngine::synchronizeWatchers() diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp index 1da5b51d966..a1098b9fd6c 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.cpp +++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp @@ -115,15 +115,6 @@ void QmlInspectorAgent::updateWatchData(const WatchData &data) if (data.id && !m_fetchDataIds.contains(data.id)) { // objects - using namespace QmlDebug::Constants; - if (m_engineClient->objectName() == QLatin1String(QDECLARATIVE_ENGINE)) { - int parentId = parentIdForIname(data.iname); - if (parentId != -1) { - QList childIds = m_debugIdChildIds.value(parentId); - childIds << data.id; - m_debugIdChildIds.insert(parentId, childIds); - } - } m_fetchDataIds << data.id; fetchObject(data.id); } @@ -461,7 +452,6 @@ void QmlInspectorAgent::onResult(quint32 queryId, const QVariant &value, } if (m_objectTreeQueryIds.contains(queryId)) { - m_objectTreeQueryIds.removeOne(queryId); if (value.type() == QVariant::List) { QVariantList objList = value.toList(); foreach (QVariant var, objList) { @@ -472,6 +462,7 @@ void QmlInspectorAgent::onResult(quint32 queryId, const QVariant &value, } else { insertObjectInTree(qvariant_cast(value)); } + m_objectTreeQueryIds.removeOne(queryId); } else if (queryId == m_engineQueryId) { m_engineQueryId = 0; QList engines = qvariant_cast >(value); @@ -492,7 +483,7 @@ void QmlInspectorAgent::onResult(quint32 queryId, const QVariant &value, } -void QmlInspectorAgent::newObject(int engineId, int objectId, int /*parentId*/) +void QmlInspectorAgent::newObject(int engineId, int /*objectId*/, int /*parentId*/) { if (debug) qDebug() << __FUNCTION__ << "()"; @@ -502,11 +493,8 @@ void QmlInspectorAgent::newObject(int engineId, int objectId, int /*parentId*/) if (m_engine.debugId() != engineId) return; - m_newObjectsCreated = true; - if (m_engineClient->objectName() != QLatin1String(QDECLARATIVE_ENGINE)) - fetchObject(objectId); - else - m_delayQueryTimer.start(); + // TODO: FIX THIS for qt 5.x (Needs update in the qt side) + m_delayQueryTimer.start(); } void QmlInspectorAgent::onValueChanged(int debugId, const QByteArray &propertyName, @@ -634,75 +622,29 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object) if (!object.isValid()) return; - m_objectStack.push(object); - - if (m_objectTreeQueryIds.count()) { - return; - } - QElapsedTimer timeElapsed; // sync tree with watchhandler QList watchData; - ObjectReference last; - QStack stack; + int objectDebugId = object.debugId(); - // qt <= 4.8.3 - if (m_newObjectsCreated && m_engineClient->objectName() == QLatin1String(QDECLARATIVE_ENGINE)) { - // We need to reverse the stack as the root objects - // are pushed to the bottom since they are fetched first. - // The child objects need to placed in the correct position and therefore - // the m_debugIdChildIds needs to be populated first. - while (!m_objectStack.isEmpty()) - stack.push(m_objectStack.pop()); - } else { - stack = m_objectStack; - } + // When root items are inserted in the object tree, m_objectTreeQueryIds = 0 + if (!m_debugIdToIname.contains(objectDebugId) && m_objectTreeQueryIds.count()) + return; - while (!stack.isEmpty()) { - last = stack.pop(); - int parentId = last.parentId(); - QByteArray parentIname; + int parentId = parentIdForIname(m_debugIdToIname.value(objectDebugId)); - // qt <= 4.8.3 - if (m_engineClient->objectName() == QLatin1String(QDECLARATIVE_ENGINE)) { - QHashIterator > i(m_debugIdChildIds); - while (i.hasNext()) { - i.next(); - if (i.value().contains(last.debugId())) { - parentId = i.key(); - break; - } - } - } - if (m_debugIdToIname.contains(parentId)) - parentIname = m_debugIdToIname.value(parentId); - if (!m_newObjectsCreated && parentId != -1 && parentIname.isEmpty()) { - fetchObject(parentId); - return; - } - // qt > 4.8.3 - if (m_engineClient->objectName() != QLatin1String(QDECLARATIVE_ENGINE) - && m_newObjectsCreated && parentIname.isEmpty()) { - if (watchData.count()) - break; - return; - } - - if (debug) - timeElapsed.start(); - watchData.append(buildWatchData(last, parentIname, true)); - if (debug) - qDebug() << __FUNCTION__ << "Time: Build Watch Data took " - << timeElapsed.elapsed() << " ms"; - if (debug) - timeElapsed.start(); - buildDebugIdHashRecursive(last); - if (debug) - qDebug() << __FUNCTION__ << "Time: Build Debug Id Hash took " - << timeElapsed.elapsed() << " ms"; - } - m_newObjectsCreated = false; - m_objectStack.clear(); + if (debug) + timeElapsed.start(); + watchData.append(buildWatchData(object, m_debugIdToIname.value(parentId), true)); + if (debug) + qDebug() << __FUNCTION__ << "Time: Build Watch Data took " + << timeElapsed.elapsed() << " ms"; + if (debug) + timeElapsed.start(); + buildDebugIdHashRecursive(object); + if (debug) + qDebug() << __FUNCTION__ << "Time: Build Debug Id Hash took " + << timeElapsed.elapsed() << " ms"; WatchHandler *watchHandler = m_debuggerEngine->watchHandler(); if (debug) @@ -712,9 +654,9 @@ void QmlInspectorAgent::insertObjectInTree(const ObjectReference &object) qDebug() << __FUNCTION__ << "Time: Insertion took " << timeElapsed.elapsed() << " ms"; emit objectTreeUpdated(); - emit objectFetched(last); + emit objectFetched(object); - if (m_objectToSelect == last.debugId() || m_debugIdToIname.keys().contains(m_objectToSelect)) { + if (m_debugIdToIname.contains(m_objectToSelect)) { // select item in view QByteArray iname = m_debugIdToIname.value(m_objectToSelect); if (debug) @@ -753,18 +695,6 @@ void QmlInspectorAgent::buildDebugIdHashRecursive(const ObjectReference &ref) m_debugIdHash[file][location].append(ref.debugId()); m_debugIdLocations.insert(ref.debugId(), FileReference(filePath, lineNum, colNum)); - // qt <= 4.8.3 - if (m_newObjectsCreated - && m_engineClient->objectName() == QLatin1String(QDECLARATIVE_ENGINE)) { - QList childIds = m_debugIdChildIds.value(ref.debugId()); - foreach (const ObjectReference &c, ref.children()) { - childIds << c.debugId(); - } - // For qt <= 4.8.3, we do not get the parentId. Hence, store the child ids - // to look up correct insertion places later - m_debugIdChildIds.insert(ref.debugId(), childIds); - } - foreach (const ObjectReference &it, ref.children()) buildDebugIdHashRecursive(it); } @@ -814,6 +744,13 @@ QList QmlInspectorAgent::buildWatchData(const ObjectReference &obj, list.append(objWatch); addObjectWatch(objWatch.id); + if (m_debugIdToIname.contains(objDebugId)) { + // The data needs to be removed since we now know the parent and + // hence we can insert the data in the correct position + const QByteArray oldIname = m_debugIdToIname.value(objDebugId); + if (oldIname != objIname) + m_debuggerEngine->watchHandler()->removeData(oldIname); + } m_debugIdToIname.insert(objDebugId, objIname); } @@ -885,16 +822,13 @@ bool QmlInspectorAgent::isConnected() const void QmlInspectorAgent::clearObjectTree() { - // clear view - m_debuggerEngine->watchHandler()->cleanup(); - + m_debuggerEngine->watchHandler()->removeAllData(true); m_objectTreeQueryIds.clear(); m_fetchDataIds.clear(); int old_count = m_debugIdHash.count(); m_debugIdHash.clear(); m_debugIdHash.reserve(old_count + 1); m_debugIdToIname.clear(); - m_debugIdChildIds.clear(); m_objectStack.clear(); // reset only for qt > 4.8.3. if (m_engineClient->objectName() != QLatin1String(QDECLARATIVE_ENGINE)) diff --git a/src/plugins/debugger/qml/qmlinspectoragent.h b/src/plugins/debugger/qml/qmlinspectoragent.h index 0f8cc51472d..d83f79b5b3e 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.h +++ b/src/plugins/debugger/qml/qmlinspectoragent.h @@ -137,7 +137,6 @@ private: QStack m_objectStack; QmlDebug::EngineReference m_engine; QHash m_debugIdToIname; - QHash > m_debugIdChildIds; // This is for 4.x QHash m_debugIdLocations; DebugIdHash m_debugIdHash; diff --git a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp index dc4690ada02..588ad937fe4 100644 --- a/src/plugins/debugger/qml/qmlv8debuggerclient.cpp +++ b/src/plugins/debugger/qml/qmlv8debuggerclient.cpp @@ -1152,6 +1152,7 @@ void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId void QmlV8DebuggerClient::setEngine(QmlEngine *engine) { d->engine = engine; + connect(this, SIGNAL(stackFrameCompleted()), engine, SIGNAL(stackFrameCompleted())); } void QmlV8DebuggerClient::getSourceFiles() @@ -1648,8 +1649,17 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const QVariantMap currentFrame = bodyVal.toMap(); StackHandler *stackHandler = d->engine->stackHandler(); - + WatchHandler * watchHandler = d->engine->watchHandler(); d->clearCache(); + + const int frameIndex = stackHandler->currentIndex(); + watchHandler->removeAllData(); + if (frameIndex < 0) + return; + const StackFrame frame = stackHandler->currentFrame(); + if (!frame.isUsable()) + return; + //Set "this" variable { WatchData data; @@ -1667,7 +1677,7 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const data.setHasChildren(true); data.id = 0; } - d->engine->watchHandler()->insertData(data); + watchHandler->insertData(data); } const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList(); @@ -1681,6 +1691,7 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const d->scope(scopeIndex); } d->engine->gotoLocation(stackHandler->currentFrame()); + emit stackFrameCompleted(); } void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &refsVal) diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp index 12d948502cf..4a595475fa9 100644 --- a/src/plugins/debugger/qml/qscriptdebuggerclient.cpp +++ b/src/plugins/debugger/qml/qscriptdebuggerclient.cpp @@ -401,6 +401,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) stream >> command; WatchHandler *watchHandler = d->engine->watchHandler(); + StackHandler *stackHandler = d->engine->stackHandler(); if (command == "STOPPED") { d->engine->inferiorSpontaneousStop(); @@ -426,35 +427,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) ideStackFrames << frame; } - if (ideStackFrames.size() && ideStackFrames.back().function == QLatin1String("")) - ideStackFrames.takeLast(); - - d->engine->stackHandler()->setFrames(ideStackFrames); - - bool needPing = false; - - foreach (WatchData data, watches) { - data.iname = watchHandler->watcherName(data.exp); - watchHandler->insertIncompleteData(data); - - if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { - needPing = true; - expandObject(data.iname,data.id); - } - } - - foreach (WatchData data, locals) { - data.iname = "local." + data.exp; - watchHandler->insertIncompleteData(data); - - if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { - needPing = true; - expandObject(data.iname,data.id); - } - } - - if (needPing) - sendPing(); + stackHandler->setFrames(ideStackFrames); bool becauseOfException; stream >> becauseOfException; @@ -502,6 +475,8 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) if (!ideStackFrames.isEmpty()) d->engine->gotoLocation(ideStackFrames.value(0)); + insertLocalsAndWatches(locals, watches, stackHandler->currentIndex()); + } else if (command == "RESULT") { WatchData data; QByteArray iname; @@ -511,12 +486,12 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) + QLatin1String(iname) + QLatin1Char(' ') + data.value); data.iname = iname; if (iname.startsWith("watch.")) { - watchHandler->insertIncompleteData(data); + watchHandler->insertData(data); } else if (iname == "console") { d->engine->showMessage(data.value, ConsoleOutput); } else if (iname.startsWith("local.")) { data.name = data.name.left(data.name.indexOf(QLatin1Char(' '))); - watchHandler->insertIncompleteData(data); + watchHandler->insertData(data); } else { qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value; } @@ -531,7 +506,7 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) foreach (WatchData data, result) { data.iname = iname + '.' + data.exp; - watchHandler->insertIncompleteData(data); + watchHandler->insertData(data); if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { needPing = true; @@ -552,27 +527,8 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) d->logReceiveMessage(QString::fromLatin1("%1 %2 (%3 x locals) (%4 x watchdata)").arg( QLatin1String(command), QString::number(frameId), QString::number(locals.size()), QString::number(watches.size()))); - bool needPing = false; - foreach (WatchData data, watches) { - data.iname = watchHandler->watcherName(data.exp); - watchHandler->insertIncompleteData(data); - if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { - needPing = true; - expandObject(data.iname, data.id); - } - } - - foreach (WatchData data, locals) { - data.iname = "local." + data.exp; - watchHandler->insertIncompleteData(data); - if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { - needPing = true; - expandObject(data.iname, data.id); - } - } - if (needPing) - sendPing(); + insertLocalsAndWatches(locals, watches, frameId); } else if (command == "PONG") { int ping; @@ -585,9 +541,50 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data) } +void QScriptDebuggerClient::insertLocalsAndWatches(QList &locals, + QList &watches, + int stackFrameIndex) +{ + WatchHandler *watchHandler = d->engine->watchHandler(); + watchHandler->removeAllData(); + if (stackFrameIndex < 0) + return; + const StackFrame frame = d->engine->stackHandler()->frameAt(stackFrameIndex); + if (!frame.isUsable()) + return; + + bool needPing = false; + foreach (WatchData data, watches) { + data.iname = watchHandler->watcherName(data.exp); + watchHandler->insertData(data); + + if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { + needPing = true; + expandObject(data.iname, data.id); + } + } + + foreach (WatchData data, locals) { + if (data.name == QLatin1String("")) + data.name = tr("No Local Variables"); + data.iname = "local." + data.exp; + watchHandler->insertData(data); + + if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) { + needPing = true; + expandObject(data.iname, data.id); + } + } + + if (needPing) + sendPing(); + emit stackFrameCompleted(); +} + void QScriptDebuggerClient::setEngine(QmlEngine *engine) { d->engine = engine; + connect(this, SIGNAL(stackFrameCompleted()), engine, SIGNAL(stackFrameCompleted())); } void QScriptDebuggerClientPrivate::logSendMessage(const QString &msg) const diff --git a/src/plugins/debugger/qml/qscriptdebuggerclient.h b/src/plugins/debugger/qml/qscriptdebuggerclient.h index 9af899bbeba..48843cd2c43 100644 --- a/src/plugins/debugger/qml/qscriptdebuggerclient.h +++ b/src/plugins/debugger/qml/qscriptdebuggerclient.h @@ -86,6 +86,8 @@ protected: private: void sendPing(); + void insertLocalsAndWatches(QList &locals, QList &watches, + int stackFrameIndex); private: QScriptDebuggerClientPrivate *d; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 8b9bee75e49..7071ca88a27 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -193,7 +193,7 @@ private: bool ancestorChanged(const QSet &parentINames, WatchItem *item) const; void insertBulkData(const QList &data); QString displayForAutoTest(const QByteArray &iname) const; - void reinitialize(); + void reinitialize(bool includeInspectData = false); void destroyItem(WatchItem *item); // With model notification. void destroyChildren(WatchItem *item); // With model notification. void destroyHelper(const WatchItems &items); // Without model notification. @@ -315,7 +315,7 @@ WatchItem *WatchModel::createItem(const QByteArray &iname, const QString &name, return item; } -void WatchModel::reinitialize() +void WatchModel::reinitialize(bool includeInspectData) { CHECK(checkTree()); //MODEL_DEBUG("REMOVING " << n << " CHILDREN OF " << m_root->iname); @@ -324,8 +324,10 @@ void WatchModel::reinitialize() destroyChildren(m_watchRoot); destroyChildren(m_returnRoot); destroyChildren(m_tooltipRoot); - destroyChildren(m_inspectorRoot); - QTC_CHECK(m_cache.size() == 6); + if (includeInspectData) { + destroyChildren(m_inspectorRoot); + QTC_CHECK(m_cache.size() == 6); + } CHECK(checkTree()); } @@ -434,7 +436,7 @@ void WatchModel::reinsertAllData() { QList list; reinsertAllDataHelper(m_root, &list); - reinitialize(); + reinitialize(true); insertBulkData(list); } @@ -1516,9 +1518,9 @@ void WatchHandler::insertData(const QList &list) updateWatchersWindow(); } -void WatchHandler::removeAllData() +void WatchHandler::removeAllData(bool includeInspectData) { - m_model->reinitialize(); + m_model->reinitialize(includeInspectData); updateWatchersWindow(); } diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index bb7b635b52b..19e8a090e55 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -130,7 +130,7 @@ public: void insertIncompleteData(const WatchData &data); void removeData(const QByteArray &iname); void removeChildren(const QByteArray &iname); - void removeAllData(); + void removeAllData(bool includeInspectData = false); void resetValueCache(); private: diff --git a/src/plugins/locator/locatorwidget.cpp b/src/plugins/locator/locatorwidget.cpp index 8d59455f8d4..343b1e7cd8d 100644 --- a/src/plugins/locator/locatorwidget.cpp +++ b/src/plugins/locator/locatorwidget.cpp @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -194,7 +195,7 @@ QVariant LocatorModel::data(const QModelIndex &index, int role) const } return entry.displayIcon; } else if (role == Qt::ForegroundRole && index.column() == 1) { - return Qt::darkGray; + return QColor(Qt::darkGray); } else if (role == Qt::UserRole) { return qVariantFromValue(mEntries.at(index.row())); } diff --git a/src/plugins/projectexplorer/customwizard/customwizardpreprocessor.cpp b/src/plugins/projectexplorer/customwizard/customwizardpreprocessor.cpp index a84fe06eb92..23ffafcda23 100644 --- a/src/plugins/projectexplorer/customwizard/customwizardpreprocessor.cpp +++ b/src/plugins/projectexplorer/customwizard/customwizardpreprocessor.cpp @@ -28,6 +28,10 @@ ****************************************************************************/ #include "customwizardpreprocessor.h" +#ifdef WITH_TESTS +# include "projectexplorer.h" +# include +#endif #include @@ -192,7 +196,7 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM switch (preprocessorLine(lines.at(l), &expression)) { case IfSection: // '@If': Push new section - if (top.parentEnabled) { + if (top.condition) { if (!evaluateBooleanJavaScriptExpression(m_scriptEngine, expression, &expressionValue, errorMessage)) { *errorMessage = QString::fromLatin1("Error in @if at %1: %2"). arg(l + 1).arg(*errorMessage); @@ -282,4 +286,70 @@ bool customWizardPreprocess(const QString &in, QString *out, QString *errorMessa } } // namespace Internal + +#ifdef WITH_TESTS // Run qtcreator -test ProjectExplorer + +void ProjectExplorerPlugin::testCustomWizardPreprocessor_data() +{ + QTest::addColumn("input"); + QTest::addColumn("expectedOutput"); + QTest::addColumn("expectedSuccess"); + QTest::addColumn("expectedErrorMessage"); + QTest::newRow("if") + << QString::fromLatin1("@if 1\nline 1\n@elsif 0\nline 2\n@else\nline 3\n@endif\n") + << QString::fromLatin1("line 1") + << true << QString(); + QTest::newRow("elsif") + << QString::fromLatin1("@if 0\nline 1\n@elsif 1\nline 2\n@else\nline 3\n@endif\n") + << QString::fromLatin1("line 2") + << true << QString(); + QTest::newRow("else") + << QString::fromLatin1("@if 0\nline 1\n@elsif 0\nline 2\n@else\nline 3\n@endif\n") + << QString::fromLatin1("line 3") + << true << QString(); + QTest::newRow("nested-if") + << QString::fromLatin1("@if 1\n" + " @if 1\nline 1\n@elsif 0\nline 2\n@else\nline 3\n@endif\n" + "@else\n" + " @if 1\nline 4\n@elsif 0\nline 5\n@else\nline 6\n@endif\n" + "@endif\n") + << QString::fromLatin1("line 1") + << true << QString(); + QTest::newRow("nested-else") + << QString::fromLatin1("@if 0\n" + " @if 1\nline 1\n@elsif 0\nline 2\n@else\nline 3\n@endif\n" + "@else\n" + " @if 1\nline 4\n@elsif 0\nline 5\n@else\nline 6\n@endif\n" + "@endif\n") + << QString::fromLatin1("line 4") + << true << QString(); + QTest::newRow("twice-nested-if") + << QString::fromLatin1("@if 0\n" + " @if 1\n" + " @if 1\nline 1\n@else\nline 2\n@endif\n" + " @endif\n" + "@else\n" + " @if 1\n" + " @if 1\nline 3\n@else\nline 4\n@endif\n" + " @endif\n" + "@endif\n") + << QString::fromLatin1("line 3") + << true << QString(); +} + +void ProjectExplorerPlugin::testCustomWizardPreprocessor() +{ + QFETCH(QString, input); + QFETCH(QString, expectedOutput); + QFETCH(bool, expectedSuccess); + QFETCH(QString, expectedErrorMessage); + + QString errorMessage; + QString output; + const bool success = Internal::customWizardPreprocess(input, &output, &errorMessage); + QCOMPARE(success, expectedSuccess); + QCOMPARE(output.trimmed(), expectedOutput.trimmed()); + QCOMPARE(errorMessage, expectedErrorMessage); +} +#endif // WITH_TESTS } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp index d72e1d68a57..ec12df52c67 100644 --- a/src/plugins/projectexplorer/kitmanager.cpp +++ b/src/plugins/projectexplorer/kitmanager.cpp @@ -150,22 +150,24 @@ void KitManager::restoreKits() { QTC_ASSERT(!d->m_writer, return); QList kitsToRegister; + QList kitsToValidate; QList kitsToCheck; // read all kits from SDK QFileInfo systemSettingsFile(Core::ICore::settings(QSettings::SystemScope)->fileName()); - QFileInfo kitFile(systemSettingsFile.absolutePath(), QLatin1String(KIT_FILENAME)); + QFileInfo kitFile(systemSettingsFile.absolutePath() + QLatin1String(KIT_FILENAME)); if (kitFile.exists()) { KitList system = restoreKits(Utils::FileName(kitFile)); // make sure we mark these as autodetected! foreach (Kit *k, system.kits) k->setAutoDetected(true); - // SDK kits are always considered to be up-to-date, so no need to recheck them. - kitsToRegister = system.kits; + // SDK kits are always considered to be up for validation since they might have been + // extended with additional information by creator in the meantime: + kitsToValidate = system.kits; } - // read all kit chains from user file + // read all kits from user file KitList userKits = restoreKits(settingsFileName()); foreach (Kit *k, userKits.kits) { if (k->isAutoDetected()) @@ -174,20 +176,16 @@ void KitManager::restoreKits() kitsToRegister.append(k); } - // Then auto create kits: - QList detectedKits; - - // Find/update autodetected kits: Kit *toStore = 0; - foreach (Kit *currentDetected, detectedKits) { - toStore = currentDetected; + foreach (Kit *current, kitsToValidate) { + toStore = current; - // Check whether we had this kit stored and prefer the old one with the old id: + // Check whether we had this kit stored and prefer the stored one: for (int i = 0; i < kitsToCheck.count(); ++i) { - if (*(kitsToCheck.at(i)) == *currentDetected) { + if (kitsToCheck.at(i)->id() == current->id()) { toStore = kitsToCheck.at(i); kitsToCheck.removeAt(i); - delete currentDetected; + delete current; break; } } diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index b7b9b4d43a6..03e46fb9b2d 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -262,6 +262,9 @@ private slots: void testFlavorForOs(); void testDeviceManager(); + + void testCustomWizardPreprocessor_data(); + void testCustomWizardPreprocessor(); #endif private: diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.ui b/src/plugins/projectexplorer/projectexplorersettingspage.ui index ce21dbda9f7..6f13f17fd77 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.ui +++ b/src/plugins/projectexplorer/projectexplorersettingspage.ui @@ -174,7 +174,7 @@ - <i>jom</i> is a drop-in replacement for <i>nmake</i> which distributes the compilation process to multiple CPU cores. The latest binary is available at <a href="ftp://ftp.qt.nokia.com/jom/">ftp://ftp.qt.nokia.com/jom/</a>. Disable it if you experience problems with your builds. + <i>jom</i> is a drop-in replacement for <i>nmake</i> which distributes the compilation process to multiple CPU cores. The latest binary is available at <a href="http://releases.qt-project.org/jom/">http://releases.qt-project.org/jom/</a>. Disable it if you experience problems with your builds. true diff --git a/src/plugins/projectexplorer/taskmodel.cpp b/src/plugins/projectexplorer/taskmodel.cpp index 89102ea2599..b4b3a8be788 100644 --- a/src/plugins/projectexplorer/taskmodel.cpp +++ b/src/plugins/projectexplorer/taskmodel.cpp @@ -345,8 +345,8 @@ TaskFilterModel::TaskFilterModel(TaskModel *sourceModel, QObject *parent) : QAbs Q_ASSERT(m_sourceModel); connect(m_sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(handleNewRows(QModelIndex,int,int))); - connect(m_sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), - this, SLOT(handleRemovedRows(QModelIndex,int,int))); + connect(m_sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), + this, SLOT(handleRowsAboutToBeRemoved(QModelIndex,int,int))); connect(m_sourceModel, SIGNAL(modelReset()), this, SLOT(handleReset())); connect(m_sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), @@ -434,7 +434,7 @@ void TaskFilterModel::handleNewRows(const QModelIndex &index, int first, int las endInsertRows(); } -void TaskFilterModel::handleRemovedRows(const QModelIndex &index, int first, int last) +void TaskFilterModel::handleRowsAboutToBeRemoved(const QModelIndex &index, int first, int last) { if (index.isValid()) return; diff --git a/src/plugins/projectexplorer/taskmodel.h b/src/plugins/projectexplorer/taskmodel.h index bc81915c02d..81953c7f6a5 100644 --- a/src/plugins/projectexplorer/taskmodel.h +++ b/src/plugins/projectexplorer/taskmodel.h @@ -164,7 +164,7 @@ public: QModelIndex mapFromSource(const QModelIndex &idx) const; private slots: void handleNewRows(const QModelIndex &index, int first, int last); - void handleRemovedRows(const QModelIndex &index, int first, int last); + void handleRowsAboutToBeRemoved(const QModelIndex &index, int first, int last); void handleDataChanged(QModelIndex,QModelIndex bottom); void handleReset(); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index c3a890f4714..64cffe1f0cf 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -63,6 +63,20 @@ using namespace QmlJS::AST; namespace { +static inline QStringList supportedVersionsList() +{ + QStringList list; + list << QLatin1String("1.0") << QLatin1String("1.1"); + return list; +} + +static inline bool supportedQtQuickVersion(const QString &version) +{ + static QStringList supportedVersions = supportedVersionsList(); + + return supportedVersions.contains(version); +} + static inline QString stripQuotes(const QString &str) { if ((str.startsWith(QLatin1Char('"')) && str.endsWith(QLatin1Char('"'))) @@ -738,6 +752,14 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH errors.append(RewriterView::Error(diagnosticMessage, QUrl::fromLocalFile(doc->fileName()))); } + foreach (const QmlDesigner::Import &import, m_rewriterView->model()->imports()) { + if (import.isLibraryImport() && import.url() == QLatin1String("QtQuick") && !supportedQtQuickVersion(import.version())) { + const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::DiagnosticMessage::Error, AST::SourceLocation(0, 0, 0, 0), + QCoreApplication::translate("QmlDesigner::TextToModelMerger error message", "Unsupported QtQuick version")); + errors.append(RewriterView::Error(diagnosticMessage, QUrl::fromLocalFile(doc->fileName()))); + } + } + if (view()->checkSemanticErrors()) { Check check(doc, m_scopeChain->context()); check.disableMessage(StaticAnalysis::ErrUnknownComponent); diff --git a/src/plugins/qnx/blackberryapplicationrunner.cpp b/src/plugins/qnx/blackberryapplicationrunner.cpp index 806f98f4d92..4da11f95b7e 100644 --- a/src/plugins/qnx/blackberryapplicationrunner.cpp +++ b/src/plugins/qnx/blackberryapplicationrunner.cpp @@ -84,6 +84,7 @@ using namespace Qnx::Internal; BlackBerryApplicationRunner::BlackBerryApplicationRunner(bool debugMode, BlackBerryRunConfiguration *runConfiguration, QObject *parent) : QObject(parent) , m_debugMode(debugMode) + , m_slog2infoFound(true) , m_pid(-1) , m_appId(QString()) , m_running(false) @@ -91,6 +92,7 @@ BlackBerryApplicationRunner::BlackBerryApplicationRunner(bool debugMode, BlackBe , m_launchProcess(0) , m_stopProcess(0) , m_tailProcess(0) + , m_testSlog2Process(0) , m_runningStateTimer(new QTimer(this)) , m_runningStateProcess(0) { @@ -141,6 +143,17 @@ void BlackBerryApplicationRunner::start() m_running = true; } +void BlackBerryApplicationRunner::checkSlog2Info() +{ + // Not necessary to retest if slog2info exists. + if (!m_testSlog2Process) { + m_testSlog2Process = new QSsh::SshRemoteProcessRunner(this); + connect(m_testSlog2Process, SIGNAL(processClosed(int)), + this, SLOT(handleSlog2InfoFound())); + m_testSlog2Process->run("slog2info", m_sshParams); + } +} + void BlackBerryApplicationRunner::startFinished(int exitCode, QProcess::ExitStatus exitStatus) { if (exitCode == 0 && exitStatus == QProcess::NormalExit && m_pid > -1) { @@ -164,6 +177,12 @@ ProjectExplorer::RunControl::StopResult BlackBerryApplicationRunner::stop() m_stopping = true; + if (m_testSlog2Process && m_testSlog2Process->isProcessRunning()) { + m_testSlog2Process->cancel(); + delete m_testSlog2Process; + m_testSlog2Process = 0; + } + QStringList args; args << QLatin1String("-terminateApp"); args << QLatin1String("-device") << m_deviceHost; @@ -234,7 +253,11 @@ void BlackBerryApplicationRunner::killTailProcess() QSsh::SshRemoteProcessRunner *slayProcess = new QSsh::SshRemoteProcessRunner(this); connect(slayProcess, SIGNAL(processClosed(int)), this, SIGNAL(finished())); - slayProcess->run("slay tail", m_sshParams); + if (m_slog2infoFound) { + slayProcess->run("slay slog2info", m_sshParams); + } else { + slayProcess->run("slay tail", m_sshParams); + } // Not supported by OpenSSH server //m_tailProcess->sendSignalToProcess(Utils::SshRemoteProcess::KillSignal); @@ -264,21 +287,62 @@ void BlackBerryApplicationRunner::tailApplicationLog() this, SLOT(handleTailConnectionError())); } - const QString command = QLatin1String("tail -c +1 -f /accounts/1000/appdata/") + m_appId - + QLatin1String("/logs/log"); - + QString command; + if (m_slog2infoFound) { + command = QString::fromLatin1("slog2info -w"); + } else { + command = QLatin1String("tail -c +1 -f /accounts/1000/appdata/") + m_appId + + QLatin1String("/logs/log"); + } m_tailProcess->run(command.toLatin1(), m_sshParams); } +void BlackBerryApplicationRunner::handleSlog2InfoFound() +{ + QSsh::SshRemoteProcessRunner *process = qobject_cast(sender()); + QTC_ASSERT(process, return); + + m_slog2infoFound = (process->processExitCode() == 0); + + tailApplicationLog(); +} + void BlackBerryApplicationRunner::handleTailOutput() { QSsh::SshRemoteProcessRunner *process = qobject_cast(sender()); QTC_ASSERT(process, return); const QString message = QString::fromLatin1(process->readAllStandardOutput()); + if (m_slog2infoFound) { + const QStringList multiLine = message.split(QLatin1Char('\n')); + Q_FOREACH (const QString &line, multiLine) { + if ( line.contains(m_appId) ) { + QStringList validLineBeginnings; + validLineBeginnings << QLatin1String("qt-msg 0 ") + << QLatin1String("qt-msg* 0 ") + << QLatin1String(" 0 "); + Q_FOREACH (const QString &beginning, validLineBeginnings) { + if (showQtMessage(beginning, line)) + break; + } + } + } + return; + } emit output(message, Utils::StdOutFormat); } +bool BlackBerryApplicationRunner::showQtMessage(const QString& pattern, const QString& line) +{ + const int index = line.indexOf(pattern); + if (index != -1) { + const QString str = line.right(line.length()-index-pattern.length()) + QLatin1Char('\n'); + emit output(str, Utils::StdOutFormat); + return true; + } + return false; +} + void BlackBerryApplicationRunner::handleTailError() { QSsh::SshRemoteProcessRunner *process = qobject_cast(sender()); diff --git a/src/plugins/qnx/blackberryapplicationrunner.h b/src/plugins/qnx/blackberryapplicationrunner.h index c7da6e05f70..2993eb09f33 100644 --- a/src/plugins/qnx/blackberryapplicationrunner.h +++ b/src/plugins/qnx/blackberryapplicationrunner.h @@ -62,7 +62,7 @@ public: public slots: void start(); - void tailApplicationLog(); + void checkSlog2Info(); signals: void output(const QString &msg, Utils::OutputFormat format); @@ -72,6 +72,8 @@ signals: void startFailed(const QString &msg); private slots: + bool showQtMessage(const QString& pattern, const QString& line); + void tailApplicationLog(); void startFinished(int exitCode, QProcess::ExitStatus exitStatus); void stopFinished(int exitCode, QProcess::ExitStatus exitStatus); @@ -86,11 +88,14 @@ private slots: void determineRunningState(); void readRunningStateStandardOutput(); + void handleSlog2InfoFound(); + private: void reset(); void killTailProcess(); bool m_debugMode; + bool m_slog2infoFound; qint64 m_pid; QString m_appId; @@ -108,7 +113,7 @@ private: QProcess *m_launchProcess; QProcess *m_stopProcess; QSsh::SshRemoteProcessRunner *m_tailProcess; - + QSsh::SshRemoteProcessRunner *m_testSlog2Process; QTimer *m_runningStateTimer; QProcess *m_runningStateProcess; }; diff --git a/src/plugins/qnx/blackberrydebugsupport.cpp b/src/plugins/qnx/blackberrydebugsupport.cpp index fbc46e3cfa5..19823e54a2f 100644 --- a/src/plugins/qnx/blackberrydebugsupport.cpp +++ b/src/plugins/qnx/blackberrydebugsupport.cpp @@ -58,7 +58,7 @@ BlackBerryDebugSupport::BlackBerryDebugSupport(BlackBerryRunConfiguration *runCo runControl, SLOT(appendMessage(QString,Utils::OutputFormat))); connect(m_runner, SIGNAL(started()), this, SLOT(handleStarted())); - connect(m_runner, SIGNAL(started()), m_runner, SLOT(tailApplicationLog())); + connect(m_runner, SIGNAL(started()), m_runner, SLOT(checkSlog2Info())); connect(m_runner, SIGNAL(startFailed(QString)), this, SLOT(handleStartFailed(QString))); connect(m_runner, SIGNAL(output(QString,Utils::OutputFormat)), this, SLOT(handleApplicationOutput(QString,Utils::OutputFormat))); diff --git a/src/plugins/qnx/blackberryruncontrol.cpp b/src/plugins/qnx/blackberryruncontrol.cpp index 408f14cd3f4..89c8e8fcc15 100644 --- a/src/plugins/qnx/blackberryruncontrol.cpp +++ b/src/plugins/qnx/blackberryruncontrol.cpp @@ -93,5 +93,5 @@ void BlackBerryRunControl::launchTailProcess() { // Delay the launch of "tail" to ensure the blackberry-connect // connection has been properly established - QTimer::singleShot(500, m_runner, SLOT(tailApplicationLog())); + QTimer::singleShot(500, m_runner, SLOT(checkSlog2Info())); } diff --git a/src/plugins/qnx/qnxabstractqtversion.cpp b/src/plugins/qnx/qnxabstractqtversion.cpp index 6bece7b2483..7bfdb9b109d 100644 --- a/src/plugins/qnx/qnxabstractqtversion.cpp +++ b/src/plugins/qnx/qnxabstractqtversion.cpp @@ -50,6 +50,7 @@ QnxAbstractQtVersion::QnxAbstractQtVersion(QnxArchitecture arch, const Utils::Fi : QtSupport::BaseQtVersion(path, isAutoDetected, autoDetectionSource) , m_arch(arch) { + setDefaultSdkPath(); } QnxArchitecture QnxAbstractQtVersion::architecture() const @@ -168,3 +169,24 @@ QString QnxAbstractQtVersion::invalidReason() const return tr("No SDK path set"); return QtSupport::BaseQtVersion::invalidReason(); } + +void QnxAbstractQtVersion::setDefaultSdkPath() +{ + QHash info = versionInfo(); + QString qtHostPrefix; + if (info.contains(QLatin1String("QT_HOST_PREFIX"))) + qtHostPrefix = info.value(QLatin1String("QT_HOST_PREFIX")); + else + return; + + QString envFile; +#if defined Q_OS_WIN + envFile = qtHostPrefix + QLatin1String("/bbndk-env.bat"); +#elif defined Q_OS_UNIX + envFile = qtHostPrefix + QLatin1String("/bbndk-env.sh"); +#endif + + if (QFileInfo(envFile).exists()) + setSdkPath(qtHostPrefix); + +} diff --git a/src/plugins/qnx/qnxabstractqtversion.h b/src/plugins/qnx/qnxabstractqtversion.h index bd8b742f0a0..b72fd096419 100644 --- a/src/plugins/qnx/qnxabstractqtversion.h +++ b/src/plugins/qnx/qnxabstractqtversion.h @@ -70,6 +70,7 @@ public: QString invalidReason() const; virtual QString sdkDescription() const = 0; + void setDefaultSdkPath(); protected: QString sdkPath() const; diff --git a/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp b/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp index 4d9e8fb23c3..f57ffd7961f 100644 --- a/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp +++ b/src/plugins/qt4projectmanager/qt4projectconfigwidget.cpp @@ -114,6 +114,13 @@ void Qt4ProjectConfigWidget::updateDetails() .arg(QDir::toNativeSeparators(m_buildConfiguration->buildDirectory()))); } +void Qt4ProjectConfigWidget::setProblemLabel(const QString &text) +{ + m_ui->warningLabel->setVisible(!text.isEmpty()); + m_ui->problemLabel->setVisible(!text.isEmpty()); + m_ui->problemLabel->setText(text); +} + void Qt4ProjectConfigWidget::environmentChanged() { m_ui->shadowBuildDirEdit->setEnvironment(m_buildConfiguration->environment()); @@ -202,22 +209,20 @@ void Qt4ProjectConfigWidget::shadowBuildEdited() void Qt4ProjectConfigWidget::updateProblemLabel() { - bool targetMismatch = false; - bool incompatibleBuild = false; - bool allGood = false; ProjectExplorer::Kit *k = m_buildConfiguration->target()->kit(); const QString proFileName = m_buildConfiguration->target()->project()->document()->fileName(); + // Check for Qt version: QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k); if (!version) { - m_ui->problemLabel->setVisible(true); - m_ui->warningLabel->setVisible(true); - m_ui->problemLabel->setText(tr("This target cannot build this project since it does not define a " - "Qt version.")); + setProblemLabel(tr("This target cannot build this project since it does not define a Qt version.")); return; } + bool targetMismatch = false; + bool incompatibleBuild = false; + bool allGood = false; // we only show if we actually have a qmake and makestep if (m_buildConfiguration->qmakeStep() && m_buildConfiguration->makeStep()) { QString makefile = m_buildConfiguration->buildDirectory() + QLatin1Char('/'); @@ -244,7 +249,7 @@ void Qt4ProjectConfigWidget::updateProblemLabel() QString shadowBuildWarning; if (!version->supportsShadowBuilds() && m_buildConfiguration->shadowBuild()) { - shadowBuildWarning =tr("The Qt version %1 does not support shadow builds, building might fail.") + shadowBuildWarning = tr("The Qt version %1 does not support shadow builds, building might fail.") .arg(version->displayName()) + QLatin1String("
"); } @@ -257,12 +262,7 @@ void Qt4ProjectConfigWidget::updateProblemLabel() issues = version->reportIssues(proFileName, buildDirectory); qSort(issues); - if (issues.isEmpty() && shadowBuildWarning.isEmpty()) { - m_ui->problemLabel->setVisible(false); - m_ui->warningLabel->setVisible(false); - } else { - m_ui->problemLabel->setVisible(true); - m_ui->warningLabel->setVisible(true); + if (!issues.isEmpty() || !shadowBuildWarning.isEmpty()) { QString text = QLatin1String("") + shadowBuildWarning; foreach (const ProjectExplorer::Task &task, issues) { QString type; @@ -283,23 +283,23 @@ void Qt4ProjectConfigWidget::updateProblemLabel() text.append(QLatin1String("
")); text.append(type + task.description); } - m_ui->problemLabel->setText(text); + setProblemLabel(text); + return; } } else if (targetMismatch) { - m_ui->problemLabel->setVisible(true); - m_ui->warningLabel->setVisible(true); - m_ui->problemLabel->setText(shadowBuildWarning + tr("A build for a different project exists in %1, which will be overwritten.", - "%1 build directory") - .arg(m_ui->shadowBuildDirEdit->path())); + setProblemLabel(shadowBuildWarning + tr("A build for a different project exists in %1, which will be overwritten.", + "%1 build directory") + .arg(m_ui->shadowBuildDirEdit->path())); + return; } else if (incompatibleBuild) { - m_ui->warningLabel->setVisible(true); - m_ui->problemLabel->setVisible(true); - m_ui->problemLabel->setText(shadowBuildWarning +tr("An incompatible build exists in %1, which will be overwritten.", - "%1 build directory") - .arg(m_ui->shadowBuildDirEdit->path())); + setProblemLabel(shadowBuildWarning +tr("An incompatible build exists in %1, which will be overwritten.", + "%1 build directory") + .arg(m_ui->shadowBuildDirEdit->path())); + return; } else if (!shadowBuildWarning.isEmpty()) { - m_ui->warningLabel->setVisible(true); - m_ui->problemLabel->setVisible(true); - m_ui->problemLabel->setText(shadowBuildWarning); + setProblemLabel(shadowBuildWarning); + return; } + + setProblemLabel(QString()); } diff --git a/src/plugins/qt4projectmanager/qt4projectconfigwidget.h b/src/plugins/qt4projectmanager/qt4projectconfigwidget.h index da407c865f3..16d26c13bd8 100644 --- a/src/plugins/qt4projectmanager/qt4projectconfigwidget.h +++ b/src/plugins/qt4projectmanager/qt4projectconfigwidget.h @@ -72,6 +72,7 @@ private slots: private: void updateDetails(); + void setProblemLabel(const QString &text); Ui::Qt4ProjectConfigWidget *m_ui; QAbstractButton *m_browseButton; diff --git a/src/tools/sdktool/addkeysoperation.cpp b/src/tools/sdktool/addkeysoperation.cpp index e53cdb779d0..86308591f8d 100644 --- a/src/tools/sdktool/addkeysoperation.cpp +++ b/src/tools/sdktool/addkeysoperation.cpp @@ -112,7 +112,7 @@ bool AddKeysOperation::test() const data.append(KeyValuePair(QLatin1String("newsub/1/2.1/3/qbytearray"), QString::fromLatin1("QByteArray:test array."))); QVariantMap result = addKeys(testMap, data); - if (result.count() != 8) + if (result.count() != 9) return false; // subkeys: diff --git a/src/tools/sdktool/addkitoperation.cpp b/src/tools/sdktool/addkitoperation.cpp index 6abb9f7bec4..917ea48760a 100644 --- a/src/tools/sdktool/addkitoperation.cpp +++ b/src/tools/sdktool/addkitoperation.cpp @@ -208,7 +208,7 @@ int AddKitOperation::execute() const map = initializeKits(); map = addKit(map, m_id, m_displayName, m_icon, m_debuggerEngine, m_debugger, - m_deviceType, m_sysRoot, m_tc, m_qt, m_mkspec, m_extra); + m_deviceType.toUtf8(), m_sysRoot, m_tc, m_qt, m_mkspec, m_extra); if (map.isEmpty()) return -2; @@ -230,9 +230,9 @@ bool AddKitOperation::test() const || map.value(QLatin1String(DEFAULT)).toInt() != -1) return false; - map = addKit(map, QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("/tmp/icon.png"), + map = addKit(map, QLatin1String("testId"), QLatin1String("Test Kit"), QLatin1String("/tmp/icon.png"), 1, QLatin1String("/usr/bin/gdb-test"), - QLatin1String("Desktop"), QString(), + QByteArray("Desktop"), QString(), QLatin1String("{some-tc-id}"), QLatin1String("{some-qt-id}"), QLatin1String("unsupported/mkspec"), KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue")))); @@ -247,11 +247,11 @@ bool AddKitOperation::test() const return false; QVariantMap profile0 = map.value(QLatin1String("Profile.0")).toMap(); - if (profile0.count() != 6 + if (profile0.count() != 5 || !profile0.contains(QLatin1String(ID)) || profile0.value(QLatin1String(ID)).toString() != QLatin1String("testId") || !profile0.contains(QLatin1String(DISPLAYNAME)) - || profile0.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version") + || profile0.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Kit") || !profile0.contains(QLatin1String(AUTODETECTED)) || profile0.value(QLatin1String(AUTODETECTED)).toBool() != true) return false; @@ -259,16 +259,16 @@ bool AddKitOperation::test() const // Ignore existing ids: QVariantMap result = addKit(map, QLatin1String("testId"), QLatin1String("Test Qt Version X"), QLatin1String("/tmp/icon3.png"), 1, QLatin1String("/usr/bin/gdb-test3"), - QLatin1String("Desktop"), QString(), + QByteArray("Desktop"), QString(), QLatin1String("{some-tc-id3}"), QLatin1String("{some-qt-id3}"), QLatin1String("unsupported/mkspec3"), KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue3")))); if (!result.isEmpty()) return false; // Make sure name is unique: - map = addKit(map, QLatin1String("testId2"), QLatin1String("Test Qt Version"), QLatin1String("/tmp/icon2.png"), + map = addKit(map, QLatin1String("testId2"), QLatin1String("Test Kit2"), QLatin1String("/tmp/icon2.png"), 1, QLatin1String("/usr/bin/gdb-test2"), - QLatin1String("Desktop"), QString(), + QByteArray("Desktop"), QString(), QLatin1String("{some-tc-id2}"), QLatin1String("{some-qt-id2}"), QLatin1String("unsupported/mkspec2"), KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue2")))); if (map.count() != 5 @@ -285,11 +285,11 @@ bool AddKitOperation::test() const return false; QVariantMap profile1 = map.value(QLatin1String("Profile.1")).toMap(); - if (profile1.count() != 6 + if (profile1.count() != 5 || !profile1.contains(QLatin1String(ID)) || profile1.value(QLatin1String(ID)).toString() != QLatin1String("testId2") || !profile1.contains(QLatin1String(DISPLAYNAME)) - || profile1.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version2") + || profile1.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Kit2") || !profile1.contains(QLatin1String(AUTODETECTED)) || profile1.value(QLatin1String(AUTODETECTED)).toBool() != true) return false; @@ -301,7 +301,7 @@ bool AddKitOperation::test() const QVariantMap AddKitOperation::addKit(const QVariantMap &map, const QString &id, const QString &displayName, const QString &icon, const quint32 &debuggerType, const QString &debugger, - const QString &deviceType, const QString &sysRoot, + const QByteArray &deviceType, const QString &sysRoot, const QString &tc, const QString &qt, const QString &mkspec, const KeyValuePairList &extra) { diff --git a/src/tools/sdktool/addkitoperation.h b/src/tools/sdktool/addkitoperation.h index 4acc06b457a..5585fadec3e 100644 --- a/src/tools/sdktool/addkitoperation.h +++ b/src/tools/sdktool/addkitoperation.h @@ -54,7 +54,7 @@ public: static QVariantMap addKit(const QVariantMap &map, const QString &id, const QString &displayName, const QString &icon, const quint32 &debuggerType, const QString &debugger, - const QString &deviceType, const QString &sysRoot, + const QByteArray &deviceType, const QString &sysRoot, const QString &tc, const QString &qt, const QString &mkspec, const KeyValuePairList &extra); diff --git a/src/tools/sdktool/addqtoperation.cpp b/src/tools/sdktool/addqtoperation.cpp index 57f44e3c64c..ec5f6b4e2b5 100644 --- a/src/tools/sdktool/addqtoperation.cpp +++ b/src/tools/sdktool/addqtoperation.cpp @@ -77,46 +77,74 @@ bool AddQtOperation::setArguments(const QStringList &args) const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString(); if (current == QLatin1String("--id")) { - if (next.isNull()) + if (next.isNull()) { + std::cerr << "Error parsing after --id." << std::endl << std::endl; return false; + } ++i; // skip next; m_id = next; continue; } if (current == QLatin1String("--name")) { - if (next.isNull()) + if (next.isNull()) { + std::cerr << "Error parsing after --name." << std::endl << std::endl; return false; + } ++i; // skip next; m_displayName = next; continue; } if (current == QLatin1String("--qmake")) { - if (next.isNull()) + if (next.isNull()) { + std::cerr << "Error parsing after --qmake." << std::endl << std::endl; return false; + } ++i; // skip next; m_qmake = next; continue; } if (current == QLatin1String("--type")) { - if (next.isNull()) + if (next.isNull()) { + std::cerr << "Error parsing after --type." << std::endl << std::endl; return false; + } ++i; // skip next; m_type = next; continue; } - if (next.isNull()) + if (next.isNull()) { + std::cerr << "Unknown parameter: " << qPrintable(current) << std::endl << std::endl; return false; + } ++i; // skip next; KeyValuePair pair(current, next); - if (!pair.value.isValid()) + if (!pair.value.isValid()) { + std::cerr << "Error parsing: " << qPrintable(current) << " " << qPrintable(next) << std::endl << std::endl; return false; + } m_extra << pair; } + if (m_id.isEmpty()) { + std::cerr << "Error no id was passed." << std::endl << std::endl; + } + + if (m_displayName.isEmpty()) { + std::cerr << "Error no display name was passed." << std::endl << std::endl; + } + + if (m_qmake.isEmpty()) { + std::cerr << "Error no qmake was passed." << std::endl << std::endl; + } + + if (m_type.isEmpty()) { + std::cerr << "Error no type was passed." << std::endl << std::endl; + } + return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_qmake.isEmpty() && !m_type.isEmpty(); } @@ -155,7 +183,7 @@ bool AddQtOperation::test() const return false; QVariantMap version0 = map.value(QLatin1String("QtVersion.0")).toMap(); - if (version0.count() != 6 + if (version0.count() != 7 || !version0.contains(QLatin1String(ID)) || version0.value(QLatin1String(ID)).toInt() != -1 || !version0.contains(QLatin1String(DISPLAYNAME)) @@ -194,7 +222,7 @@ bool AddQtOperation::test() const return false; QVariantMap version1 = map.value(QLatin1String("QtVersion.1")).toMap(); - if (version1.count() != 6 + if (version1.count() != 7 || !version1.contains(QLatin1String(ID)) || version1.value(QLatin1String(ID)).toInt() != -1 || !version1.contains(QLatin1String(DISPLAYNAME)) diff --git a/src/tools/sdktool/main.cpp b/src/tools/sdktool/main.cpp index 732c7621ebb..e87022480f4 100644 --- a/src/tools/sdktool/main.cpp +++ b/src/tools/sdktool/main.cpp @@ -139,6 +139,7 @@ int parseArguments(const QStringList &args, Settings *s, const QListoperation->setArguments(opArgs)) { + std::cerr << "Argument parsing failed." << std::endl << std::endl; printHelp(s->operation); return -1; } diff --git a/src/tools/sdktool/operation.cpp b/src/tools/sdktool/operation.cpp index 073d1a5fe34..13faf1172e5 100644 --- a/src/tools/sdktool/operation.cpp +++ b/src/tools/sdktool/operation.cpp @@ -105,8 +105,6 @@ QVariantMap Operation::load(const QString &file) const if (!reader.load(path)) return QVariantMap(); map = reader.restoreValues(); - } else { - std::cout << "No such file: " << qPrintable(path.toUserOutput()) << std::endl; } return map; diff --git a/src/tools/sdktool/rmkitoperation.cpp b/src/tools/sdktool/rmkitoperation.cpp index 2fe2f3df2b1..417c8f7d874 100644 --- a/src/tools/sdktool/rmkitoperation.cpp +++ b/src/tools/sdktool/rmkitoperation.cpp @@ -100,7 +100,7 @@ bool RmKitOperation::test() const QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("/tmp/icon.png"), 1, QLatin1String("/usr/bin/gdb-test"), - QLatin1String("Desktop"), QString(), + QByteArray("Desktop"), QString(), QLatin1String("{some-tc-id}"), QLatin1String("{some-qt-id}"), QLatin1String("unsupported/mkspec"), KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue")))); @@ -108,7 +108,7 @@ bool RmKitOperation::test() const AddKitOperation::addKit(map, QLatin1String("testId2"), QLatin1String("Test Qt Version"), QLatin1String("/tmp/icon2.png"), 1, QLatin1String("/usr/bin/gdb-test2"), - QLatin1String("Desktop"), QString(), + QByteArray("Desktop"), QString(), QLatin1String("{some-tc-id2}"), QLatin1String("{some-qt-id2}"), QLatin1String("unsupported/mkspec2"), KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue2")))); diff --git a/src/tools/sdktool/sdktool.pro b/src/tools/sdktool/sdktool.pro index 868c660ac58..ecb13e8d33a 100644 --- a/src/tools/sdktool/sdktool.pro +++ b/src/tools/sdktool/sdktool.pro @@ -42,3 +42,5 @@ DESTDIR=$$IDE_LIBEXEC_PATH macx:DEFINES += "DATA_PATH=\"\\\".\\\"\"" else:DEFINES += "DATA_PATH=\"\\\"../share/qtcreator\\\"\"" +target.path = $$QTC_PREFIX/bin # FIXME: libexec, more or less +INSTALLS += target diff --git a/tests/manual/debugger/simple/simple_test_app.cpp b/tests/manual/debugger/simple/simple_test_app.cpp index c18ed88a951..dea97a0034c 100644 --- a/tests/manual/debugger/simple/simple_test_app.cpp +++ b/tests/manual/debugger/simple/simple_test_app.cpp @@ -956,19 +956,19 @@ namespace qhash { Hash::iterator it1 = hash.begin(); Hash::iterator it2 = it1; ++it2; - Hash::iterator it3 = it2; ++it2; - Hash::iterator it4 = it3; ++it3; - Hash::iterator it5 = it4; ++it4; - Hash::iterator it6 = it5; ++it5; + Hash::iterator it3 = it2; ++it3; + Hash::iterator it4 = it3; ++it4; + Hash::iterator it5 = it4; ++it5; + Hash::iterator it6 = it5; ++it6; BREAK_HERE; // Expand hash. - // Check hash <6 items> Hash. + // Check hash <6 items> qhash::Hash. // Check hash.11 11 float. - // Check it1.first 11 int. - // Check it1.second 11 float. - // Check it1.first 55 int. - // Check it1.second 55 float. + // Check it1.key 55 int. + // Check it1.value 55 float. + // Check it6.key 33 int. + // Check it6.value 33 float. // Continue. dummyStatement(&hash, &it1, &it2, &it3, &it4, &it5, &it6); } @@ -1746,7 +1746,7 @@ namespace qobject { s += test.myProp2(); BREAK_HERE; // Check s "HELLOWORLD" QString. - // Check test "" qobject::Names::Bar::TestObject. + // Check test qobject::Names::Bar::TestObject. // Continue. dummyStatement(&s); #endif @@ -2141,7 +2141,7 @@ namespace plugin { #endif BREAK_HERE; // CheckType dir QString. - // Check lib "" QLibrary. + // CheckType lib QLibrary. // CheckType name QString. // CheckType res int. // Continue. @@ -2175,7 +2175,7 @@ namespace final { QVariant value = settings.value("item1","").toString(); BREAK_HERE; // Expand settings. - // Check settings "" QSettings. + // Check settings QSettings. // Check settings.@1 "" QObject. // Check value "" QVariant (QString). // Continue. @@ -2852,19 +2852,19 @@ namespace stdmap { Map::iterator it1 = map.begin(); Map::iterator it2 = it1; ++it2; - Map::iterator it3 = it2; ++it2; - Map::iterator it4 = it3; ++it3; - Map::iterator it5 = it4; ++it4; - Map::iterator it6 = it5; ++it5; + Map::iterator it3 = it2; ++it3; + Map::iterator it4 = it3; ++it4; + Map::iterator it5 = it4; ++it5; + Map::iterator it6 = it5; ++it6; BREAK_HERE; // Expand map. - // Check map <6 items> std::map. + // Check map <6 items> stdmap::Map. // Check map.11 11 float. // Check it1.first 11 int. // Check it1.second 11 float. - // Check it1.first 55 int. - // Check it1.second 55 float. + // Check it6.first 66 int. + // Check it6.second 66 float. // Continue. dummyStatement(&map, &it1, &it2, &it3, &it4, &it5, &it6); } @@ -3026,17 +3026,15 @@ namespace stdset { Set::iterator it1 = set.begin(); Set::iterator it2 = it1; ++it2; - Set::iterator it3 = it2; ++it2; - Set::iterator it4 = it3; ++it3; - Set::iterator it5 = it4; ++it4; - Set::iterator it6 = it5; ++it5; + Set::iterator it3 = it2; ++it3; + Set::iterator it4 = it3; ++it4; + Set::iterator it5 = it4; ++it5; + Set::iterator it6 = it5; ++it6; BREAK_HERE; - // Check set <6 items> std::set. - // Check it1.key 11 unsigned int. + // Check set <6 items> stdset::Set. // Check it1.value 11 int. - // Check it1.key 55 unsigned int. - // Check it1.value 55 int. + // Check it6.value 66 int. // Continue. dummyStatement(&set, &it1, &it2, &it3, &it4, &it5, &it6); } @@ -3486,7 +3484,7 @@ namespace itemmodel { // CheckType i1 QStandardItem. // CheckType i11 QStandardItem. // CheckType i2 QStandardItem. - // Check m "" QStandardItemModel. + // Check m QStandardItemModel. // Check mi "1" QModelIndex. // Continue. dummyStatement(&i1, &mi, &m, &i2, &i11); @@ -3846,9 +3844,11 @@ namespace qthread { if (m_id == 3) { BREAK_HERE; // Expand this. + // Expand this.@1. // Check j 3 int. // CheckType this qthread::Thread. - // Check this.@1 "This is thread #3" QThread. + // Check this.@1 QThread. + // Check this.@1.@1 "This is thread #3" QObject. // Continue. dummyStatement(this); } @@ -3871,9 +3871,15 @@ namespace qthread { } BREAK_HERE; // Expand thread. + // Expand thread.0. + // Expand thread.0.@1. + // Expand thread.13. + // Expand thread.13.@1. // CheckType thread qthread::Thread [14]. - // Check thread.0 "This is thread #0" qthread::Thread. - // Check thread.13 "This is thread #13" qthread::Thread. + // Check thread.0 qthread::Thread. + // Check thread.0.@1.@1 "This is thread #0" qthread::Thread. + // Check thread.13 qthread::Thread. + // Check thread.13.@1.@1 "This is thread #13" qthread::Thread. // Continue. for (int i = 0; i != N; ++i) { thread[i].wait(); @@ -5065,7 +5071,7 @@ namespace basic { ba.append('x'); BREAK_HERE; // Check ba "x" QByteArray. - // Check proc "" QProcess. + // Check proc QProcess. // Continue. // Check there is some contents in ba. Error message is expected. @@ -5410,7 +5416,7 @@ namespace qscript { QScriptValue s; BREAK_HERE; - // Check engine "" QScriptEngine. + // Check engine QScriptEngine. // Check s (invalid) QScriptValue. // Check x1 QString. // Continue. @@ -5505,10 +5511,12 @@ namespace boost { boost::shared_ptr j = i; boost::shared_ptr sl(new QStringList(QStringList() << "HUH!")); BREAK_HERE; - // Check s boost::shared_ptr. + // Expand sl. + // Check s (null) boost::shared_ptr. // Check i 43 boost::shared_ptr. // Check j 43 boost::shared_ptr. - // Check sl <1 item> boost::shared_ptr. + // Check sl boost::shared_ptr. + // Check sl.data <1 items> QStringList // Continue. dummyStatement(&s, &j, &sl); } @@ -5547,7 +5555,7 @@ namespace boost { // Not where we started (expected in boost) d -= months(4); BREAK_HERE; - // Check d Tue Nov 30 2005 boost::gregorian::date. + // Check d Wed Nov 30 2005 boost::gregorian::date. // Continue. dummyStatement(&d); @@ -6199,8 +6207,11 @@ namespace bug6857 { file.setObjectName("A file"); BREAK_HERE; // Expand file. - // Check file "A file" bug6857::MyFile. + // Expand file.@1. + // Expand file.@1.@1. + // Check file bug6857::MyFile. // Check file.@1 "/tmp/tt" QFile. + // Check file.@1.@1.@1 "A file" QObject. // Continue. dummyStatement(&file); } @@ -6222,8 +6233,12 @@ namespace bug6858 { file.setObjectName("Another file"); QFile *pfile = &file; BREAK_HERE; - // Check pfile "Another file" bug6858::MyFile. + // Expand pfile. + // Expand pfile.@1. + // Expand pfile.@1.@1. + // Check pfile bug6858::MyFile. // Check pfile.@1 "/tmp/tt" QFile. + // Check pfile.@1.@1.@1 "Another file" QObject. // Continue. dummyStatement(&file, pfile); } diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index 090ee68f267..341ad5bd454 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -83,13 +83,16 @@ def shadowBuildDir(path, project, qtVersion, debugVersion): # because the Simulator target is added for some cases even when Simulator has not # been set up inside Qt versions/Toolchains # this list can be used in __chooseTargets__() -def __createProjectSelectType__(category, template, fromWelcome = False): +def __createProjectOrFileSelectType__(category, template, fromWelcome = False, isProject=True): if fromWelcome: mouseClick(waitForObject(":CreateProject_QStyleItem"), 5, 5, 0, Qt.LeftButton) else: invokeMenuItem("File", "New File or Project...") categoriesView = waitForObject("{type='QTreeView' name='templateCategoryView'}", 20000) - clickItem(categoriesView, "Projects." + category, 5, 5, 0, Qt.LeftButton) + if isProject: + clickItem(categoriesView, "Projects." + category, 5, 5, 0, Qt.LeftButton) + else: + clickItem(categoriesView, "Files and Classes." + category, 5, 5, 0, Qt.LeftButton) templatesView = waitForObject("{name='templatesView' type='QListView'}", 20000) clickItem(templatesView, template, 5, 5, 0, Qt.LeftButton) text = waitForObject("{type='QTextBrowser' name='templateDescription' visible='1'}").plainText @@ -150,7 +153,7 @@ def __verifyFileCreation__(path, expectedFiles): # param checks turns tests in the function on if set to True def createProject_Qt_GUI(path, projectName, checks = True): template = "Qt Gui Application" - available = __createProjectSelectType__(" Applications", template) + available = __createProjectOrFileSelectType__(" Applications", template) __createProjectSetNameAndPath__(path, projectName, checks) __selectQtVersionDesktop__(checks, available) @@ -188,7 +191,7 @@ def createProject_Qt_GUI(path, projectName, checks = True): # param projectName is the name for the new project # param checks turns tests in the function on if set to True def createProject_Qt_Console(path, projectName, checks = True): - available = __createProjectSelectType__(" Applications", "Qt Console Application") + available = __createProjectOrFileSelectType__(" Applications", "Qt Console Application") __createProjectSetNameAndPath__(path, projectName, checks) __selectQtVersionDesktop__(checks, available) @@ -210,9 +213,9 @@ def createNewQtQuickApplication(workingDir, projectName = None, templateFile = N targets = QtQuickConstants.Targets.DESKTOP_474_GCC, qtQuickVersion=1, fromWelcome=False): if templateFile: - available = __createProjectSelectType__(" Applications", "Qt Quick Application (from Existing QML File)", fromWelcome) + available = __createProjectOrFileSelectType__(" Applications", "Qt Quick Application (from Existing QML File)", fromWelcome) else: - available = __createProjectSelectType__(" Applications", "Qt Quick %d Application (Built-in Elements)" + available = __createProjectOrFileSelectType__(" Applications", "Qt Quick %d Application (Built-in Elements)" % qtQuickVersion, fromWelcome) projectName = __createProjectSetNameAndPath__(workingDir, projectName) if templateFile: @@ -228,7 +231,7 @@ def createNewQtQuickApplication(workingDir, projectName = None, templateFile = N return projectName def createNewQtQuickUI(workingDir): - __createProjectSelectType__(" Applications", "Qt Quick UI") + __createProjectOrFileSelectType__(" Applications", "Qt Quick UI") if workingDir == None: workingDir = tempDir() projectName = __createProjectSetNameAndPath__(workingDir) @@ -236,7 +239,7 @@ def createNewQtQuickUI(workingDir): return projectName def createNewQmlExtension(workingDir): - available = __createProjectSelectType__(" Libraries", "Custom QML Extension Plugin") + available = __createProjectOrFileSelectType__(" Libraries", "Custom QML Extension Plugin") if workingDir == None: workingDir = tempDir() __createProjectSetNameAndPath__(workingDir) @@ -248,7 +251,7 @@ def createNewQmlExtension(workingDir): 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") + replaceEditorContent(uriLineEd, "org.qt-project.test.qmlcomponents") clickButton(nextButton) __createProjectHandleLastPage__() diff --git a/tests/system/tools/findUnusedObjects.py b/tests/system/tools/findUnusedObjects.py new file mode 100755 index 00000000000..a032960299e --- /dev/null +++ b/tests/system/tools/findUnusedObjects.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python + +import os +import sys +import tokenize +from optparse import OptionParser + +objMap = None + +def parseCommandLine(): + global directory, onlyRemovable, fileType + scriptChoice = ('Python', 'JavaScript', 'Perl', 'Tcl', 'Ruby') + parser = OptionParser("\n%prog [OPTIONS] [DIRECTORY]") + parser.add_option("-o", "--only-removable", dest="onlyRemovable", + action="store_true", default=False, + help="list removable objects only") + parser.add_option("-t", "--type", dest='fileType', type="choice", + choices=scriptChoice, + default='Python', nargs=1, metavar='LANG', + help="script language of the Squish tests (" + + ", ".join(scriptChoice) + "; default: %default)") + (options, args) = parser.parse_args() + if len(args) == 0: + directory = os.path.abspath(".") + elif len(args) == 1: + directory = os.path.abspath(args[0]) + else: + print "\nERROR: Too many arguments\n" + parser.print_help() + sys.exit(1) + onlyRemovable = options.onlyRemovable + fileType = options.fileType + +def checkDirectory(): + global directory, objMap + if not os.path.exists(directory): + print "Given path '%s' does not exist" % directory + sys.exit(1) + objMap = os.path.join(directory, "objects.map") + if not os.path.exists(objMap): + print "Given path '%s' does not contain an objects.map file" % directory + sys.exit(1) + +def getFileContent(filePath): + if os.path.isfile(filePath): + f = open(filePath, "r") + data = f.read() + f.close() + return data + return "" + +def collectObjects(): + global objMap + data = getFileContent(objMap) + return map(lambda x: x.strip().split("\t", 1)[0], data.strip().splitlines()) + +def getFileSuffix(): + global fileType + fileSuffixes = {'Python':'.py', 'JavaScript':'.js', 'Perl':'.pl', + 'Tcl':'.tcl', 'Ruby':'.rb'} + return fileSuffixes.get(fileType, None) + +def handle_token(tokenType, token, (startRow, startCol), (endRow, endCol), line): + global useCounts + if tokenize.tok_name[tokenType] == 'STRING': + for obj in useCounts: + useCounts[obj] += str(token).count("'%s'" % obj) + useCounts[obj] += str(token).count('"%s"' % obj) + +def findUsages(): + global directory, objMap + suffix = getFileSuffix() + for root, dirnames, filenames in os.walk(directory): + for filename in filter(lambda x: x.endswith(suffix), filenames): + currentFile = open(os.path.join(root, filename)) + tokenize.tokenize(currentFile.readline, handle_token) + currentFile.close() + currentFile = open(objMap) + tokenize.tokenize(currentFile.readline, handle_token) + currentFile.close() + +def printResult(): + global useCounts, onlyRemovable + print + if onlyRemovable: + if min(useCounts.values()) > 0: + print "All objects are used once at least.\n" + return False + print "Unused objects:\n" + for obj in filter(lambda x: useCounts[x] == 0, useCounts): + print "%s" % obj + return True + else: + length = max(map(len, useCounts.keys())) + outFormat = "%%%ds %%3d" % length + for obj,useCount in useCounts.iteritems(): + print outFormat % (obj, useCount) + print + return None + +def main(): + global useCounts + checkDirectory() + useCounts = dict.fromkeys(collectObjects(), 0) + findUsages() + atLeastOneRemovable = printResult() + if atLeastOneRemovable: + print "\nAfter removing the listed objects you should re-run this tool" + print "to find objects that might have been used only by these objects.\n" + return 0 + +if __name__ == '__main__': + parseCommandLine() + sys.exit(main())