diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 40230fee147..8392aceb96f 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -24,6 +24,7 @@ ############################################################################ import os +import codecs import copy import collections import struct @@ -436,7 +437,7 @@ class DumperBase: elif self.currentValue.encoding == 'utf8': value = self.hexdecode(value) elif self.currentValue.encoding == 'utf16': - b = bytes.fromhex(value) + b = bytes(bytearray.fromhex(value)) value = codecs.decode(b, 'utf-16') self.put('"%s"' % value) if self.currentValue.elided: @@ -1501,20 +1502,20 @@ class DumperBase: return customEventFunc in (self.qtCustomEventFunc, self.qtCustomEventPltFunc) - def extractQObjectProperty(objectPtr): - vtablePtr = self.extractPointer(objectPtr) - metaObjectFunc = self.extractPointer(vtablePtr) - cmd = '((void*(*)(void*))0x%x)((void*)0x%x)' % (metaObjectFunc, objectPtr) - try: - #warn('MO CMD: %s' % cmd) - res = self.parseAndEvaluate(cmd) - #warn('MO RES: %s' % res) - self.bump('successfulMetaObjectCall') - return res.pointer() - except: - self.bump('failedMetaObjectCall') - #warn('COULD NOT EXECUTE: %s' % cmd) - return 0 +# def extractQObjectProperty(objectPtr): +# vtablePtr = self.extractPointer(objectPtr) +# metaObjectFunc = self.extractPointer(vtablePtr) +# cmd = '((void*(*)(void*))0x%x)((void*)0x%x)' % (metaObjectFunc, objectPtr) +# try: +# #warn('MO CMD: %s' % cmd) +# res = self.parseAndEvaluate(cmd) +# #warn('MO RES: %s' % res) +# self.bump('successfulMetaObjectCall') +# return res.pointer() +# except: +# self.bump('failedMetaObjectCall') +# #warn('COULD NOT EXECUTE: %s' % cmd) +# return 0 def extractMetaObjectPtr(self, objectPtr, typeobj): """ objectPtr - address of *potential* instance of QObject derived class @@ -1863,10 +1864,6 @@ class DumperBase: self.putTypedPointer('[extraData]', extraData, ns + 'QObjectPrivate::ExtraData') - if connectionListsPtr: - self.putTypedPointer('[connectionLists]', connectionListsPtr, - ns + 'QObjectConnectionListVector') - with SubItem(self, '[metaObject]'): self.putAddress(metaObjectPtr) self.putNumChild(1) @@ -1874,6 +1871,40 @@ class DumperBase: with Children(self): self.putQObjectGutsHelper(0, 0, -1, metaObjectPtr, 'QMetaObject') + with SubItem(self, '[connections]'): + if connectionListsPtr: + typeName = ns + 'QVector<' + ns + 'QObjectPrivate::ConnectionList>' + self.putItem(self.createValue(connectionListsPtr, typeName)) + else: + self.putItemCount(0) + + with SubItem(self, '[signals]'): + self.putItemCount(signalCount) + if self.isExpanded(): + with Children(self): + j = -1 + for i in range(signalCount): + t = self.split('IIIII', dataPtr + 56 + 20 * i) + flags = t[4] + if flags != 0x06: + continue + j += 1 + with SubItem(self, j): + name = self.metaString(metaObjectPtr, t[0], revision) + self.putType(' ') + self.putValue(name) + self.putNumChild(1) + with Children(self): + putt('[nameindex]', t[0]) + #putt('[type]', 'signal') + putt('[argc]', t[1]) + putt('[parameter]', t[2]) + putt('[tag]', t[3]) + putt('[flags]', t[4]) + putt('[localindex]', str(i)) + putt('[globalindex]', str(globalOffset + i)) + #self.putQObjectConnections(dd) + if isQMetaObject or isQObject: with SubItem(self, '[properties]'): @@ -2012,20 +2043,6 @@ class DumperBase: self.putValue(globalOffset + localIndex) - #with SubItem(self, '[signals]'): - # self.putItemCount(signalCount) - # signalNames = metaData(52, -14, 5) - # warn('NAMES: %s' % signalNames) - # if self.isExpanded(): - # with Children(self): - # putt('A', 'b') - # for i in range(signalCount): - # k = signalNames[i] - # with SubItem(self, k): - # self.putEmptyValue() - # if dd: - # self.putQObjectConnections(dd) - def putQObjectConnections(self, dd): with SubItem(self, '[connections]'): ptrSize = self.ptrSize() diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 29cbfb5e2f1..0877634a3c5 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -1078,6 +1078,26 @@ def qdump__QMetaObject(d, value): d.putMembersItem(value) +def qdump__QObjectPrivate__ConnectionList(d, value): + d.putNumChild(1) + if d.isExpanded(): + i = 0 + with Children(d): + first, last = value.split('pp') + currentConnection = first + connectionType = d.createType('QObjectPrivate::Connection') + while currentConnection and currentConnection != last: + sender, receiver, slotObj, nextConnectionList, nextp, prev = \ + d.split('pppppp', currentConnection) + d.putSubItem(i, d.createValue(currentConnection, connectionType)) + currentConnection = nextp + i += 1 + d.putFields(value) + d.putItemCount(i) + else: + d.putSpecialValue('minimumitemcount', 0) + + def qdump__QPixmap(d, value): if d.qtVersion() < 0x050000: (vtbl, painters, dataPtr) = value.split('ppp'); diff --git a/src/plugins/coreplugin/manhattanstyle.cpp b/src/plugins/coreplugin/manhattanstyle.cpp index 63bdabb73ce..375d38afb5c 100644 --- a/src/plugins/coreplugin/manhattanstyle.cpp +++ b/src/plugins/coreplugin/manhattanstyle.cpp @@ -618,26 +618,6 @@ void ManhattanStyle::drawControl(ControlElement element, const QStyleOption *opt return QProxyStyle::drawControl(element, option, painter, widget); switch (element) { - case CE_TabBarTabShape: - // Most styles draw a single dark outline. This looks rather ugly when combined with our - // single pixel dark separator so we adjust the first tab to compensate for this - - if (const QStyleOptionTab *tab = qstyleoption_cast(option)) { - QStyleOptionTab adjustedTab = *tab; - if (tab->cornerWidgets == QStyleOptionTab::NoCornerWidgets && ( - tab->position == QStyleOptionTab::Beginning || - tab->position == QStyleOptionTab::OnlyOneTab)) - { - if (option->direction == Qt::LeftToRight) - adjustedTab.rect = adjustedTab.rect.adjusted(-1, 0, 0, 0); - else - adjustedTab.rect = adjustedTab.rect.adjusted(0, 0, 1 ,0); - } - QProxyStyle::drawControl(element, &adjustedTab, painter, widget); - return; - } - break; - case CE_MenuItem: painter->save(); if (const QStyleOptionMenuItem *mbi = qstyleoption_cast(option)) { diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index d8a197b45a3..d2493e2e457 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -208,7 +208,14 @@ const char pp_configuration[] = "#define __finally\n" "#define __inline inline\n" "#define __forceinline inline\n" - "#define __pragma(x)\n"; + "#define __pragma(x)\n" + "#define __w64\n" + "#define __int64 long long\n" + "#define __int32 long\n" + "#define __int16 short\n" + "#define __int8 char\n" + "#define __ptr32\n" + "#define __ptr64\n"; QSet CppModelManager::timeStampModifiedFiles(const QList &documentsToCheck) { diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 33759888faf..2b95e64cb73 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -303,7 +303,7 @@ QmlEngine::QmlEngine(const DebuggerRunParameters &startParameters, DebuggerEngin connect(d->connection, &QmlDebugConnection::logStateChange, this, &QmlEngine::showConnectionStateMessage); connect(d->connection, &QmlDebugConnection::logError, this, - [this](const QString &error) { showMessage("QML Debugger: " + error, StatusBar); }); + [this](const QString &error) { showMessage("QML Debugger: " + error, LogWarning); }); connect(d->connection, &QmlDebugConnection::connectionFailed, this, &QmlEngine::connectionFailed); @@ -1261,6 +1261,8 @@ void QmlEngine::connectionFailed() { // this is only an error if we are already connected and something goes wrong. if (isConnected()) { + showMessage(tr("QML Debugger: Connection failed."), StatusBar); + if (!isSlaveEngine()) { // normal flow for slave engine when gdb exits notifyInferiorSpontaneousStop(); notifyInferiorIll(); diff --git a/src/plugins/debugger/qml/qmlinspectoragent.cpp b/src/plugins/debugger/qml/qmlinspectoragent.cpp index 0f430bb45ee..132369fea71 100644 --- a/src/plugins/debugger/qml/qmlinspectoragent.cpp +++ b/src/plugins/debugger/qml/qmlinspectoragent.cpp @@ -606,7 +606,15 @@ void QmlInspectorAgent::addWatchData(const ObjectReference &obj, name = obj.className(); if (name.isEmpty()) - return; + name = obj.name(); + + if (name.isEmpty()) { + FileReference file = obj.source(); + name = file.url().fileName() + ':' + QString::number(file.lineNumber()); + } + + if (name.isEmpty()) + name = tr(""); // object auto objWatch = new WatchItem; diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index 566fcc9fef4..0b259e6f329 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -498,7 +498,8 @@ void IosConfigurations::loadProvisioningData(bool notify) } const QDir provisioningProflesDir(provisioningProfileDirPath); - foreach (QFileInfo fileInfo, provisioningProflesDir.entryInfoList({"*.mobileprovision"}, QDir::NoDotAndDotDot | QDir::Files)) { + const QStringList filters = {"*.mobileprovision"}; + foreach (QFileInfo fileInfo, provisioningProflesDir.entryInfoList(filters, QDir::NoDotAndDotDot | QDir::Files)) { QDomDocument provisioningDoc; auto profile = std::make_shared(); QString teamID; diff --git a/src/plugins/modeleditor/modelindexer.cpp b/src/plugins/modeleditor/modelindexer.cpp index 049352b5370..2c8a5d85f36 100644 --- a/src/plugins/modeleditor/modelindexer.cpp +++ b/src/plugins/modeleditor/modelindexer.cpp @@ -382,6 +382,9 @@ void ModelIndexer::onProjectFileListChanged(ProjectExplorer::Project *project) void ModelIndexer::scanProject(ProjectExplorer::Project *project) { + if (!project->rootProjectNode()) + return; + // TODO harmonize following code with findFirstModel()? QStringList files = project->files(ProjectExplorer::Project::SourceFiles); QQueue filesQueue; diff --git a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp index c66be6cc4b2..c9ecff28a9c 100644 --- a/src/plugins/projectexplorer/abstractmsvctoolchain.cpp +++ b/src/plugins/projectexplorer/abstractmsvctoolchain.cpp @@ -270,23 +270,10 @@ bool AbstractMsvcToolChain::canClone() const } // Function must be thread-safe! -QByteArray AbstractMsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags, - const Utils::Environment& env) const +QByteArray AbstractMsvcToolChain::msvcPredefinedMacros(const QStringList, + const Utils::Environment&) const { - Q_UNUSED(cxxflags); - Q_UNUSED(env); - - static const QByteArray predefinedMacros( - "#define __MSVCRT__\n" - "#define __w64\n" - "#define __int64 long long\n" - "#define __int32 long\n" - "#define __int16 short\n" - "#define __int8 char\n" - "#define __ptr32\n" - "#define __ptr64\n"); - - return predefinedMacros; + return QByteArray(); } bool AbstractMsvcToolChain::generateEnvironmentSettings(const Utils::Environment &env, diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 1c6328ad46a..86c3b32c1e4 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -260,22 +260,85 @@ static QString generateDisplayName(const QString &name, static QByteArray msvcCompilationFile() { - static const char* macros[] = {"_ATL_VER", "_CHAR_UNSIGNED", "__CLR_VER", - "__cplusplus_cli", "__COUNTER__", "__cplusplus", - "_CPPLIB_VER", "_CPPRTTI", "_CPPUNWIND", - "_DEBUG", "_DLL", "__FUNCDNAME__", - "__FUNCSIG__", "__FUNCTION__", "_INTEGRAL_MAX_BITS", - "_M_ALPHA", "_M_AAMD64", "_M_CEE", "_M_CEE_PURE", - "_M_CEE_SAFE", "_M_IX86", "_M_IA64", - "_M_IX86_FP", "_M_MPPC", "_M_MRX000", - "_M_PPC", "_M_X64", "_MANAGED", - "_MFC_VER", "_MSC_BUILD", "_MSC_EXTENSIONS", - "_MSC_FULL_VER", "_MSC_VER", "__MSVC_RUNTIME_CHECKS", - "_MT", "_NATIVE_WCHAR_T_DEFINED", "_OPENMP", - "_VC_NODEFAULTLIB", "_WCHAR_T_DEFINED", "_WIN32", - "_WIN32_WCE", "_WIN64", "_Wp64", - "__DATE__", "__TIME__", "__TIMESTAMP__", - 0}; + static const char* macros[] = { + "_ATL_VER", + "__ATOM__", + "__AVX__", + "__AVX2__", + "_CHAR_UNSIGNED", + "__CLR_VER", + "_CMMN_INTRIN_FUNC", + "_CONTROL_FLOW_GUARD", + "__COUNTER__", + "__cplusplus", + "__cplusplus_cli", + "__cplusplus_winrt", + "_CPPLIB_VER", + "_CPPRTTI", + "_CPPUNWIND", + "__DATE__", + "_DEBUG", + "_DLL", + "__FILE__", + "__func__", + "__FUNCDNAME__", + "__FUNCSIG__", + "__FUNCTION__", + "_INTEGRAL_MAX_BITS", + "__INTELLISENSE__", + "_ISO_VOLATILE", + "_KERNEL_MODE", + "__LINE__", + "_M_AAMD64", + "_M_ALPHA", + "_M_AMD64", + "_MANAGED", + "_M_ARM", + "_M_ARM64", + "_M_ARM_ARMV7VE", + "_M_ARM_FP", + "_M_ARM_NT", + "_M_ARMT", + "_M_CEE", + "_M_CEE_PURE", + "_M_CEE_SAFE", + "_MFC_VER", + "_M_FP_EXCEPT", + "_M_FP_FAST", + "_M_FP_PRECISE", + "_M_FP_STRICT", + "_M_IA64", + "_M_IX86", + "_M_IX86_FP", + "_M_MPPC", + "_M_MRX000", + "_M_PPC", + "_MSC_BUILD", + "_MSC_EXTENSIONS", + "_MSC_FULL_VER", + "_MSC_VER", + "_MSVC_LANG", + "__MSVC_RUNTIME_CHECKS", + "_MT", + "_M_THUMB", + "_M_X64", + "_NATIVE_WCHAR_T_DEFINED", + "_OPENMP", + "_PREFAST_", + "__STDC__", + "__STDC_HOSTED__", + "__STDCPP_THREADS__", + "__TIME__", + "__TIMESTAMP__", + "_VC_NODEFAULTLIB", + "_WCHAR_T_DEFINED", + "_WIN32", + "_WIN32_WCE", + "_WIN64", + "_WINRT_DLL", + "_Wp64", + 0 + }; QByteArray file = "#define __PPOUT__(x) V##x=x\n\n"; for (int i = 0; macros[i] != 0; ++i) { const QByteArray macro(macros[i]); @@ -287,11 +350,66 @@ static QByteArray msvcCompilationFile() } // Run MSVC 'cl' compiler to obtain #defines. -// Function must be thread-safe! +// This function must be thread-safe! +// +// Some notes regarding the used approach: +// +// It seems that there is no reliable way to get all the +// predefined macros for a cl invocation. The following two +// approaches are unfortunately limited since both lead to an +// incomplete list of actually predefined macros and come with +// other problems, too. +// +// 1) Maintain a list of predefined macros from the official +// documentation (for MSVC2015, e.g. [1]). Feed cl with a +// temporary file that queries the values of those macros. +// +// Problems: +// * Maintaining that list. +// * The documentation is incomplete, we do not get all +// predefined macros. E.g. the cl from MSVC2015, set up +// with "vcvars.bat x86_arm", predefines among others +// _M_ARMT, but that's not reflected in the +// documentation. +// +// 2) Run cl with the undocumented options /B1 and /Bx, as +// described in [2]. +// +// Note: With qmake from Qt >= 5.8 it's possible to print +// the macros formatted as preprocessor code in an easy to +// read/compare/diff way: +// +// > cl /nologo /c /TC /B1 qmake NUL +// > cl /nologo /c /TP /Bx qmake NUL +// +// Problems: +// * Using undocumented options. +// * Resulting macros are incomplete. +// For example, the nowadays default option /Zc:wchar_t +// predefines _WCHAR_T_DEFINED, but this is not reflected +// with this approach. +// +// To work around this we would need extra cl invocations +// to get the actual values of the missing macros +// (approach 1). +// +// Currently we combine both approaches in this way: +// * As base, maintain the list from the documentation and +// update it once a new MSVC version is released. +// * Enrich it with macros that we discover with approach 2 +// once a new MSVC version is released. +// * Enrich it further with macros that are not covered with +// the above points. +// +// TODO: Update the predefined macros for MSVC 2017 once the +// page exists. +// +// [1] https://msdn.microsoft.com/en-us/library/b0084kay.aspx +// [2] http://stackoverflow.com/questions/3665537/how-to-find-out-cl-exes-built-in-macros QByteArray MsvcToolChain::msvcPredefinedMacros(const QStringList cxxflags, const Utils::Environment &env) const { - QByteArray predefinedMacros = AbstractMsvcToolChain::msvcPredefinedMacros(cxxflags, env); + QByteArray predefinedMacros; QStringList toProcess; foreach (const QString &arg, cxxflags) { diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 6c97502dd6b..43870201dbd 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -419,7 +419,7 @@ void Project::setDocument(Core::IDocument *doc) d->m_document = doc; if (!d->m_rootProjectNode) { - auto newRoot = new ProjectNode(projectFilePath()); + auto newRoot = new ProjectNode(projectDirectory()); newRoot->setDisplayName(displayName()); newRoot->addNode(new FileNode(projectFilePath(), FileType::Project, false)); setRootProjectNode(newRoot); diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index 5645909cbb5..1a362da0c52 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -124,7 +124,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const case Qt::FontRole: { QFont font; if (Project *project = SessionManager::startupProject()) { - if (node == project->rootProjectNode()) + if (node == SessionManager::nodeForProject(project)) font.setBold(true); } result = font; @@ -227,7 +227,7 @@ ExpandData FlatModel::expandDataForNode(const Node *node) const void FlatModel::handleProjectAdded(Project *project) { - Node *node = project->rootProjectNode(); + Node *node = SessionManager::nodeForProject(project); m_toExpand.insert(expandDataForNode(node)); if (WrapperNode *wrapper = wrapperForNode(node)) { wrapper->forFirstLevelChildren([this](WrapperNode *child) { diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 413d722bd2b..b9491687c21 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -637,6 +637,7 @@ FolderNode::AddNewInformation FolderNode::addNewInformation(const QStringList &f void FolderNode::addNode(Node *node) { + QTC_ASSERT(node, return); QTC_ASSERT(!node->parentFolderNode(), qDebug("File node has already a parent folder")); node->setParentFolderNode(this); m_nodes.append(node); diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index 3cc54c2dcc9..6efdea90190 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -680,6 +680,15 @@ Project *SessionManager::projectForNode(Node *node) return nullptr; } +Node *SessionManager::nodeForProject(Project *project) +{ + for (const QPair &pair : d->m_projects) { + if (pair.first == project) + return pair.second; + } + return nullptr; +} + Project *SessionManager::projectForFile(const Utils::FileName &fileName) { const QList &projectList = projects(); diff --git a/src/plugins/projectexplorer/session.h b/src/plugins/projectexplorer/session.h index b97f297ff2d..c654efc615e 100644 --- a/src/plugins/projectexplorer/session.h +++ b/src/plugins/projectexplorer/session.h @@ -116,6 +116,7 @@ public: static SessionNode *sessionNode(); static Project *projectForNode(Node *node); + static Node *nodeForProject(Project *project); static Node *nodeForFile(const Utils::FileName &fileName); static Project *projectForFile(const Utils::FileName &fileName); diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp index 65b060572b9..88c6b3f78a2 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp @@ -442,7 +442,8 @@ QmakeProFileNode *DesktopQmakeRunConfiguration::projectNode() const QmakeProject *project = qmakeProject(); QTC_ASSERT(project, return nullptr); QmakeProFileNode *rootNode = project->rootProjectNode(); - QTC_ASSERT(rootNode, return nullptr); + if (!rootNode) + return nullptr; return rootNode->findProFileFor(m_proFilePath); } diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index 67878b23570..89f6039dd6e 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -69,10 +69,10 @@ public: QmakeProFileNode *proFileNode() const; protected: - QmakeProject *m_project; + QmakeProject *m_project = nullptr; private: - QmakeProFileNode *m_qmakeProFileNode; + QmakeProFileNode *m_qmakeProFileNode = nullptr; }; // Implements ProjectNode for qmake .pro files diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 3c7df4302d6..add833f5b18 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -37,17 +37,17 @@ #include #include #include -#include -#include -#include -#include -#include #include #include +#include +#include #include #include +#include +#include +#include #include namespace QmlDesigner { @@ -81,6 +81,14 @@ void FormEditorView::modelAttached(Model *model) setupFormEditorItemTree(rootModelNode()); m_formEditorWidget->updateActions(); + + if (!rewriterView()->errors().isEmpty()) + formEditorWidget()->showErrorMessageBox(rewriterView()->errors()); + else + formEditorWidget()->hideErrorMessageBox(); + + if (!rewriterView()->warnings().isEmpty()) + formEditorWidget()->showWarningMessageBox(rewriterView()->warnings()); } diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp index 60ee35a922d..c4b120c97b5 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp @@ -114,6 +114,10 @@ void TextEditorView::modelAttached(Model *model) void TextEditorView::modelAboutToBeDetached(Model *model) { AbstractView::modelAboutToBeDetached(model); + + m_widget->setTextEditor(0); + + QmlDesignerPlugin::instance()->emitCurrentTextEditorChanged(QmlDesignerPlugin::instance()->currentDesignDocument()->textEditor()); } void TextEditorView::importsChanged(const QList &/*addedImports*/, const QList &/*removedImports*/) diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp index e645ad2ef6a..b7f20e77a2f 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp @@ -68,21 +68,24 @@ void TextEditorWidget::setTextEditor(TextEditor::BaseTextEditor *textEditor) { TextEditor::BaseTextEditor *oldEditor = m_textEditor.release(); m_textEditor.reset(textEditor); - layout()->removeWidget(m_statusBar); - layout()->addWidget(textEditor->editorWidget()); - layout()->addWidget(m_statusBar); - setFocusProxy(textEditor->editorWidget()); - QmlDesignerPlugin::instance()->emitCurrentTextEditorChanged(textEditor); + if (textEditor) { + layout()->removeWidget(m_statusBar); + layout()->addWidget(textEditor->editorWidget()); + layout()->addWidget(m_statusBar); + setFocusProxy(textEditor->editorWidget()); - connect(textEditor->editorWidget(), &QPlainTextEdit::cursorPositionChanged, - this, [this]() { - /* Cursor position is changed by rewriter */ - if (!m_blockCurserSelectionSyncronisation) - m_updateSelectionTimer.start(); - }); + QmlDesignerPlugin::instance()->emitCurrentTextEditorChanged(textEditor); - textEditor->editorWidget()->installEventFilter(this); + connect(textEditor->editorWidget(), &QPlainTextEdit::cursorPositionChanged, + this, [this]() { + /* Cursor position is changed by rewriter */ + if (!m_blockCurserSelectionSyncronisation) + m_updateSelectionTimer.start(); + }); + + textEditor->editorWidget()->installEventFilter(this); + } if (oldEditor) oldEditor->deleteLater(); @@ -113,6 +116,12 @@ void TextEditorWidget::jumpTextCursorToSelectedModelNode() { ModelNode selectedNode; + if (hasFocus()) + return; + + if (m_textEditor && m_textEditor->editorWidget()->hasFocus()) + return; + if (!m_textEditorView->selectedModelNodes().isEmpty()) selectedNode = m_textEditorView->selectedModelNodes().first(); diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index bddac451ca9..77f61b2d5fd 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -371,6 +371,8 @@ bool itemIsMovable(const ModelNode &modelNode) if (modelNode.metaInfo().isSubclassOf("QtQuick.Controls.Tab")) return false; + if (!modelNode.parentProperty().isNodeListProperty()) + return false; return NodeHints::fromModelNode(modelNode).isMovable(); } diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index e5f2bc23385..c1a48b95ad7 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -283,16 +283,15 @@ void QmlDesignerPlugin::integrateIntoQtCreator(QWidget *modeWidget) if (d && currentEditor && checkIfEditorIsQtQuick(currentEditor) && !documentIsAlreadyOpen(currentDesignDocument(), currentEditor, newMode)) { - if (!isDesignerMode(newMode) && isDesignerMode(oldMode)) - hideDesigner(); - else if (currentEditor && isDesignerMode(newMode)) + if (isDesignerMode(newMode)) { showDesigner(); - else if (currentDesignDocument()) - hideDesigner(); + } else if (currentDesignDocument() || + (!isDesignerMode(newMode) && isDesignerMode(oldMode))) { + hideDesigner(); + } } }); - d->viewManager.designerActionManager().polishActions(); } diff --git a/src/plugins/qmlprofiler/qmlprofilertextmark.cpp b/src/plugins/qmlprofiler/qmlprofilertextmark.cpp index 5cdcaeb183b..3060c8f1400 100644 --- a/src/plugins/qmlprofiler/qmlprofilertextmark.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertextmark.cpp @@ -33,10 +33,9 @@ namespace Internal { QmlProfilerTextMark::QmlProfilerTextMark(QmlProfilerTool *tool, int typeId, const QString &fileName, int lineNumber) : - TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY), m_tool(tool), + TextMark(fileName, lineNumber, Constants::TEXT_MARK_CATEGORY, 3.5), m_tool(tool), m_typeIds(1, typeId) { - setWidthFactor(3.5); } void QmlProfilerTextMark::addTypeId(int typeId) diff --git a/src/plugins/silversearcher/silversearcherplugin.cpp b/src/plugins/silversearcher/silversearcherplugin.cpp index 80b5b0edc77..7b26ddd4f96 100644 --- a/src/plugins/silversearcher/silversearcherplugin.cpp +++ b/src/plugins/silversearcher/silversearcherplugin.cpp @@ -44,10 +44,11 @@ void SilverSearcherPlugin::extensionsInitialized() { } +#ifdef WITH_TESTS QList SilverSearcherPlugin::createTestObjects() const { return {new OutputParserTest}; } - +#endif } // namespace Internal } // namespace SilverSearcher diff --git a/src/plugins/silversearcher/silversearcherplugin.h b/src/plugins/silversearcher/silversearcherplugin.h index 5c3df4ea682..4ff3246dad7 100644 --- a/src/plugins/silversearcher/silversearcherplugin.h +++ b/src/plugins/silversearcher/silversearcherplugin.h @@ -36,8 +36,8 @@ class SilverSearcherPlugin : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "SilverSearcher.json") public: - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) override; + void extensionsInitialized() override; #ifdef WITH_TESTS private: QList createTestObjects() const override; diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp index dea5ca70c01..286cd2af41d 100644 --- a/src/plugins/texteditor/textmark.cpp +++ b/src/plugins/texteditor/textmark.cpp @@ -41,14 +41,14 @@ using namespace TextEditor::Internal; namespace TextEditor { -TextMark::TextMark(const QString &fileName, int lineNumber, Id category) +TextMark::TextMark(const QString &fileName, int lineNumber, Id category, double widthFactor) : m_baseTextDocument(0), m_fileName(fileName), m_lineNumber(lineNumber), m_priority(NormalPriority), m_visible(true), m_category(category), - m_widthFactor(1.0) + m_widthFactor(widthFactor) { if (!m_fileName.isEmpty()) TextEditorPlugin::baseTextMarkRegistry()->add(this); diff --git a/src/plugins/texteditor/textmark.h b/src/plugins/texteditor/textmark.h index 0aebe697606..1eec26d17ac 100644 --- a/src/plugins/texteditor/textmark.h +++ b/src/plugins/texteditor/textmark.h @@ -50,7 +50,7 @@ namespace Internal { class TextMarkRegistry; } class TEXTEDITOR_EXPORT TextMark { public: - TextMark(const QString &fileName, int lineNumber, Core::Id category); + TextMark(const QString &fileName, int lineNumber, Core::Id category, double widthFactor = 1.0); virtual ~TextMark(); // determine order on markers on the same line. diff --git a/src/plugins/valgrind/callgrindtextmark.cpp b/src/plugins/valgrind/callgrindtextmark.cpp index 5a8ed43ebd3..cfd19c7a0ce 100644 --- a/src/plugins/valgrind/callgrindtextmark.cpp +++ b/src/plugins/valgrind/callgrindtextmark.cpp @@ -42,11 +42,10 @@ namespace Constants { const char CALLGRIND_TEXT_MARK_CATEGORY[] = "Callgrind.Tex CallgrindTextMark::CallgrindTextMark(const QPersistentModelIndex &index, const QString &fileName, int lineNumber) - : TextEditor::TextMark(fileName, lineNumber, Constants::CALLGRIND_TEXT_MARK_CATEGORY) + : TextEditor::TextMark(fileName, lineNumber, Constants::CALLGRIND_TEXT_MARK_CATEGORY, 4.0) , m_modelIndex(index) { setPriority(TextEditor::TextMark::HighPriority); - setWidthFactor(4.0); } void CallgrindTextMark::paint(QPainter *painter, const QRect &paintRect) const diff --git a/src/tools/sdktool/addtoolchainoperation.cpp b/src/tools/sdktool/addtoolchainoperation.cpp index ee31311dd6b..60aba4558d3 100644 --- a/src/tools/sdktool/addtoolchainoperation.cpp +++ b/src/tools/sdktool/addtoolchainoperation.cpp @@ -47,6 +47,7 @@ const char ID[] = "ProjectExplorer.ToolChain.Id"; const char DISPLAYNAME[] = "ProjectExplorer.ToolChain.DisplayName"; const char AUTODETECTED[] = "ProjectExplorer.ToolChain.Autodetect"; const char LANGUAGE_KEY[] = "ProjectExplorer.ToolChain.Language"; +const char LANGUAGE_KEY_V2[] = "ProjectExplorer.ToolChain.LanguageV2"; // GCC ToolChain: const char PATH[] = "ProjectExplorer.GccToolChain.Path"; @@ -265,7 +266,30 @@ QVariantMap AddToolChainOperation::addToolChain(const QVariantMap &map, const QS KeyValuePairList data; data << KeyValuePair({tc, ID}, QVariant(id)); - data << KeyValuePair({tc, LANGUAGE_KEY}, QVariant(lang)); + + // Language compatibility hack for 4.2: + QString newLang; // QtC 4.3 and later + QString oldLang; // QtC 4.2 + int langInt = lang.toInt(&ok); + Q_UNUSED(langInt); + if (lang == "2" || lang == "Cxx") { + newLang = "Cxx"; + oldLang = "2"; + } else if (lang == "1" || lang == "C") { + newLang = "C"; + oldLang = "1"; + } else if (ok) { + std::cerr << "Error: Language ID must be 1 for C, 2 for Cxx " + << "or a string like (\"C\", \"Cxx\", \"Nim\", etc.)" << std::endl; + return {}; + } else if (!ok) { + newLang = lang; + oldLang = ""; + } + if (!oldLang.isEmpty()) + data << KeyValuePair({tc, LANGUAGE_KEY}, QVariant(oldLang)); + if (!newLang.isEmpty()) + data << KeyValuePair({tc, LANGUAGE_KEY_V2}, QVariant(newLang)); data << KeyValuePair({tc, DISPLAYNAME}, QVariant(uniqueName)); data << KeyValuePair({tc, AUTODETECTED}, QVariant(true)); data << KeyValuePair({tc, PATH}, QVariant(path)); diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 00d2bc05f4b..eb3fa0dd5f4 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -2723,7 +2723,8 @@ void tst_Dumpers::dumper_data() + Check("ob", "\"An Object\"", "@QWidget") + Check("ob1", "\"Another Object\"", "@QObject") - + Check("ob2", "\"A Subobject\"", "@QObject"); + + Check("ob2", "\"A Subobject\"", "@QObject") + + Check("ob.[extra].[connections].0.0.receiver", "\"Another Object\"", "@QObject"); QString senderData =