diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index 403355426fd..9db241266a0 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -1390,12 +1390,20 @@ void Check::warnAboutUnnecessarySuppressions() bool Check::isQtQuick2() const { - foreach (const Import &import, _imports->all()) { - if (import.info.name() == QLatin1String("QtQuick") - && import.info.version().majorVersion() == 2) - return true; + if (_doc->language() == Dialect::Qml) { + foreach (const Import &import, _imports->all()) { + if (import.info.name() == QLatin1String("QtQuick") + && import.info.version().majorVersion() == 2) + return true; + } + return false; } - return false; + return _doc->language() == Dialect::QmlQtQuick2 || _doc->language() == Dialect::QmlQtQuick2Ui; +} + +bool Check::isQtQuick2Ui() const +{ + return _doc->language() == Dialect::QmlQtQuick2Ui; } bool Check::visit(NewExpression *ast) diff --git a/src/libs/qmljs/qmljscheck.h b/src/libs/qmljs/qmljscheck.h index a4e37981525..b5247856fea 100644 --- a/src/libs/qmljs/qmljscheck.h +++ b/src/libs/qmljs/qmljscheck.h @@ -118,6 +118,7 @@ private: void warnAboutUnnecessarySuppressions(); bool isQtQuick2() const; + bool isQtQuick2Ui() const; AST::Node *parent(int distance = 0); diff --git a/src/libs/qmljs/qmljsdialect.cpp b/src/libs/qmljs/qmljsdialect.cpp index 2641f6bf7c6..4330db263de 100644 --- a/src/libs/qmljs/qmljsdialect.cpp +++ b/src/libs/qmljs/qmljsdialect.cpp @@ -38,6 +38,7 @@ bool Dialect::isQmlLikeLanguage() const case Dialect::Qml: case Dialect::QmlQtQuick1: case Dialect::QmlQtQuick2: + case Dialect::QmlQtQuick2Ui: case Dialect::QmlQbs: case Dialect::QmlProject: case Dialect::QmlTypeInfo: @@ -56,6 +57,7 @@ bool Dialect::isFullySupportedLanguage() const case Dialect::Qml: case Dialect::QmlQtQuick1: case Dialect::QmlQtQuick2: + case Dialect::QmlQtQuick2Ui: return true; case Dialect::NoLanguage: case Dialect::AnyLanguage: @@ -73,6 +75,7 @@ bool Dialect::isQmlLikeOrJsLanguage() const case Dialect::Qml: case Dialect::QmlQtQuick1: case Dialect::QmlQtQuick2: + case Dialect::QmlQtQuick2Ui: case Dialect::QmlQbs: case Dialect::QmlProject: case Dialect::QmlTypeInfo: @@ -97,6 +100,8 @@ QString Dialect::toString() const return QLatin1String("QmlQtQuick1"); case Dialect::QmlQtQuick2: return QLatin1String("QmlQtQuick2"); + case Dialect::QmlQtQuick2Ui: + return QLatin1String("QmlQtQuick2Ui"); case Dialect::NoLanguage: return QLatin1String("NoLanguage"); case Dialect::AnyLanguage: @@ -178,6 +183,9 @@ bool Dialect::restrictLanguage(const Dialect &l2) } if (i2 && !i1) return true; + qDebug() << toString() << "restrictTo" << l2.toString() << "failed"; + qDebug() << ll1 << ll2; + qDebug() << i1 << i2; QList qmlLangs = Dialect(Qml).companionLanguages(); if (qmlLangs.contains(*this) && qmlLangs.contains(l2)) *this = Dialect::Qml; @@ -199,16 +207,22 @@ QList Dialect::companionLanguages() const langs << Dialect::JavaScript; break; case Dialect::Qml: - langs << Dialect::QmlQtQuick1 << Dialect::QmlQtQuick2 << Dialect::JavaScript; + langs << Dialect::QmlQtQuick1 << Dialect::QmlQtQuick2 << Dialect::QmlQtQuick2Ui + << Dialect::JavaScript; break; case Dialect::QmlQtQuick1: - case Dialect::QmlQtQuick2: langs << Dialect::Qml << Dialect::JavaScript; break; + case Dialect::QmlQtQuick2: + case Dialect::QmlQtQuick2Ui: + langs.clear(); + langs << Dialect::QmlQtQuick2 << Dialect::QmlQtQuick2Ui << Dialect::Qml + << Dialect::JavaScript; + break; case Dialect::AnyLanguage: langs << Dialect::JavaScript << Dialect::Json << Dialect::QmlProject << Dialect:: QmlQbs << Dialect::QmlTypeInfo << Dialect::QmlQtQuick1 << Dialect::QmlQtQuick2 - << Dialect::Qml; + << Dialect::QmlQtQuick2Ui << Dialect::Qml; break; case Dialect::NoLanguage: return QList(); // return at least itself? diff --git a/src/libs/qmljs/qmljsdialect.h b/src/libs/qmljs/qmljsdialect.h index 3ee6f26c125..accb00956af 100644 --- a/src/libs/qmljs/qmljsdialect.h +++ b/src/libs/qmljs/qmljsdialect.h @@ -51,7 +51,8 @@ public: QmlQbs = 6, QmlProject = 7, QmlTypeInfo = 8, - AnyLanguage = 9, + QmlQtQuick2Ui = 9, + AnyLanguage = 10, }; Dialect(Enum dialect = NoLanguage) : m_dialect(dialect) diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp index be664ba56d9..f8413ad3ec2 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp @@ -78,6 +78,8 @@ QMLJS_EXPORT Q_LOGGING_CATEGORY(qmljsLog, "qtc.qmljs.common") static ModelManagerInterface *g_instance = 0; +const char qtQuickUISuffix[] = "ui.qml"; + static QStringList environmentImportPaths() { QStringList paths; @@ -148,6 +150,7 @@ static QHash defaultLanguageMapping() res[QLatin1String("qmlproject")] = Dialect::QmlProject; res[QLatin1String("json")] = Dialect::Json; res[QLatin1String("qbs")] = Dialect::QmlQbs; + res[QLatin1String(qtQuickUISuffix)] = Dialect::QmlQtQuick2Ui; return res; } @@ -159,7 +162,16 @@ Dialect ModelManagerInterface::guessLanguageOfFile(const QString &fileName) else lMapping = defaultLanguageMapping(); const QFileInfo info(fileName); - const QString fileSuffix = info.suffix(); + QString fileSuffix = info.suffix(); + + /* + * I was reluctant to use complete suffix in all cases, because it is a huge + * change in behaivour. But in case of .qml this should be safe. + */ + + if (fileSuffix == QLatin1String("qml")) + fileSuffix = info.completeSuffix(); + return lMapping.value(fileSuffix, Dialect::NoLanguage); } @@ -856,6 +868,8 @@ void ModelManagerInterface::parseLoop(QSet &scannedPaths, if (language == Dialect::Qml && (mainLanguage == Dialect::QmlQtQuick1 || mainLanguage == Dialect::QmlQtQuick2)) language = mainLanguage; + if (language == Dialect::Qml && mainLanguage == Dialect::QmlQtQuick2Ui) + language = Dialect::QmlQtQuick2; QString contents; int documentRevision = 0; @@ -1314,7 +1328,8 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx, && ((vCtx.language == Dialect::AnyLanguage && doc->language() != Dialect::NoLanguage) || (vCtx.language == Dialect::Qml && (doc->language() == Dialect::QmlQtQuick1 - || doc->language() == Dialect::QmlQtQuick2)))) + || doc->language() == Dialect::QmlQtQuick2 + || doc->language() == Dialect::QmlQtQuick2Ui)))) res.language = doc->language(); ProjectInfo info; if (!doc.isNull()) @@ -1344,8 +1359,9 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx, res.maybeAddPath(info.qtImportsPath); // fallthrough case Dialect::QmlQtQuick2: + case Dialect::QmlQtQuick2Ui: { - if (res.language == Dialect::QmlQtQuick2) + if (res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui) res.maybeAddPath(info.qtQmlPath); QList allProjects; { @@ -1382,13 +1398,14 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx, foreach (const QString &path, defaultVCtx.paths) res.maybeAddPath(path); if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml - || res.language == Dialect::QmlQtQuick2) + || res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui) res.maybeAddPath(info.qtImportsPath); if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml || res.language == Dialect::QmlQtQuick1) res.maybeAddPath(info.qtQmlPath); if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml - || res.language == Dialect::QmlQtQuick1 || res.language == Dialect::QmlQtQuick2) { + || res.language == Dialect::QmlQtQuick1 || res.language == Dialect::QmlQtQuick2 + || res.language == Dialect::QmlQtQuick2Ui) { foreach (const QString &path, environmentImportPaths()) res.maybeAddPath(path); } @@ -1406,7 +1423,8 @@ ViewerContext ModelManagerInterface::defaultVContext(Dialect language, if (language == Dialect::AnyLanguage && doc->language() != Dialect::NoLanguage) language = doc->language(); else if (language == Dialect::Qml && - (doc->language() == Dialect::QmlQtQuick1 || doc->language() == Dialect::QmlQtQuick2)) + (doc->language() == Dialect::QmlQtQuick1 || doc->language() == Dialect::QmlQtQuick2 + || doc->language() == Dialect::QmlQtQuick2Ui)) language = doc->language(); } ViewerContext defaultCtx; diff --git a/src/libs/qmljs/qmljsviewercontext.cpp b/src/libs/qmljs/qmljsviewercontext.cpp index 14482f1158e..15bace4000d 100644 --- a/src/libs/qmljs/qmljsviewercontext.cpp +++ b/src/libs/qmljs/qmljsviewercontext.cpp @@ -71,7 +71,9 @@ bool ViewerContext::languageIsCompatible(Dialect l) const case Dialect::QmlQtQuick1: return l == Dialect::Qml || l == Dialect::QmlQtQuick1 || l == Dialect::JavaScript; case Dialect::QmlQtQuick2: - return l == Dialect::Qml || l == Dialect::QmlQtQuick2 || l == Dialect::JavaScript; + case Dialect::QmlQtQuick2Ui: + return l == Dialect::Qml || l == Dialect::QmlQtQuick2 || l == Dialect::QmlQtQuick2Ui + || l == Dialect::JavaScript; case Dialect::AnyLanguage: return true; case Dialect::NoLanguage: diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index e07c6d4ae7e..c4ce16e9c45 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -366,6 +366,7 @@ static bool checkIfEditorIsQtQuick(Core::IEditor *editor) if (!document.isNull()) return document->language() == QmlJS::Dialect::QmlQtQuick1 || document->language() == QmlJS::Dialect::QmlQtQuick2 + || document->language() == QmlJS::Dialect::QmlQtQuick2Ui || document->language() == QmlJS::Dialect::Qml; } diff --git a/src/plugins/qmljstools/QmlJSTools.mimetypes.xml b/src/plugins/qmljstools/QmlJSTools.mimetypes.xml index a1bdef531ef..048a192e9d9 100644 --- a/src/plugins/qmljstools/QmlJSTools.mimetypes.xml +++ b/src/plugins/qmljstools/QmlJSTools.mimetypes.xml @@ -4,7 +4,7 @@ QML file - + @@ -12,6 +12,12 @@ Qt Build Suite file + + + + QtQuick Designer ui file + + diff --git a/src/plugins/qmljstools/qmljsbundleprovider.cpp b/src/plugins/qmljstools/qmljsbundleprovider.cpp index 5b125591f16..a75bbdefb11 100644 --- a/src/plugins/qmljstools/qmljsbundleprovider.cpp +++ b/src/plugins/qmljstools/qmljsbundleprovider.cpp @@ -127,6 +127,7 @@ void BasicBundleProvider::mergeBundlesForKit(ProjectExplorer::Kit *kit QmlBundle b2(defaultQt5QtQuick2Bundle()); bundles.mergeBundleForLanguage(Dialect::Qml, b2); bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2, b2); + bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2Ui, b2); return; } QString qtImportsPath = qtVersion->qmakeProperty("QT_INSTALL_IMPORTS"); @@ -181,6 +182,7 @@ void BasicBundleProvider::mergeBundlesForKit(ProjectExplorer::Kit *kit qtQuick2Bundle.replaceVars(myReplacements); bundles.mergeBundleForLanguage(Dialect::Qml, qtQuick2Bundle); bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2, qtQuick2Bundle); + bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2Ui, qtQuick2Bundle); } } diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index 31b00169c19..c64fb7a3f65 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -189,6 +189,9 @@ QHash ModelManager::languageForSuffix() const MimeType qmlProjectSourceTy = MimeDatabase::findByType(QLatin1String(Constants::QMLPROJECT_MIMETYPE)); foreach (const QString &suffix, qmlProjectSourceTy.suffixes()) res[suffix] = Dialect::QmlProject; + MimeType qmlUiSourceTy = MimeDatabase::findByType(QLatin1String(Constants::QMLUI_MIMETYPE)); + foreach (const QString &suffix, qmlUiSourceTy.suffixes()) + res[suffix] = Dialect::QmlQtQuick2Ui; MimeType jsonSourceTy = MimeDatabase::findByType(QLatin1String(Constants::JSON_MIMETYPE)); foreach (const QString &suffix, jsonSourceTy.suffixes()) res[suffix] = Dialect::Json; diff --git a/src/plugins/qmljstools/qmljstoolsconstants.h b/src/plugins/qmljstools/qmljstoolsconstants.h index b5de5aabb97..bc23aeddc00 100644 --- a/src/plugins/qmljstools/qmljstoolsconstants.h +++ b/src/plugins/qmljstools/qmljstoolsconstants.h @@ -39,6 +39,7 @@ const char QML_MIMETYPE[] = "application/x-qml"; // separate def also in project const char QBS_MIMETYPE[] = "application/x-qt.qbs+qml"; const char QMLPROJECT_MIMETYPE[] = "application/x-qmlproject"; const char QMLTYPES_MIMETYPE[] = "application/x-qt.meta-info+qml"; +const char QMLUI_MIMETYPE[] = "application/x-qt.ui+qml"; const char JS_MIMETYPE[] = "application/javascript"; const char JSON_MIMETYPE[] = "application/json";