diff --git a/CMakeLists.txt b/CMakeLists.txt index c7947d6082b..5067c46ebd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,37 +164,14 @@ endif() add_subdirectory(doc) -find_package(Python3 COMPONENTS Interpreter) -if (NOT Python3_Interpreter_FOUND) - message("No python interpreter found, skipping \"Dependencies\" install component.") -else() - get_target_property(_qmake_binary Qt5::qmake IMPORTED_LOCATION) - set(_llvm_arg) - if (LLVM_INSTALL_PREFIX) - set(_llvm_arg "--llvm \"${LLVM_INSTALL_PREFIX}\"") - endif() - set(_elfutils_arg) - if (ELFUTILS_INCLUDE_DIR) - get_filename_component(_elfutils_path ${ELFUTILS_INCLUDE_DIR} DIRECTORY) - set(_elfutils_arg "--elfutils \"${_elfutils_path}\"") - endif() - install(CODE " - execute_process(COMMAND - \"${Python3_EXECUTABLE}\" - \"${CMAKE_CURRENT_LIST_DIR}/scripts/deployqt.py\" - ${_llvm_arg} - ${_elfutils_arg} - \"\${CMAKE_INSTALL_PREFIX}/${IDE_APP_PATH}/${IDE_APP_TARGET}\" - \"${_qmake_binary}\" - COMMAND_ECHO STDOUT - ) - " - COMPONENT Dependencies - EXCLUDE_FROM_ALL - ) -endif() +setup_dependencies_component() feature_summary(INCLUDE_QUIET_PACKAGES WHAT PACKAGES_FOUND PACKAGES_NOT_FOUND ENABLED_FEATURES DISABLED_FEATURES ) + +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + # Only for non super repo builds + add_subdirectory(packaging) +endif() diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake index 0b0670b267f..363c78ddaf5 100644 --- a/cmake/Utils.cmake +++ b/cmake/Utils.cmake @@ -5,3 +5,46 @@ function (env_with_default envName varToSet default) set(${varToSet} ${default} PARENT_SCOPE) endif() endfunction() + +function(setup_dependencies_component) + find_package(Python3 COMPONENTS Interpreter) + if (NOT Python3_Interpreter_FOUND) + message("No python interpreter found, skipping \"Dependencies\" install component.") + else() + get_target_property(_qmake_binary Qt5::qmake IMPORTED_LOCATION) + set(_llvm_arg) + if (LLVM_INSTALL_PREFIX) + set(_llvm_arg "--llvm \"${LLVM_INSTALL_PREFIX}\"") + endif() + set(_elfutils_arg) + if (ELFUTILS_INCLUDE_DIR) + get_filename_component(_elfutils_path ${ELFUTILS_INCLUDE_DIR} DIRECTORY) + set(_elfutils_arg "--elfutils \"${_elfutils_path}\"") + endif() + install(CODE " + set(_ide_app_target \"\${CMAKE_INSTALL_PREFIX}/${IDE_APP_PATH}/${IDE_APP_TARGET}${CMAKE_EXECUTABLE_SUFFIX}\") + if (NOT EXISTS \"\${_ide_app_target}\") + # The component CPack generators (WIX, NSIS64, IFW) install every component with their own CMAKE_INSTALL_PREFIX + # directory and since deployqt.py needs the path to IDE_APP_TARGET the line below is needeed + string(REPLACE \"Dependencies\" \"${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}\" _ide_app_target \"\${_ide_app_target}\") + endif() + if (NOT EXISTS \"\${_ide_app_target}\") + # On Linux with the DEB generator the CMAKE_INSTALL_PREFIX is relative and the DESTDIR environment variable is needed + # to point out to the IDE_APP_TARGET binary + set(_ide_app_target \"\$ENV{DESTDIR}/\${CMAKE_INSTALL_PREFIX}/${IDE_APP_PATH}/${IDE_APP_TARGET}${CMAKE_EXECUTABLE_SUFFIX}\") + endif() + execute_process(COMMAND + \"${Python3_EXECUTABLE}\" + \"${CMAKE_CURRENT_LIST_DIR}/scripts/deployqt.py\" + ${_llvm_arg} + ${_elfutils_arg} + \"\${_ide_app_target}\" + \"${_qmake_binary}\" + COMMAND_ECHO STDOUT + ) + " + COMPONENT Dependencies + EXCLUDE_FROM_ALL + ) + endif() +endfunction() diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt new file mode 100644 index 00000000000..ef89687621c --- /dev/null +++ b/packaging/CMakeLists.txt @@ -0,0 +1,70 @@ +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/QtCreatorIDEBranding.cmake) + +set(CPACK_PACKAGE_NAME ${IDE_CASED_ID}) +set(CPACK_PACKAGE_VENDOR "The Qt Company Ltd") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${IDE_DISPLAY_NAME}) +set(CPACK_PACKAGE_INSTALL_DIRECTORY ${IDE_ID}) +set(CPACK_VERBATIM_VARIABLES YES) + +#set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_LIST_DIR}/Description.txt) +#set(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_CURRENT_LIST_DIR}/Welcome.txt) +#set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_LIST_DIR}/Readme.txt) + +# WIX needs a license file ending with .txt +file(CREATE_LINK + ${CMAKE_CURRENT_LIST_DIR}/../LICENSE.GPL3-EXCEPT + ${CMAKE_CURRENT_BINARY_DIR}/LICENSE.GPL3-EXCEPT.txt + COPY_ON_ERROR) +set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_BINARY_DIR}/LICENSE.GPL3-EXCEPT.txt) + +set(CPACK_PACKAGE_CONTACT "None") +set(CPACK_THREADS 4) +set(CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR}) +set(CPACK_DEBIAN_COMPRESSION_TYPE lzma) + +# Make CMAKE_INSTALL_DEFAULT_COMPONENT_NAME the first component to install +get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS) +list(REMOVE_ITEM CPACK_COMPONENTS_ALL ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}) +list(REMOVE_ITEM CPACK_COMPONENTS_ALL libraries) # empty component, breaks WIX +list(PREPEND CPACK_COMPONENTS_ALL ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}) + +set(CPACK_COMPONENT_Dependencies_HIDDEN TRUE) + +if (APPLE) + set(CPACK_INSTALL_PREFIX "/") +endif() + +if (WIN32) + set(CPACK_PACKAGE_INSTALL_DIRECTORY ${IDE_ID}-${CMAKE_PROJECT_VERSION}) +else() + set(CPACK_SET_DESTDIR ON) + set(CPACK_STRIP_FILES ON) + + if (NOT APPLE) + set(CPACK_INSTALL_CMAKE_PROJECTS + "${CMAKE_BINARY_DIR};${IDE_CASED_ID};ALL;/" + "${CMAKE_BINARY_DIR};Dependencies;Dependencies;/" + ) + endif() +endif() + +# NSIS-specific configuration +set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_LIST_DIR}/../src/app/qtcreator.ico") +set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_LIST_DIR}/../src/app/qtcreator.ico") +set(CPACK_NSIS_INSTALLED_ICON_NAME "${IDE_APP_PATH}\\${IDE_APP_TARGET}.exe") +set(CPACK_NSIS_DISPLAY_NAME "${IDE_DISPLAY_NAME} ${CMAKE_PROJECT_VERSION}") +set(CPACK_NSIS_PACKAGE_NAME "${IDE_DISPLAY_NAME} ${CMAKE_PROJECT_VERSION}") +set(CPACK_NSIS_COMPRESSOR "/SOLID lzma\n SetCompressorDictSize 64") +set(CPACK_NSIS_INSTALL_ROOT "C:\\Qt") +set(CPACK_NSIS_MUI_FINISHPAGE_RUN "${IDE_APP_TARGET}") +set(CPACK_NSIS_CREATE_ICONS_EXTRA + "CreateShortCut '$SMPROGRAMS\\$STARTMENU_FOLDER\\${IDE_DISPLAY_NAME} ${CMAKE_PROJECT_VERSION}.lnk' '$INSTDIR\\${IDE_APP_PATH}\\${IDE_APP_TARGET}.exe' " +) +set(CPACK_NSIS_MANIFEST_DPI_AWARE ON) + +# WIX-specific configuration +set(CPACK_WIX_PRODUCT_ICON "${CMAKE_CURRENT_LIST_DIR}/../src/app/qtcreator.ico") +set(CPACK_WIX_UPGRADE_GUID "E6A093A5-83DE-47FA-B669-1DE0102BE92A") +set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-dcl:high") # set high compression + +include(CPack) diff --git a/scripts/scrubts.py b/scripts/scrubts.py index a31ef1109ab..9a863970b67 100644 --- a/scripts/scrubts.py +++ b/scripts/scrubts.py @@ -12,6 +12,7 @@ import argparse import pathlib import sys from dataclasses import dataclass +from enum import Enum, auto def rewriteLines(input, scrubbedContext, tsFilePath): result = [] @@ -94,19 +95,46 @@ def findDistinctDuplicates(input, scrubbedContext, tsFilePath): continue if inContext: sourceXml = [] - lineNr = inputLineNr - for sourceLine in lineIter: # .. (possibly multi-line) - inputLineNr += 1 - sourceXml.append(sourceLine) - if sourceLine.count(r"") == 1: - break - sourceXmlHash = hash(str(sourceXml)) translationXml = [] - for translationLine in lineIter: # .. (possibly multi-line) + lineNr = inputLineNr + + class Position(Enum): + MESSAGESTART = auto() + LOCATION = auto() + SOURCE = auto() + COMMENT = auto() + EXTRACOMMENT = auto() + TRANSLATORCOMMENT = auto() + TRANSLATION = auto() + MESSAGEOVER = auto() + + pos = Position.MESSAGESTART + + for messageLine in lineIter: inputLineNr += 1 - translationXml.append(translationLine) - if translationLine.count(r"") == 1: + if messageLine.count(r"") == 1: + pos = Position.MESSAGEOVER + + if pos == Position.SOURCE or pos == Position.COMMENT: + sourceXml.append(messageLine) + elif pos == Position.TRANSLATION or pos == Position.EXTRACOMMENT or pos == Position.TRANSLATORCOMMENT: + translationXml.append(messageLine) + elif pos == Position.MESSAGEOVER: break + + sourceXmlHash = hash(str(sourceXml)) translation = Translation(lineNr, translationXml) if sourceXmlHash in messages: messages[sourceXmlHash].translations.append(translation) @@ -117,13 +145,14 @@ def findDistinctDuplicates(input, scrubbedContext, tsFilePath): source = messages[sourceId] translationsCount = len(source.translations) if translationsCount > 1: + print (f"\n==========================================") print (f"\n{translationsCount} duplicates for source:") for sourceXmlLine in source.sourceXml: - print (sourceXmlLine.rstrip()) + print (sourceXmlLine.rstrip()) for translation in source.translations: print (f"\n{tsFilePath}:{translation.lineNr}") for translationXmlLine in translation.translationXml: - print (translationXmlLine.rstrip()) + print (translationXmlLine.rstrip()) def processTsFile(tsFilePath, scrubbedContext): diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index b791139199d..173b5a60111 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -162,13 +162,11 @@ class Dumper(DumperBase): return self.createArrayType(targetType, nativeType.arrayElements()) code = TypeCode.Struct - tdata = self.TypeData(self) + tdata = self.TypeData(self, typeId) tdata.name = nativeType.name() - tdata.typeId = typeId tdata.lbitsize = nativeType.bitsize() tdata.code = code tdata.moduleName = nativeType.module() - self.registerType(typeId, tdata) # Prevent recursion in fields. if code == TypeCode.Struct: tdata.lfields = lambda value: \ self.listFields(nativeType, value) @@ -179,7 +177,6 @@ class Dumper(DumperBase): self.nativeTypeEnumDisplay(nativeType, intval, form) tdata.templateArguments = lambda: \ self.listTemplateParameters(nativeType.name()) - self.registerType(typeId, tdata) # Fix up fields and template args return self.Type(self, typeId) def listFields(self, nativeType, value): @@ -388,8 +385,8 @@ class Dumper(DumperBase): if nativeType is None: return None _type = self.fromNativeType(nativeType) - if _type.name != typeName: - self.registerType(typeName, _type.tdata) + if _type.typeId != typeName: + self.registerTypeAlias(_type.typeId, typeName) return _type return self.Type(self, typeName) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index ff3783f3c90..22f3f732d87 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -422,24 +422,18 @@ class DumperBase(): return None if nativeType is None else self.fromNativeType(nativeType) def registerKnownTypes(self): - typeId = 'unsigned short' - tdata = self.TypeData(self) - tdata.name = typeId - tdata.typeId = typeId + tdata = self.TypeData(self, 'unsigned short') tdata.lbitsize = 16 + tdata.lalignment = 2 tdata.code = TypeCode.Integral - self.registerType(typeId, tdata) - typeId = 'QChar' - tdata = self.TypeData(self) - tdata.name = typeId - tdata.typeId = typeId + tdata = self.TypeData(self, 'QChar') tdata.lbitsize = 16 + tdata.lalignment = 2 tdata.code = TypeCode.Struct tdata.lfields = [self.Field(dumper=self, name='ucs', type='unsigned short', bitsize=16, bitpos=0)] - tdata.lalignment = 2 - self.registerType(typeId, tdata) + tdata.templateArguments = lambda: [] def nativeDynamicType(self, address, baseType): return baseType # Override in backends. @@ -3462,19 +3456,12 @@ class DumperBase(): item_count = type_name[pos1 + 1:pos2] return (type_name[0:pos1].strip(), type_name[pos2 + 1:].strip(), int(item_count)) - def registerType(self, typeId, tdata): - #DumperBase.warn('REGISTER TYPE: %s' % typeId) - self.typeData[typeId] = tdata - #typeId = typeId.replace(' ', '') - #self.typeData[typeId] = tdata - #DumperBase.warn('REGISTERED: %s' % self.typeData) - def registerTypeAlias(self, existingTypeId, aliasId): #DumperBase.warn('REGISTER ALIAS %s FOR %s' % (aliasId, existingTypeId)) self.typeData[aliasId] = self.typeData[existingTypeId] class TypeData(): - def __init__(self, dumper): + def __init__(self, dumper, type_id): self.dumper = dumper self.lfields = None # None or Value -> list of member Values self.lalignment = None # Function returning alignment of this struct @@ -3482,13 +3469,15 @@ class DumperBase(): self.ltarget = None # Inner type for arrays self.templateArguments = None self.code = None - self.name = None - self.typeId = None + self.name = type_id + self.typeId = type_id self.enumDisplay = None self.moduleName = None + #DumperBase.warn('REGISTER TYPE: %s' % type_id) + dumper.typeData[type_id] = self def copy(self): - tdata = self.dumper.TypeData(self.dumper) + tdata = self.dumper.TypeData(self.dumper, self.typeId) tdata.dumper = self.dumper tdata.lfields = self.lfields tdata.lalignment = self.lalignment @@ -3791,13 +3780,11 @@ class DumperBase(): raise RuntimeError('Expected type in createPointerType(), got %s' % type(targetType)) typeId = targetType.typeId + ' *' - tdata = self.TypeData(self) + tdata = self.TypeData(self, typeId) tdata.name = targetType.name + '*' - tdata.typeId = typeId tdata.lbitsize = 8 * self.ptrSize() tdata.code = TypeCode.Pointer tdata.ltarget = targetType - self.registerType(typeId, tdata) return self.Type(self, typeId) def createReferenceType(self, targetType): @@ -3805,14 +3792,12 @@ class DumperBase(): raise RuntimeError('Expected type in createReferenceType(), got %s' % type(targetType)) typeId = targetType.typeId + ' &' - tdata = self.TypeData(self) + tdata = self.TypeData(self, typeId) tdata.name = targetType.name + ' &' - tdata.typeId = typeId tdata.code = TypeCode.Reference tdata.ltarget = targetType tdata.lbitsize = 8 * self.ptrSize() # Needed for Gdb13393 test. #tdata.lbitsize = None - self.registerType(typeId, tdata) return self.Type(self, typeId) def createRValueReferenceType(self, targetType): @@ -3820,13 +3805,11 @@ class DumperBase(): raise RuntimeError('Expected type in createRValueReferenceType(), got %s' % type(targetType)) typeId = targetType.typeId + ' &&' - tdata = self.TypeData(self) + tdata = self.TypeData(self, typeId) tdata.name = targetType.name + ' &&' - tdata.typeId = typeId tdata.code = TypeCode.RValueReference tdata.ltarget = targetType tdata.lbitsize = None - self.registerType(typeId, tdata) return self.Type(self, typeId) def createArrayType(self, targetType, count): @@ -3843,13 +3826,11 @@ class DumperBase(): type_id = '%s[%d]' % (targetTypeId, count) type_name = '%s[%d]' % (targetType.name, count) - tdata = self.TypeData(self) + tdata = self.TypeData(self, type_id) tdata.name = type_name - tdata.typeId = type_id tdata.code = TypeCode.Array tdata.ltarget = targetType tdata.lbitsize = targetType.lbitsize * count - self.registerType(type_id, tdata) return self.Type(self, type_id) def createBitfieldType(self, targetType, bitsize): @@ -3857,13 +3838,11 @@ class DumperBase(): raise RuntimeError('Expected type in createBitfieldType(), got %s' % type(targetType)) typeId = '%s:%d' % (targetType.typeId, bitsize) - tdata = self.TypeData(self) + tdata = self.TypeData(self, typeId) tdata.name = '%s : %d' % (targetType.typeId, bitsize) - tdata.typeId = typeId tdata.code = TypeCode.Bitfield tdata.ltarget = targetType tdata.lbitsize = bitsize - self.registerType(typeId, tdata) return self.Type(self, typeId) def createTypedefedType(self, targetType, typeName, typeId=None): @@ -3875,15 +3854,13 @@ class DumperBase(): # Happens for C-style struct in GDB: typedef { int x; } struct S1; if targetType.typeId == typeId: return targetType - tdata = self.TypeData(self) + tdata = self.TypeData(self, typeId) tdata.name = typeName - tdata.typeId = typeId tdata.code = TypeCode.Typedef tdata.ltarget = targetType tdata.lbitsize = targetType.lbitsize #tdata.lfields = targetType.lfields tdata.lbitsize = targetType.lbitsize - self.registerType(typeId, tdata) return self.Type(self, typeId) def knownArrayTypeSize(self): @@ -3939,9 +3916,7 @@ class DumperBase(): return knownType #DumperBase.warn('FAKING: %s SIZE: %s' % (typish, size)) - tdata = self.TypeData(self) - tdata.name = typish - tdata.typeId = typish + tdata = self.TypeData(self, typish) tdata.templateArguments = lambda: self.listTemplateParameters(typish) if size is not None: tdata.lbitsize = 8 * size @@ -3950,8 +3925,7 @@ class DumperBase(): tdata.lbitsize = 8 * self.ptrSize() tdata.ltarget = self.createType(typish[:-1].strip()) - self.registerType(typish, tdata) - typeobj = self.Type(self, typish) + typeobj = self.Type(self, tdata.typeId) #DumperBase.warn('CREATE TYPE: %s' % typeobj.stringify()) typeobj.check() return typeobj @@ -3979,11 +3953,8 @@ class DumperBase(): raise RuntimeError('EXPECTING ADDRESS OR BYTES, GOT %s' % type(datish)) def createProxyValue(self, proxy_data, type_name): - tdata = self.TypeData(self) - tdata.name = type_name - tdata.typeId = type_name + tdata = self.TypeData(self, type_name) tdata.code = TypeCode.Struct - self.registerType(type_name, tdata) val = self.Value(self) val._type = self.Type(self, type_name) val.ldata = proxy_data diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 1168bce81b8..f142a30fb4a 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -367,9 +367,8 @@ class Dumper(DumperBase): typeId = self.nativeTypeId(nativeType) res = self.typeData.get(typeId, None) if res is None: - tdata = self.TypeData(self) + tdata = self.TypeData(self, typeId) tdata.name = str(nativeType) - tdata.typeId = typeId tdata.lbitsize = nativeType.sizeof * 8 tdata.code = { #gdb.TYPE_CODE_TYPEDEF : TypeCode.Typedef, # Handled above. @@ -401,7 +400,6 @@ class Dumper(DumperBase): self.listMembers(value, nativeType) tdata.templateArguments = lambda: \ self.listTemplateParameters(nativeType) - self.registerType(typeId, tdata) # Fix up fields and template args # warn('CREATE TYPE: %s' % typeId) #else: # warn('REUSE TYPE: %s' % typeId) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 25e47688ecc..032b2242211 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -434,8 +434,7 @@ class Dumper(DumperBase): if res is None: # # This strips typedefs for pointers. We don't want that. # typeobj.nativeType = nativeType.GetUnqualifiedType() - tdata = self.TypeData(self) - tdata.typeId = typeId + tdata = self.TypeData(self, typeId) tdata.name = typeName tdata.lbitsize = nativeType.GetByteSize() * 8 if code == lldb.eTypeClassBuiltin: @@ -471,8 +470,6 @@ class Dumper(DumperBase): tdata.code = TypeCode.Function elif code == lldb.eTypeClassMemberPointer: tdata.code = TypeCode.MemberPointer - - self.registerType(typeId, tdata) # Fix up fields and template args # warn('CREATE TYPE: %s' % typeId) #else: # warn('REUSE TYPE: %s' % typeId) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 39bb174f0d3..7ddd00d4ccd 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -234,14 +234,14 @@ def qdump__QStandardItem(d, value): vtable, dptr = value.split('pp') if d.qtVersion() >= 0x060000: model, parent, values, children, rows, cols, item = \ - d.split('pp{@QList<@QStandardItemData>}{@QList<@QStandardItem*>}IIp', dptr) + d.split('pp{@QList<@QStandardItemData>}{@QList<@QStandardItem *>}IIp', dptr) else: # There used to be a virtual destructor that got removed in # 88b6abcebf29b455438 on Apr 18 17:01:22 2017 if d.qtVersion() < 0x050900 and not d.isMsvcTarget(): dptr += d.ptrSize(); model, parent, values, children, rows, cols, item = \ - d.split('pp{@QVector<@QStandardItemData>}{@QVector<@QStandardItem*>}IIp', dptr) + d.split('pp{@QVector<@QStandardItemData>}{@QVector<@QStandardItem *>}IIp', dptr) d.putEmptyValue() d.putExpandable() diff --git a/src/libs/utils/fsengine/fsenginehandler.cpp b/src/libs/utils/fsengine/fsenginehandler.cpp index a7f190e1e7b..f2b649c48da 100644 --- a/src/libs/utils/fsengine/fsenginehandler.cpp +++ b/src/libs/utils/fsengine/fsenginehandler.cpp @@ -48,16 +48,15 @@ QAbstractFileEngine *FSEngineHandler::create(const QString &fileName) const return new FixedListFSEngine(rootFilePath.pathAppended(scheme), filteredRoots); } } + + FilePath filePath = FilePath::fromString(fixedFileName); + if (filePath.needsDevice()) + return new FSEngineImpl(filePath); + + if (fixedFileName.compare(QDir::rootPath(), Qt::CaseInsensitive) == 0) + return new RootInjectFSEngine(fixedFileName); } - FilePath filePath = FilePath::fromString(fixedFileName); - if (filePath.needsDevice()) - return new FSEngineImpl(filePath); - - - if (fixedFileName.compare(QDir::rootPath(), Qt::CaseInsensitive) == 0) - return new RootInjectFSEngine(fixedFileName); - return nullptr; } diff --git a/src/libs/utils/hostosinfo.h b/src/libs/utils/hostosinfo.h index 7626e3caccf..9720b2ecec1 100644 --- a/src/libs/utils/hostosinfo.h +++ b/src/libs/utils/hostosinfo.h @@ -72,12 +72,12 @@ public: : OsSpecificAspects::fileNameCaseSensitivity(hostOs()); } - static QChar pathListSeparator() + static constexpr QChar pathListSeparator() { return OsSpecificAspects::pathListSeparator(hostOs()); } - static Qt::KeyboardModifier controlModifier() + static constexpr Qt::KeyboardModifier controlModifier() { return OsSpecificAspects::controlModifier(hostOs()); } diff --git a/src/libs/utils/osspecificaspects.h b/src/libs/utils/osspecificaspects.h index 2d7b55e12d4..d5f331efdfa 100644 --- a/src/libs/utils/osspecificaspects.h +++ b/src/libs/utils/osspecificaspects.h @@ -24,22 +24,22 @@ inline QString withExecutableSuffix(OsType osType, const QString &executable) return finalName; } -inline Qt::CaseSensitivity fileNameCaseSensitivity(OsType osType) +constexpr Qt::CaseSensitivity fileNameCaseSensitivity(OsType osType) { return osType == OsTypeWindows || osType == OsTypeMac ? Qt::CaseInsensitive : Qt::CaseSensitive; } -inline Qt::CaseSensitivity envVarCaseSensitivity(OsType osType) +constexpr Qt::CaseSensitivity envVarCaseSensitivity(OsType osType) { return fileNameCaseSensitivity(osType); } -inline QChar pathListSeparator(OsType osType) +constexpr QChar pathListSeparator(OsType osType) { return QLatin1Char(osType == OsTypeWindows ? ';' : ':'); } -inline Qt::KeyboardModifier controlModifier(OsType osType) +constexpr Qt::KeyboardModifier controlModifier(OsType osType) { return osType == OsTypeMac ? Qt::MetaModifier : Qt::ControlModifier; } diff --git a/src/plugins/autotest/qtest/qttestoutputreader.cpp b/src/plugins/autotest/qtest/qttestoutputreader.cpp index a11b984dea0..a3695dcdca1 100644 --- a/src/plugins/autotest/qtest/qttestoutputreader.cpp +++ b/src/plugins/autotest/qtest/qttestoutputreader.cpp @@ -10,8 +10,6 @@ #include #include -#include -#include #include #include diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 157f907d69b..36bf395a0a8 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -63,6 +63,7 @@ #include #include +#include #include #include #include @@ -839,7 +840,7 @@ void ClangdClient::followSymbol(TextDocument *document, d->followSymbol = nullptr; const QTextCursor adjustedCursor = d->adjustedCursor(cursor, document); - if (!resolveTarget) { + if (followTo == FollowTo::SymbolDef && !resolveTarget) { symbolSupport().findLinkAt(document, adjustedCursor, callback, false); return; } @@ -1356,8 +1357,13 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc, doc = QPointer(doc), rev = doc->document()->revision(), clangdVersion = q->versionNumber(), this] { - return Utils::runAsync(doSemanticHighlighting, filePath, tokens, text, ast, doc, rev, - clangdVersion, highlightingTimer); + try { + return Utils::runAsync(doSemanticHighlighting, filePath, tokens, text, ast, doc, + rev, clangdVersion, highlightingTimer); + } catch (const std::exception &e) { + qWarning() << "caught" << e.what() << "in main highlighting thread"; + return QFuture(); + } }; if (isTesting) { diff --git a/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp b/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp index 98456d3db1c..3d989901349 100644 --- a/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp +++ b/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp @@ -19,6 +19,8 @@ #include #include +#include + using namespace LanguageClient; using namespace LanguageServerProtocol; using namespace TextEditor; @@ -345,7 +347,15 @@ void doSemanticHighlighting( return HighlightingResult(token.line, token.column, token.length, styles); }; - auto results = QtConcurrent::blockingMapped(tokens, toResult); + const auto safeToResult = [&toResult](const ExpandedSemanticToken &token) { + try { + return toResult(token); + } catch (const std::exception &e) { + qWarning() << "caught" << e.what() << "in toResult()"; + return HighlightingResult(); + } + }; + auto results = QtConcurrent::blockingMapped(tokens, safeToResult); const QList ifdefedOutBlocks = cleanupDisabledCode(results, &doc, docContents); ExtraHighlightingResultsCollector(future, results, filePath, ast, &doc, docContents, clangdVersion).collect(); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 2bcdd71874a..913f31a3fd9 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -270,6 +270,19 @@ void ClangModelManagerSupport::followSymbol(const CppEditor::CursorInEditor &dat CppModelManager::Backend::Builtin); } +void ClangModelManagerSupport::followSymbolToType(const CppEditor::CursorInEditor &data, + const Utils::LinkHandler &processLinkCallback, + bool inNextSplit) +{ + if (ClangdClient * const client = clientForFile(data.filePath())) { + client->followSymbol(data.textDocument(), data.cursor(), data.editorWidget(), + processLinkCallback, false, FollowTo::SymbolType, inNextSplit); + return; + } + CppModelManager::followSymbolToType(data, processLinkCallback, inNextSplit, + CppModelManager::Backend::Builtin); +} + void ClangModelManagerSupport::switchDeclDef(const CppEditor::CursorInEditor &data, const Utils::LinkHandler &processLinkCallback) { diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 8557574805b..3968e9bebab 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -52,6 +52,9 @@ private: void followSymbol(const CppEditor::CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool resolveTarget, bool inNextSplit) override; + void followSymbolToType(const CppEditor::CursorInEditor &data, + const Utils::LinkHandler &processLinkCallback, + bool inNextSplit) override; void switchDeclDef(const CppEditor::CursorInEditor &data, const Utils::LinkHandler &processLinkCallback) override; void startLocalRenaming(const CppEditor::CursorInEditor &data, diff --git a/src/plugins/clangtools/unit-tests/exported-diagnostics/CMakeLists.txt b/src/plugins/clangtools/unit-tests/exported-diagnostics/CMakeLists.txt index b445f81b7dd..cccf51f4929 100644 --- a/src/plugins/clangtools/unit-tests/exported-diagnostics/CMakeLists.txt +++ b/src/plugins/clangtools/unit-tests/exported-diagnostics/CMakeLists.txt @@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.5) project(clangtools LANGUAGES CXX) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) @@ -17,8 +16,6 @@ find_package(Qt5 COMPONENTS Widgets REQUIRED) add_executable(clangtools main.cpp clang-analyzer.dividezero.cpp - clang.unused-parameter.cpp - clang.unused-parameter.h clazy.qgetenv.cpp tidy.modernize-use-nullptr.cpp ) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 91e1cd80479..e746f2374f2 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -1301,8 +1301,8 @@ static void addCMakeConfigurePresetToInitialArguments(QStringList &initialArgume } } -static Utils::EnvironmentItems getEnvironmentItemsFromCMakePreset(const CMakeProject *project, - const Kit *k) +static Utils::EnvironmentItems getEnvironmentItemsFromCMakeConfigurePreset( + const CMakeProject *project, const Kit *k) { Utils::EnvironmentItems envItems; @@ -1324,6 +1324,27 @@ static Utils::EnvironmentItems getEnvironmentItemsFromCMakePreset(const CMakePro return envItems; } +static Utils::EnvironmentItems getEnvironmentItemsFromCMakeBuildPreset( + const CMakeProject *project, const Kit *k, const QString &buildPresetName) + +{ + Utils::EnvironmentItems envItems; + + const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k); + if (presetItem.isNull()) + return envItems; + + PresetsDetails::BuildPreset buildPreset + = Utils::findOrDefault(project->presetsData().buildPresets, + [buildPresetName](const PresetsDetails::BuildPreset &preset) { + return preset.name == buildPresetName; + }); + + CMakePresets::Macros::expand(buildPreset, envItems, project->projectDirectory()); + + return envItems; +} + // ----------------------------------------------------------------------------- // CMakeBuildConfigurationPrivate: // ----------------------------------------------------------------------------- @@ -1423,8 +1444,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) addAspect(); addAspect(this); - appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID); - appendInitialCleanStep(Constants::CMAKE_BUILD_STEP_ID); + setInitialBuildAndCleanSteps(target); setInitializer([this, target](const BuildInfo &info) { const Kit *k = target->kit(); @@ -1527,7 +1547,7 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) cmd.addArg("-DCMAKE_CXX_FLAGS_INIT:STRING=%{" + QLatin1String(QT_QML_DEBUG_FLAG) + "}"); CMakeProject *cmakeProject = static_cast(target->project()); - setUserConfigureEnvironmentChanges(getEnvironmentItemsFromCMakePreset(cmakeProject, k)); + setUserConfigureEnvironmentChanges(getEnvironmentItemsFromCMakeConfigurePreset(cmakeProject, k)); QStringList initialCMakeArguments = cmd.splitArguments(); addCMakeConfigurePresetToInitialArguments(initialCMakeArguments, @@ -1537,6 +1557,8 @@ CMakeBuildConfiguration::CMakeBuildConfiguration(Target *target, Id id) m_buildSystem->setInitialCMakeArguments(initialCMakeArguments); m_buildSystem->setCMakeBuildType(buildType); updateAndEmitConfigureEnvironmentChanged(); + + setBuildPresetToBuildSteps(target); }); } @@ -1799,6 +1821,104 @@ CMakeConfig CMakeBuildConfiguration::signingFlags() const return {}; } +void CMakeBuildConfiguration::setInitialBuildAndCleanSteps(const ProjectExplorer::Target *target) +{ + const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem( + target->kit()); + + if (!presetItem.isNull()) { + const QString presetName = presetItem.expandedValue(target->kit()); + const CMakeProject *project = static_cast(target->project()); + + const auto buildPresets = project->presetsData().buildPresets; + const int count = std::count_if(buildPresets.begin(), + buildPresets.end(), + [presetName](const PresetsDetails::BuildPreset &preset) { + return preset.configurePreset == presetName + && !preset.hidden.value(); + }); + + for (int i = 0; i < count; ++i) + appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID); + + } else { + appendInitialBuildStep(Constants::CMAKE_BUILD_STEP_ID); + } + appendInitialCleanStep(Constants::CMAKE_BUILD_STEP_ID); +} + +void CMakeBuildConfiguration::setBuildPresetToBuildSteps(const ProjectExplorer::Target *target) +{ + const CMakeConfigItem presetItem = CMakeConfigurationKitAspect::cmakePresetConfigItem( + target->kit()); + + if (presetItem.isNull()) + return; + + const QString presetName = presetItem.expandedValue(target->kit()); + const CMakeProject *project = static_cast(target->project()); + + const auto allBuildPresets = project->presetsData().buildPresets; + const auto buildPresets + = Utils::filtered(allBuildPresets, [presetName](const PresetsDetails::BuildPreset &preset) { + return preset.configurePreset == presetName && !preset.hidden.value(); + }); + + const QList buildStepList + = Utils::filtered(buildSteps()->steps(), [](const BuildStep *bs) { + return bs->id() == Constants::CMAKE_BUILD_STEP_ID; + }); + + if (buildPresets.size() != buildStepList.size()) + return; + + for (qsizetype i = 0; i < buildStepList.size(); ++i) { + CMakeBuildStep *cbs = qobject_cast(buildStepList[i]); + cbs->setBuildPreset(buildPresets[i].name); + cbs->setUserEnvironmentChanges( + getEnvironmentItemsFromCMakeBuildPreset(project, target->kit(), buildPresets[i].name)); + + if (buildPresets[i].targets) { + QString targets = buildPresets[i].targets.value().join(" "); + + CMakePresets::Macros::expand(buildPresets[i], + cbs->environment(), + project->projectDirectory(), + targets); + + cbs->setBuildTargets(targets.split(" ")); + } + + QStringList cmakeArguments; + if (buildPresets[i].jobs) + cmakeArguments.append(QString("-j %1").arg(buildPresets[i].jobs.value())); + if (buildPresets[i].verbose && buildPresets[i].verbose.value()) + cmakeArguments.append("--verbose"); + if (buildPresets[i].cleanFirst && buildPresets[i].cleanFirst.value()) + cmakeArguments.append("--clean-first"); + if (!cmakeArguments.isEmpty()) + cbs->setCMakeArguments(cmakeArguments); + + if (buildPresets[i].nativeToolOptions) { + QString nativeToolOptions = buildPresets[i].nativeToolOptions.value().join(" "); + + CMakePresets::Macros::expand(buildPresets[i], + cbs->environment(), + project->projectDirectory(), + nativeToolOptions); + + cbs->setToolArguments(nativeToolOptions.split(" ")); + } + + if (buildPresets[i].configuration) + cbs->setConfiguration(buildPresets[i].configuration.value()); + + // Leave only the first build step enabled + if (i > 0) + cbs->setEnabled(false); + } +} + /*! \class CMakeBuildConfigurationFactory */ diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index 6512baf553c..448e0706f7b 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -69,6 +69,9 @@ private: virtual CMakeConfig signingFlags() const; + void setInitialBuildAndCleanSteps(const ProjectExplorer::Target *target); + void setBuildPresetToBuildSteps(const ProjectExplorer::Target *target); + Internal::CMakeBuildSystem *m_buildSystem = nullptr; friend class Internal::CMakeBuildSettingsWidget; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index 4f371f2c6b5..c9fcf2acf7c 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -7,11 +7,14 @@ #include "cmakebuildsystem.h" #include "cmakekitinformation.h" #include "cmakeparser.h" +#include "cmakeproject.h" #include "cmakeprojectconstants.h" #include "cmaketool.h" #include #include +#include +#include #include #include #include @@ -29,6 +32,7 @@ #include #include #include +#include using namespace Core; using namespace ProjectExplorer; @@ -42,6 +46,9 @@ const char CMAKE_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.CMakeArguments" const char TOOL_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.AdditionalArguments"; const char IOS_AUTOMATIC_PROVISIONG_UPDATES_ARGUMENTS_KEY[] = "CMakeProjectManager.MakeStep.iOSAutomaticProvisioningUpdates"; +const char CLEAR_SYSTEM_ENVIRONMENT_KEY[] = "CMakeProjectManager.MakeStep.ClearSystemEnvironment"; +const char USER_ENVIRONMENT_CHANGES_KEY[] = "CMakeProjectManager.MakeStep.UserEnvironmentChanges"; +const char BUILD_PRESET_KEY[] = "CMakeProjectManager.MakeStep.BuildPreset"; // CmakeProgressParser @@ -186,11 +193,12 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl, Utils::Id id) : setCommandLineProvider([this] { return cmakeCommand(); }); - setEnvironmentModifier([](Environment &env) { + setEnvironmentModifier([this](Environment &env) { const QString ninjaProgressString = "[%f/%t "; // ninja: [33/100 env.setupEnglishOutput(); if (!env.expandedValueForKey("NINJA_STATUS").startsWith(ninjaProgressString)) env.set("NINJA_STATUS", ninjaProgressString + "%o/sec] "); + env.modify(m_userEnvironmentChanges); }); connect(target(), &Target::parsingFinished, this, [this](bool success) { @@ -207,12 +215,26 @@ QVariantMap CMakeBuildStep::toMap() const { QVariantMap map(AbstractProcessStep::toMap()); map.insert(BUILD_TARGETS_KEY, m_buildTargets); + map.insert(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY), m_clearSystemEnvironment); + map.insert(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY), EnvironmentItem::toStringList(m_userEnvironmentChanges)); + map.insert(QLatin1String(BUILD_PRESET_KEY), m_buildPreset); + return map; } bool CMakeBuildStep::fromMap(const QVariantMap &map) { setBuildTargets(map.value(BUILD_TARGETS_KEY).toStringList()); + + m_clearSystemEnvironment = map.value(QLatin1String(CLEAR_SYSTEM_ENVIRONMENT_KEY)) + .toBool(); + m_userEnvironmentChanges = EnvironmentItem::fromStringList( + map.value(QLatin1String(USER_ENVIRONMENT_CHANGES_KEY)).toStringList()); + + updateAndEmitEnvironmentChanged(); + + m_buildPreset = map.value(QLatin1String(BUILD_PRESET_KEY)).toString(); + return BuildStep::fromMap(map); } @@ -348,6 +370,14 @@ QString CMakeBuildStep::defaultBuildTarget() const return allTarget(); } +bool CMakeBuildStep::isCleanStep() const +{ + const BuildStepList *const bsl = stepList(); + QTC_ASSERT(bsl, return false); + const Utils::Id parentId = bsl->id(); + return parentId == ProjectExplorer::Constants::BUILDSTEPS_CLEAN; +} + QStringList CMakeBuildStep::buildTargets() const { return m_buildTargets; @@ -401,7 +431,10 @@ CommandLine CMakeBuildStep::cmakeCommand() const auto bs = qobject_cast(buildSystem()); if (bs && bs->isMultiConfigReader()) { cmd.addArg("--config"); - cmd.addArg(bs->cmakeBuildType()); + if (m_configuration) + cmd.addArg(m_configuration.value()); + else + cmd.addArg(bs->cmakeBuildType()); } if (!m_cmakeArguments->value().isEmpty()) @@ -453,13 +486,36 @@ QString CMakeBuildStep::activeRunConfigTarget() const return rc ? rc->buildKey() : QString(); } +void CMakeBuildStep::setBuildPreset(const QString &preset) +{ + m_buildPreset = preset; +} + QWidget *CMakeBuildStep::createConfigWidget() { auto updateDetails = [this] { ProcessParameters param; setupProcessParameters(¶m); param.setCommandLine(cmakeCommand()); - setSummaryText(param.summary(displayName())); + + QString summaryText = param.summary(displayName()); + + if (!m_buildPreset.isEmpty()) { + const CMakeProject *cp = static_cast(project()); + + const auto buildPresets = cp->presetsData().buildPresets; + const PresetsDetails::BuildPreset preset + = Utils::findOrDefault(buildPresets, [this](const PresetsDetails::BuildPreset &bp) { + return bp.name == m_buildPreset; + }); + + const QString presetDisplayName = preset.displayName ? preset.displayName.value() + : preset.name; + if (!presetDisplayName.isEmpty()) + summaryText.append(QString("
Preset: %1").arg(presetDisplayName)); + } + + setSummaryText(summaryText); }; setDisplayName(tr("Build", "ConfigWidget display name.")); @@ -473,6 +529,34 @@ QWidget *CMakeBuildStep::createConfigWidget() auto frame = ItemViewFind::createSearchableWrapper(buildTargetsView, ItemViewFind::LightColored); + auto createAndAddEnvironmentWidgets = [this](Layouting::Form &builder) { + auto clearBox = new QCheckBox(tr("Clear system environment")); + clearBox->setChecked(useClearEnvironment()); + + auto envWidget = new EnvironmentWidget(nullptr, EnvironmentWidget::TypeLocal, clearBox); + envWidget->setBaseEnvironment(baseEnvironment()); + envWidget->setBaseEnvironmentText(baseEnvironmentText()); + envWidget->setUserChanges(userEnvironmentChanges()); + + connect(envWidget, &EnvironmentWidget::userChangesChanged, this, [this, envWidget] { + setUserEnvironmentChanges(envWidget->userChanges()); + }); + + connect(clearBox, &QAbstractButton::toggled, this, [this, envWidget](bool checked) { + setUseClearEnvironment(checked); + envWidget->setBaseEnvironment(baseEnvironment()); + envWidget->setBaseEnvironmentText(baseEnvironmentText()); + }); + + connect(this, &CMakeBuildStep::environmentChanged, this, [this, envWidget] { + envWidget->setBaseEnvironment(baseEnvironment()); + envWidget->setBaseEnvironmentText(baseEnvironmentText()); + }); + + builder.addRow(clearBox); + builder.addRow(envWidget); + }; + Layouting::Form builder; builder.addRow(m_cmakeArguments); builder.addRow(m_toolArguments); @@ -481,6 +565,10 @@ QWidget *CMakeBuildStep::createConfigWidget() builder.addRow(m_useiOSAutomaticProvisioningUpdates); builder.addRow({new QLabel(tr("Targets:")), frame}); + + if (!isCleanStep() && !m_buildPreset.isEmpty()) + createAndAddEnvironmentWidgets(builder); + auto widget = builder.emerge(Layouting::WithoutMargins); updateDetails(); @@ -552,6 +640,83 @@ void CMakeBuildStep::updateBuildTargetsModel() emit buildTargetsChanged(); } +void CMakeBuildStep::setConfiguration(const QString &configuration) +{ + m_configuration = configuration; +} + +void CMakeBuildStep::setToolArguments(const QStringList &nativeToolArguments) +{ + m_toolArguments->setValue(nativeToolArguments.join(" ")); +} + +void CMakeBuildStep::setCMakeArguments(const QStringList &cmakeArguments) +{ + m_cmakeArguments->setValue(cmakeArguments.join(" ")); +} + +Environment CMakeBuildStep::environment() const +{ + return m_environment; +} + +void CMakeBuildStep::setUserEnvironmentChanges(const Utils::EnvironmentItems &diff) +{ + if (m_userEnvironmentChanges == diff) + return; + m_userEnvironmentChanges = diff; + updateAndEmitEnvironmentChanged(); +} + +EnvironmentItems CMakeBuildStep::userEnvironmentChanges() const +{ + return m_userEnvironmentChanges; +} + +bool CMakeBuildStep::useClearEnvironment() const +{ + return m_clearSystemEnvironment; +} + +void CMakeBuildStep::setUseClearEnvironment(bool b) +{ + if (useClearEnvironment() == b) + return; + m_clearSystemEnvironment = b; + updateAndEmitEnvironmentChanged(); +} + +void CMakeBuildStep::updateAndEmitEnvironmentChanged() +{ + Environment env = baseEnvironment(); + env.modify(userEnvironmentChanges()); + if (env == m_environment) + return; + m_environment = env; + emit environmentChanged(); +} + +Environment CMakeBuildStep::baseEnvironment() const +{ + Environment result; + if (!useClearEnvironment()) { + ProjectExplorer::IDevice::ConstPtr devicePtr = BuildDeviceKitAspect::device(kit()); + result = devicePtr ? devicePtr->systemEnvironment() : Environment::systemEnvironment(); + } + buildConfiguration()->addToEnvironment(result); + kit()->addToBuildEnvironment(result); + result.modify(project()->additionalEnvironment()); + return result; +} + +QString CMakeBuildStep::baseEnvironmentText() const +{ + if (useClearEnvironment()) + return tr("Clean Environment"); + else + return tr("System Environment"); +} + void CMakeBuildStep::processFinished(int exitCode, QProcess::ExitStatus status) { AbstractProcessStep::processFinished(exitCode, status); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.h b/src/plugins/cmakeprojectmanager/cmakebuildstep.h index 2124727a65e..f44474cdaac 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.h @@ -54,8 +54,26 @@ public: QString activeRunConfigTarget() const; + void setBuildPreset(const QString &preset); + + Utils::Environment environment() const; + void setUserEnvironmentChanges(const Utils::EnvironmentItems &diff); + Utils::EnvironmentItems userEnvironmentChanges() const; + bool useClearEnvironment() const; + void setUseClearEnvironment(bool b); + void updateAndEmitEnvironmentChanged(); + + Utils::Environment baseEnvironment() const; + QString baseEnvironmentText() const; + + void setCMakeArguments(const QStringList &cmakeArguments); + void setToolArguments(const QStringList &nativeToolArguments); + + void setConfiguration(const QString &configuration); + signals: void buildTargetsChanged(); + void environmentChanged(); private: Utils::CommandLine cmakeCommand() const; @@ -69,6 +87,7 @@ private: QWidget *createConfigWidget() override; QString defaultBuildTarget() const; + bool isCleanStep() const; void runImpl(); void handleProjectWasParsed(bool success); @@ -90,6 +109,12 @@ private: QString m_installTarget = "install"; Utils::TreeModel m_buildTargetModel; + + Utils::Environment m_environment; + Utils::EnvironmentItems m_userEnvironmentChanges; + bool m_clearSystemEnvironment = false; + QString m_buildPreset; + std::optional m_configuration; }; class CMakeBuildStepFactory : public ProjectExplorer::BuildStepFactory diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index cbee35001bd..e3873d35df5 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -88,54 +88,93 @@ Internal::PresetsData CMakeProject::combinePresets(Internal::PresetsData &cmakeP result.version = cmakePresetsData.version; result.cmakeMinimimRequired = cmakePresetsData.cmakeMinimimRequired; - QHash configurePresets; + auto combinePresetsInternal = [](auto &presetsHash, + auto &presets, + auto &userPresets, + const QString &presetType) { + // Populate the hash map with the CMakePresets + for (const auto &p : presets) + presetsHash.insert(p.name, p); - // Populate the hash map with the CMakePresets - for (const PresetsDetails::ConfigurePreset &p: cmakePresetsData.configurePresets) - configurePresets.insert(p.name, p); - - auto resolveInherits = - [configurePresets](std::vector &configurePresetsList) { - for (PresetsDetails::ConfigurePreset &cp : configurePresetsList) { - if (!cp.inherits) + auto resolveInherits = [](const auto &presetsHash, auto &presetsList) { + for (auto &p : presetsList) { + if (!p.inherits) continue; - for (const QString &inheritFromName : cp.inherits.value()) - if (configurePresets.contains(inheritFromName)) - cp.inheritFrom(configurePresets[inheritFromName]); + for (const QString &inheritFromName : p.inherits.value()) + if (presetsHash.contains(inheritFromName)) + p.inheritFrom(presetsHash[inheritFromName]); } }; - // First resolve the CMakePresets - resolveInherits(cmakePresetsData.configurePresets); + // First resolve the CMakePresets + resolveInherits(presetsHash, presets); - // Add the CMakeUserPresets to the resolve hash map - for (const PresetsDetails::ConfigurePreset &cp : cmakeUserPresetsData.configurePresets) { - if (configurePresets.contains(cp.name)) { - TaskHub::addTask(BuildSystemTask( - Task::TaskType::Error, - tr("CMakeUserPresets.json cannot re-define the configure preset: %1").arg(cp.name), - "CMakeUserPresets.json")); - TaskHub::requestPopup(); - } else { - configurePresets.insert(cp.name, cp); + // Add the CMakeUserPresets to the resolve hash map + for (const auto &p : userPresets) { + if (presetsHash.contains(p.name)) { + TaskHub::addTask( + BuildSystemTask(Task::TaskType::Error, + tr("CMakeUserPresets.json cannot re-define the %1 preset: %2") + .arg(presetType) + .arg(p.name), + "CMakeUserPresets.json")); + TaskHub::requestPopup(); + } else { + presetsHash.insert(p.name, p); + } } - } - // Then resolve the CMakeUserPresets - resolveInherits(cmakeUserPresetsData.configurePresets); + // Then resolve the CMakeUserPresets + resolveInherits(presetsHash, userPresets); - // Get both CMakePresets and CMakeUserPresets into the result - result.configurePresets = cmakePresetsData.configurePresets; + // Get both CMakePresets and CMakeUserPresets into the result + auto result = presets; - // std::vector doesn't have append - std::copy(cmakeUserPresetsData.configurePresets.begin(), - cmakeUserPresetsData.configurePresets.end(), - std::back_inserter(result.configurePresets)); + // std::vector doesn't have append + std::copy(userPresets.begin(), userPresets.end(), std::back_inserter(result)); + return result; + }; + + QHash configurePresetsHash; + QHash buildPresetsHash; + + result.configurePresets = combinePresetsInternal(configurePresetsHash, + cmakePresetsData.configurePresets, + cmakeUserPresetsData.configurePresets, + "configure"); + result.buildPresets = combinePresetsInternal(buildPresetsHash, + cmakePresetsData.buildPresets, + cmakeUserPresetsData.buildPresets, + "build"); return result; } +void CMakeProject::setupBuildPresets(Internal::PresetsData &presetsData) +{ + for (auto &buildPreset : presetsData.buildPresets) { + if (buildPreset.inheritConfigureEnvironment) { + if (!buildPreset.configurePreset) { + TaskHub::addTask(BuildSystemTask( + Task::TaskType::Error, + tr("Build preset %1 is missing a corresponding configure preset.") + .arg(buildPreset.name))); + TaskHub::requestPopup(); + } + + const QString &configurePresetName = buildPreset.configurePreset.value(); + buildPreset.environment + = Utils::findOrDefault(presetsData.configurePresets, + [configurePresetName]( + const PresetsDetails::ConfigurePreset &configurePreset) { + return configurePresetName == configurePreset.name; + }) + .environment; + } + } +} + void CMakeProject::readPresets() { auto parsePreset = [](const Utils::FilePath &presetFile) -> Internal::PresetsData { @@ -168,6 +207,7 @@ void CMakeProject::readPresets() Internal::PresetsData cmakeUserPresetsData = parsePreset(cmakeUserPresetsJson); m_presetsData = combinePresets(cmakePresetsData, cmakeUserPresetsData); + setupBuildPresets(m_presetsData); } bool CMakeProject::setupTarget(Target *t) diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 4854ed1ffc1..14cebc2fc32 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -38,6 +38,7 @@ private: ProjectExplorer::DeploymentKnowledge deploymentKnowledge() const override; Internal::PresetsData combinePresets(Internal::PresetsData &cmakePresetsData, Internal::PresetsData &cmakeUserPresetsData); + void setupBuildPresets(Internal::PresetsData &presetsData); mutable Internal::CMakeProjectImporter *m_projectImporter = nullptr; diff --git a/src/plugins/cmakeprojectmanager/presetsmacros.cpp b/src/plugins/cmakeprojectmanager/presetsmacros.cpp index c5a140f4601..29ecdf946bf 100644 --- a/src/plugins/cmakeprojectmanager/presetsmacros.cpp +++ b/src/plugins/cmakeprojectmanager/presetsmacros.cpp @@ -12,9 +12,9 @@ namespace CMakeProjectManager::Internal::CMakePresets::Macros { -static void expandAllButEnv(const PresetsDetails::ConfigurePreset &configurePreset, - const Utils::FilePath &sourceDirectory, - QString &value) +void expandAllButEnv(const PresetsDetails::ConfigurePreset &preset, + const Utils::FilePath &sourceDirectory, + QString &value) { value.replace("${dollar}", "$"); @@ -22,23 +22,36 @@ static void expandAllButEnv(const PresetsDetails::ConfigurePreset &configurePres value.replace("${sourceParentDir}", sourceDirectory.parentDir().toString()); value.replace("${sourceDirName}", sourceDirectory.fileName()); - value.replace("${presetName}", configurePreset.name); - if (configurePreset.generator) - value.replace("${generator}", configurePreset.generator.value()); + value.replace("${presetName}", preset.name); + if (preset.generator) + value.replace("${generator}", preset.generator.value()); } -void expand(const PresetsDetails::ConfigurePreset &configurePreset, +void expandAllButEnv(const PresetsDetails::BuildPreset &preset, + const Utils::FilePath &sourceDirectory, + QString &value) +{ + value.replace("${dollar}", "$"); + + value.replace("${sourceDir}", sourceDirectory.toString()); + value.replace("${sourceParentDir}", sourceDirectory.parentDir().toString()); + value.replace("${sourceDirName}", sourceDirectory.fileName()); + + value.replace("${presetName}", preset.name); +} + +template +void expand(const PresetType &preset, Utils::Environment &env, const Utils::FilePath &sourceDirectory) { - const QHash presetEnv = configurePreset.environment - ? configurePreset.environment.value() - : QHash(); + const QHash presetEnv = preset.environment ? preset.environment.value() + : QHash(); for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) { const QString key = it->first; QString value = it->second; - expandAllButEnv(configurePreset, sourceDirectory, value); + expandAllButEnv(preset, sourceDirectory, value); QRegularExpression envRegex(R"((\$env\{(\w+)\}))"); for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) { @@ -69,19 +82,19 @@ void expand(const PresetsDetails::ConfigurePreset &configurePreset, } } -void expand(const PresetsDetails::ConfigurePreset &configurePreset, +template +void expand(const PresetType &preset, Utils::EnvironmentItems &envItems, const Utils::FilePath &sourceDirectory) { - const QHash presetEnv = configurePreset.environment - ? configurePreset.environment.value() - : QHash(); + const QHash presetEnv = preset.environment ? preset.environment.value() + : QHash(); for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) { const QString key = it->first; QString value = it->second; - expandAllButEnv(configurePreset, sourceDirectory, value); + expandAllButEnv(preset, sourceDirectory, value); QRegularExpression envRegex(R"((\$env\{(\w+)\}))"); for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) { @@ -108,16 +121,16 @@ void expand(const PresetsDetails::ConfigurePreset &configurePreset, } } -void expand(const PresetsDetails::ConfigurePreset &configurePreset, +template +void expand(const PresetType &preset, const Utils::Environment &env, const Utils::FilePath &sourceDirectory, QString &value) { - expandAllButEnv(configurePreset, sourceDirectory, value); + expandAllButEnv(preset, sourceDirectory, value); - const QHash presetEnv = configurePreset.environment - ? configurePreset.environment.value() - : QHash(); + const QHash presetEnv = preset.environment ? preset.environment.value() + : QHash(); QRegularExpression envRegex(R"((\$env\{(\w+)\}))"); for (const QRegularExpressionMatch &match : envRegex.globalMatch(value)) @@ -128,4 +141,32 @@ void expand(const PresetsDetails::ConfigurePreset &configurePreset, value.replace(match.captured(1), env.value(match.captured(2))); } +// Expand for PresetsDetails::ConfigurePreset +template void expand(const PresetsDetails::ConfigurePreset &preset, + Utils::Environment &env, + const Utils::FilePath &sourceDirectory); + +template void expand(const PresetsDetails::ConfigurePreset &preset, + Utils::EnvironmentItems &envItems, + const Utils::FilePath &sourceDirectory); + +template void expand(const PresetsDetails::ConfigurePreset &preset, + const Utils::Environment &env, + const Utils::FilePath &sourceDirectory, + QString &value); + +// Expand for PresetsDetails::BuildPreset +template void expand(const PresetsDetails::BuildPreset &preset, + Utils::Environment &env, + const Utils::FilePath &sourceDirectory); + +template void expand(const PresetsDetails::BuildPreset &preset, + Utils::EnvironmentItems &envItems, + const Utils::FilePath &sourceDirectory); + +template void expand(const PresetsDetails::BuildPreset &preset, + const Utils::Environment &env, + const Utils::FilePath &sourceDirectory, + QString &value); + } // namespace CMakeProjectManager::Internal::CMakePresets::Macros diff --git a/src/plugins/cmakeprojectmanager/presetsmacros.h b/src/plugins/cmakeprojectmanager/presetsmacros.h index 49f738ac784..9da2734da2a 100644 --- a/src/plugins/cmakeprojectmanager/presetsmacros.h +++ b/src/plugins/cmakeprojectmanager/presetsmacros.h @@ -12,16 +12,13 @@ class FilePath; namespace CMakeProjectManager::Internal { -namespace PresetsDetails { -class ConfigurePreset; -} - namespace CMakePresets::Macros { /** * Expands the CMakePresets Macros using Utils::Environment as target and source for parent environment values. * $penv{PATH} is taken from Utils::Environment */ -void expand(const PresetsDetails::ConfigurePreset &configurePreset, +template +void expand(const PresetType &preset, Utils::Environment &env, const Utils::FilePath &sourceDirectory); @@ -29,14 +26,16 @@ void expand(const PresetsDetails::ConfigurePreset &configurePreset, * Expands the CMakePresets Macros using Utils::Environment as target * $penv{PATH} is replaced with Qt Creator macros ${PATH} */ -void expand(const PresetsDetails::ConfigurePreset &configurePreset, +template +void expand(const PresetType &preset, Utils::EnvironmentItems &envItems, const Utils::FilePath &sourceDirectory); /** * Expands the CMakePresets macros inside the @value QString parameter. */ -void expand(const PresetsDetails::ConfigurePreset &configurePreset, +template +void expand(const PresetType &preset, const Utils::Environment &env, const Utils::FilePath &sourceDirectory, QString &value); diff --git a/src/plugins/cmakeprojectmanager/presetsparser.cpp b/src/plugins/cmakeprojectmanager/presetsparser.cpp index cf760d509e3..47e46cb0137 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.cpp +++ b/src/plugins/cmakeprojectmanager/presetsparser.cpp @@ -13,7 +13,7 @@ namespace Internal { bool parseVersion(const QJsonValue &jsonValue, int &version) { - if (jsonValue.isNull()) + if (jsonValue.isUndefined()) return false; const int invalidVersion = -1; @@ -23,7 +23,7 @@ bool parseVersion(const QJsonValue &jsonValue, int &version) bool parseCMakeMinimumRequired(const QJsonValue &jsonValue, QVersionNumber &versionNumber) { - if (jsonValue.isNull() || !jsonValue.isObject()) + if (jsonValue.isUndefined() || !jsonValue.isObject()) return false; QJsonObject object = jsonValue.toObject(); @@ -38,7 +38,7 @@ bool parseConfigurePresets(const QJsonValue &jsonValue, std::vector &configurePresets) { // The whole section is optional - if (jsonValue.isNull()) + if (jsonValue.isUndefined()) return true; if (!jsonValue.isArray()) @@ -56,7 +56,7 @@ bool parseConfigurePresets(const QJsonValue &jsonValue, preset.hidden = object.value("hidden").toBool(); QJsonValue inherits = object.value("inherits"); - if (!inherits.isNull()) { + if (!inherits.isUndefined()) { preset.inherits = QStringList(); if (inherits.isArray()) { const QJsonArray inheritsArray = inherits.toArray(); @@ -184,6 +184,97 @@ bool parseConfigurePresets(const QJsonValue &jsonValue, return true; } +bool parseBuildPresets(const QJsonValue &jsonValue, + std::vector &buildPresets) +{ + // The whole section is optional + if (jsonValue.isUndefined()) + return true; + + if (!jsonValue.isArray()) + return false; + + const QJsonArray buildPresetsArray = jsonValue.toArray(); + for (const QJsonValue &presetJson : buildPresetsArray) { + if (!presetJson.isObject()) + continue; + + QJsonObject object = presetJson.toObject(); + PresetsDetails::BuildPreset preset; + + preset.name = object.value("name").toString(); + preset.hidden = object.value("hidden").toBool(); + + QJsonValue inherits = object.value("inherits"); + if (!inherits.isUndefined()) { + preset.inherits = QStringList(); + if (inherits.isArray()) { + const QJsonArray inheritsArray = inherits.toArray(); + for (const QJsonValue &inheritsValue : inheritsArray) + preset.inherits.value() << inheritsValue.toString(); + } else { + QString inheritsValue = inherits.toString(); + if (!inheritsValue.isEmpty()) + preset.inherits.value() << inheritsValue; + } + } + if (object.contains("displayName")) + preset.displayName = object.value("displayName").toString(); + if (object.contains("description")) + preset.description = object.value("description").toString(); + + const QJsonObject environmentObj = object.value("environment").toObject(); + for (const QString &envKey : environmentObj.keys()) { + if (!preset.environment) + preset.environment = QHash(); + + QJsonValue envValue = environmentObj.value(envKey); + preset.environment.value().insert(envKey, envValue.toString()); + } + + if (object.contains("configurePreset")) + preset.configurePreset = object.value("configurePreset").toString(); + if (object.contains("inheritConfigureEnvironment")) + preset.inheritConfigureEnvironment = object.value("inheritConfigureEnvironment").toBool(); + if (object.contains("jobs")) + preset.jobs = object.value("jobs").toInt(); + + QJsonValue targets = object.value("targets"); + if (!targets.isUndefined()) { + preset.targets = QStringList(); + if (targets.isArray()) { + const QJsonArray targetsArray = targets.toArray(); + for (const QJsonValue &targetsValue : targetsArray) + preset.targets.value() << targetsValue.toString(); + } else { + QString targetsValue = targets.toString(); + if (!targetsValue.isEmpty()) + preset.targets.value() << targetsValue; + } + } + if (object.contains("configuration")) + preset.configuration = object.value("configuration").toString(); + if (object.contains("verbose")) + preset.verbose = object.value("verbose").toBool(); + if (object.contains("cleanFirst")) + preset.cleanFirst = object.value("cleanFirst").toBool(); + + QJsonValue nativeToolOptions = object.value("nativeToolOptions"); + if (!nativeToolOptions.isUndefined()) { + if (nativeToolOptions.isArray()) { + preset.nativeToolOptions = QStringList(); + const QJsonArray toolOptionsArray = nativeToolOptions.toArray(); + for (const QJsonValue &toolOptionsValue : toolOptionsArray) + preset.nativeToolOptions.value() << toolOptionsValue.toString(); + } + } + + buildPresets.emplace_back(preset); + } + + return true; +} + const PresetsData &PresetsParser::presetsData() const { return m_presetsData; @@ -232,9 +323,19 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage // optional if (!parseConfigurePresets(root.value("configurePresets"), m_presetsData.configurePresets)) { - errorMessage = QCoreApplication::translate( - "CMakeProjectManager::Internal", - "Invalid \"configurePresets\" section in %1 file").arg(jsonFile.fileName()); + errorMessage + = QCoreApplication::translate("CMakeProjectManager::Internal", + "Invalid \"configurePresets\" section in %1 file") + .arg(jsonFile.fileName()); + return false; + } + + // optional + if (!parseBuildPresets(root.value("buildPresets"), m_presetsData.buildPresets)) { + errorMessage + = QCoreApplication::translate("CMakeProjectManager::Internal", + "Invalid \"buildPresets\" section in %1 file") + .arg(jsonFile.fileName()); return false; } @@ -277,5 +378,38 @@ void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other) debug = other.debug; } +void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other) +{ + if (!vendor && other.vendor) + vendor = other.vendor; + + if (!environment && other.environment) + environment = other.environment; + + if (!configurePreset && other.configurePreset) + configurePreset = other.configurePreset; + + if (!inheritConfigureEnvironment && other.inheritConfigureEnvironment) + inheritConfigureEnvironment = other.inheritConfigureEnvironment; + + if (!jobs && other.jobs) + jobs = other.jobs; + + if (!targets && other.targets) + targets = other.targets; + + if (!configuration && other.configuration) + configuration = other.configuration; + + if (!verbose && other.verbose) + verbose = other.verbose; + + if (!cleanFirst && other.cleanFirst) + cleanFirst = other.cleanFirst; + + if (!nativeToolOptions && other.nativeToolOptions) + nativeToolOptions = other.nativeToolOptions; +} + } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/presetsparser.h b/src/plugins/cmakeprojectmanager/presetsparser.h index 0f4700f382f..c067507a2a2 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.h +++ b/src/plugins/cmakeprojectmanager/presetsparser.h @@ -67,6 +67,27 @@ public: std::optional debug; }; +class BuildPreset { +public: + void inheritFrom(const BuildPreset &other); + + QString name; + std::optional hidden = false; + std::optional inherits; + std::optional> vendor; + std::optional displayName; + std::optional description; + std::optional> environment; + std::optional configurePreset; + std::optional inheritConfigureEnvironment = true; + std::optional jobs; + std::optional targets; + std::optional configuration; + std::optional verbose; + std::optional cleanFirst; + std::optional nativeToolOptions; +}; + } // namespace PresetsDetails class PresetsData @@ -76,6 +97,7 @@ public: QVersionNumber cmakeMinimimRequired; QHash vendor; std::vector configurePresets; + std::vector buildPresets; }; class PresetsParser diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 0b6354aff41..7a9991eb6ea 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -211,12 +211,14 @@ MainWindow::MainWindow() connect(dropSupport, &DropSupport::filesDropped, this, &MainWindow::openDroppedFiles); + if (HostOsInfo::isLinuxHost()) { + m_trimTimer.setSingleShot(true); + m_trimTimer.setInterval(60000); + // glibc may not actually free memory in free(). #ifdef Q_OS_LINUX - m_trimTimer.setSingleShot(true); - m_trimTimer.setInterval(60000); - // glibc may not actually free memory in free(). - connect(&m_trimTimer, &QTimer::timeout, this, [] { malloc_trim(0); }); + connect(&m_trimTimer, &QTimer::timeout, this, [] { malloc_trim(0); }); #endif + } } NavigationWidget *MainWindow::navigationWidget(Side side) const @@ -358,7 +360,7 @@ void MainWindow::restart() void MainWindow::restartTrimmer() { - if (!m_trimTimer.isActive()) + if (HostOsInfo::isLinuxHost() && !m_trimTimer.isActive()) m_trimTimer.start(); } diff --git a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp index eade8005c37..f46d7ea03af 100644 --- a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp +++ b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp @@ -6,14 +6,15 @@ #include "builtineditordocumentprocessor.h" #include "cppcanonicalsymbol.h" #include "cppcompletionassist.h" +#include "cppeditortr.h" #include "cppeditorwidget.h" #include "cppelementevaluator.h" #include "cppfollowsymbolundercursor.h" -#include "cppoutlinemodel.h" #include "cpptoolsreuse.h" #include "symbolfinder.h" #include +#include #include #include #include @@ -105,6 +106,17 @@ void BuiltinModelManagerSupport::followSymbol(const CursorInEditor &data, data.editorWidget()->semanticInfo().doc, &finder, inNextSplit); } +void BuiltinModelManagerSupport::followSymbolToType(const CursorInEditor &data, + const Utils::LinkHandler &processLinkCallback, + bool inNextSplit) +{ + Q_UNUSED(data) + Q_UNUSED(processLinkCallback) + Q_UNUSED(inNextSplit) + MessageManager::writeDisrupting( + Tr::tr("Follow Symbol to Type is only available when using clangd")); +} + void BuiltinModelManagerSupport::switchDeclDef(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback) { diff --git a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h index 363dbfae0c2..4a6d56429c5 100644 --- a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h +++ b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h @@ -30,6 +30,9 @@ public: private: void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool resolveTarget, bool inNextSplit) override; + void followSymbolToType(const CursorInEditor &data, + const Utils::LinkHandler &processLinkCallback, + bool inNextSplit) override; void switchDeclDef(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback) override; void startLocalRenaming(const CursorInEditor &data, diff --git a/src/plugins/cppeditor/cppeditorconstants.h b/src/plugins/cppeditor/cppeditorconstants.h index ab30f790f0f..0c226f6682c 100644 --- a/src/plugins/cppeditor/cppeditorconstants.h +++ b/src/plugins/cppeditor/cppeditorconstants.h @@ -14,6 +14,8 @@ const char CPPEDITOR_ID[] = "CppEditor.C++Editor"; const char CPPEDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("OpenWith::Editors", "C++ Editor"); const char SWITCH_DECLARATION_DEFINITION[] = "CppEditor.SwitchDeclarationDefinition"; const char OPEN_DECLARATION_DEFINITION_IN_NEXT_SPLIT[] = "CppEditor.OpenDeclarationDefinitionInNextSplit"; +const char FOLLOW_SYMBOL_TO_TYPE[] = "TextEditor.FollowSymbolToType"; +const char FOLLOW_SYMBOL_TO_TYPE_IN_NEXT_SPLIT[] = "TextEditor.FollowSymbolToTypeInNextSplit"; const char OPEN_PREPROCESSOR_DIALOG[] = "CppEditor.OpenPreprocessorDialog"; const char MULTIPLE_PARSE_CONTEXTS_AVAILABLE[] = "CppEditor.MultipleParseContextsAvailable"; const char M_REFACTORING_MENU_INSERTION_POINT[] = "CppEditor.RefactorGroup"; diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index 0b4e5ca9033..3ce2884553c 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -357,6 +357,30 @@ bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err this, &CppEditorPlugin::openDeclarationDefinitionInNextSplit); cppToolsMenu->addAction(cmd); + QAction * const followSymbolToType = new QAction(tr("Follow Symbol Under Cursor to Type"), + this); + cmd = ActionManager::registerAction(followSymbolToType, Constants::FOLLOW_SYMBOL_TO_TYPE, + context, true); + cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Shift+F2"))); + connect(followSymbolToType, &QAction::triggered, this, []{ + if (CppEditorWidget *editorWidget = currentCppEditorWidget()) + editorWidget->followSymbolToType(false); + }); + contextMenu->addAction(cmd, Constants::G_CONTEXT_FIRST); + cppToolsMenu->addAction(cmd); + QAction * const followSymbolToTypeInNextSplit = + new QAction(tr("Follow Symbol To Type in Next Split"), this); + cmd = ActionManager::registerAction(followSymbolToTypeInNextSplit, + Constants::FOLLOW_SYMBOL_TO_TYPE_IN_NEXT_SPLIT, context, true); + cmd->setDefaultKeySequence(QKeySequence(HostOsInfo::isMacHost() + ? tr("Meta+E, Ctrl+Shift+F2") + : tr("Ctrl+E, Ctrl+Shift+F2"))); + connect(followSymbolToTypeInNextSplit, &QAction::triggered, this, []{ + if (CppEditorWidget *editorWidget = currentCppEditorWidget()) + editorWidget->followSymbolToType(true); + }); + cppToolsMenu->addAction(cmd); + cmd = ActionManager::command(TextEditor::Constants::FIND_USAGES); contextMenu->addAction(cmd, Constants::G_CONTEXT_FIRST); cppToolsMenu->addAction(cmd); diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 193e0d7735a..94d69382420 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -834,6 +834,20 @@ void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit) CppModelManager::switchDeclDef(cursor, std::move(callback)); } +void CppEditorWidget::followSymbolToType(bool inNextSplit) +{ + if (!d->m_modelManager) + return; + + const CursorInEditor cursor(textCursor(), textDocument()->filePath(), this, textDocument()); + const auto callback = [self = QPointer(this), + split = inNextSplit != alwaysOpenLinksInNextSplit()](const Link &link) { + if (self && link.hasValidTarget()) + self->openLink(link, split); + }; + CppModelManager::followSymbolToType(cursor, callback, inNextSplit); +} + bool CppEditorWidget::followQrcUrl(const QTextCursor &cursor, const Utils::LinkHandler &processLinkCallback) { diff --git a/src/plugins/cppeditor/cppeditorwidget.h b/src/plugins/cppeditor/cppeditorwidget.h index d3ed526c2c4..93e9691506f 100644 --- a/src/plugins/cppeditor/cppeditorwidget.h +++ b/src/plugins/cppeditor/cppeditorwidget.h @@ -54,6 +54,7 @@ public: void selectAll() override; void switchDeclarationDefinition(bool inNextSplit); + void followSymbolToType(bool inNextSplit); void showPreProcessorWidget(); void findUsages() override; diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index d5c8a28870f..c3de62dc27f 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -1764,6 +1764,14 @@ void CppModelManager::followSymbol(const CursorInEditor &data, resolveTarget, inNextSplit); } +void CppModelManager::followSymbolToType(const CursorInEditor &data, + const Utils::LinkHandler &processLinkCallback, + bool inNextSplit, Backend backend) +{ + instance()->modelManagerSupport(backend)->followSymbolToType(data, processLinkCallback, + inNextSplit); +} + void CppModelManager::switchDeclDef(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, Backend backend) diff --git a/src/plugins/cppeditor/cppmodelmanager.h b/src/plugins/cppeditor/cppmodelmanager.h index cbf39c206d2..221672d979a 100644 --- a/src/plugins/cppeditor/cppmodelmanager.h +++ b/src/plugins/cppeditor/cppmodelmanager.h @@ -167,6 +167,9 @@ public: static void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool resolveTarget, bool inNextSplit, Backend backend = Backend::Best); + static void followSymbolToType(const CursorInEditor &data, + const Utils::LinkHandler &processLinkCallback, bool inNextSplit, + Backend backend = Backend::Best); static void switchDeclDef(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, Backend backend = Backend::Best); diff --git a/src/plugins/cppeditor/cppmodelmanagersupport.h b/src/plugins/cppeditor/cppmodelmanagersupport.h index 952b1d2ea7e..0544cb45323 100644 --- a/src/plugins/cppeditor/cppmodelmanagersupport.h +++ b/src/plugins/cppeditor/cppmodelmanagersupport.h @@ -40,6 +40,9 @@ public: virtual void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool resolveTarget, bool inNextSplit) = 0; + virtual void followSymbolToType(const CursorInEditor &data, + const Utils::LinkHandler &processLinkCallback, + bool inNextSplit) = 0; virtual void switchDeclDef(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback) = 0; virtual void startLocalRenaming(const CursorInEditor &data, diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index 4d5c32ab7f5..5c4c973aefd 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -62,6 +63,8 @@ public: DebuggerItemManagerPrivate(); ~DebuggerItemManagerPrivate(); + void extensionsInitialized(); + void restoreDebuggers(); void saveDebuggers(); @@ -815,6 +818,10 @@ DebuggerItemManagerPrivate::DebuggerItemManagerPrivate() m_model = new DebuggerItemModel; m_optionsPage = new DebuggerOptionsPage; ExtensionSystem::PluginManager::addObject(m_optionsPage); +} + +void DebuggerItemManagerPrivate::extensionsInitialized() +{ restoreDebuggers(); } @@ -954,6 +961,11 @@ DebuggerItemManager::~DebuggerItemManager() delete d; } +void DebuggerItemManager::extensionsInitialized() +{ + d->extensionsInitialized(); +} + const QList DebuggerItemManager::debuggers() { QList result; diff --git a/src/plugins/debugger/debuggeritemmanager.h b/src/plugins/debugger/debuggeritemmanager.h index 36ddf9e8463..480d2a3174d 100644 --- a/src/plugins/debugger/debuggeritemmanager.h +++ b/src/plugins/debugger/debuggeritemmanager.h @@ -22,6 +22,8 @@ public: DebuggerItemManager(); ~DebuggerItemManager(); + void extensionsInitialized(); + static const QList debuggers(); static QVariant registerDebugger(const DebuggerItem &item); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index b133fdb1a43..c6d256a1233 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2053,6 +2053,10 @@ void DebuggerPluginPrivate::remoteCommand(const QStringList &options) void DebuggerPluginPrivate::extensionsInitialized() { + QTimer::singleShot(0, this, [this]{ + m_debuggerItemManager.extensionsInitialized(); + }); + // If the CppEditor or QmlJS editor plugin is there, we want to add something to // the editor context menu. for (Id menuId : { CppEditor::Constants::M_CONTEXT, QmlJSEditor::Constants::M_CONTEXT }) { diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 879ab58c334..a28147c688c 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -14,11 +14,14 @@ #include #include +#include #include #include #include #include +#include #include +#include #include #include @@ -145,6 +148,8 @@ public: CommandLine withDockerExecCmd(const CommandLine &cmd, bool interactive = false); + bool prepareForBuild(const Target *target); + private: bool createContainer(); void startContainer(); @@ -445,6 +450,14 @@ static QString getLocalIPv4Address() return QString(); } +bool DockerDevicePrivate::prepareForBuild(const Target *target) +{ + QTC_ASSERT(QThread::currentThread() == thread(), return false); + + return ensureReachable(target->project()->projectDirectory()) + && ensureReachable(target->activeBuildConfiguration()->buildDirectory()); +} + bool DockerDevicePrivate::createContainer() { if (!m_settings) @@ -1357,4 +1370,9 @@ void DockerDevicePrivate::setData(const DockerDeviceData &data) } } +bool DockerDevice::prepareForBuild(const Target *target) +{ + return d->prepareForBuild(target); +} + } // namespace Docker::Internal diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index d76329e208b..32997070693 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -122,6 +122,8 @@ public: void updateContainerAccess() const; void setMounts(const QStringList &mounts) const; + bool prepareForBuild(const ProjectExplorer::Target *target) override; + protected: void fromMap(const QVariantMap &map) final; QVariantMap toMap() const final; diff --git a/src/plugins/docker/dockerdevicewidget.cpp b/src/plugins/docker/dockerdevicewidget.cpp index 134ad2a0721..26a349a56bb 100644 --- a/src/plugins/docker/dockerdevicewidget.cpp +++ b/src/plugins/docker/dockerdevicewidget.cpp @@ -122,6 +122,7 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device) auto searchDirsComboBox = new QComboBox; searchDirsComboBox->addItem(Tr::tr("Search in PATH")); searchDirsComboBox->addItem(Tr::tr("Search in Selected Directories")); + searchDirsComboBox->addItem(Tr::tr("Search in PATH and Additional Directories")); auto searchDirsLineEdit = new FancyLineEdit; @@ -132,9 +133,10 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device) auto searchPaths = [searchDirsComboBox, searchDirsLineEdit, dockerDevice] { FilePaths paths; - if (searchDirsComboBox->currentIndex() == 0) { - paths = dockerDevice->systemEnvironment().path(); - } else { + const int idx = searchDirsComboBox->currentIndex(); + if (idx == 0 || idx == 2) + paths += dockerDevice->systemEnvironment().path(); + if (idx == 1 || idx == 2) { for (const QString &path : searchDirsLineEdit->text().split(';')) paths.append(FilePath::fromString(path.trimmed())); } @@ -184,6 +186,7 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device) Column { Space(20), Row { + Tr::tr("Search Locations:"), searchDirsComboBox, searchDirsLineEdit }, @@ -200,8 +203,8 @@ DockerDeviceWidget::DockerDeviceWidget(const IDevice::Ptr &device) searchDirsLineEdit->setVisible(false); auto updateDirectoriesLineEdit = [searchDirsLineEdit](int index) { - searchDirsLineEdit->setVisible(index == 1); - if (index == 1) + searchDirsLineEdit->setVisible(index == 1 || index == 2); + if (index == 1 || index == 2) searchDirsLineEdit->setFocus(); }; QObject::connect(searchDirsComboBox, &QComboBox::activated, this, updateDirectoriesLineEdit); diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index 393ecd7c788..fce7cc8b825 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -434,10 +434,7 @@ void LanguageClientManager::showInspector() QString clientName; if (Client *client = clientForDocument(TextEditor::TextDocument::currentTextDocument())) clientName = client->name(); - QWidget *inspectorWidget = instance()->m_inspector.createWidget(clientName); - inspectorWidget->setAttribute(Qt::WA_DeleteOnClose); - Core::ICore::registerWindow(inspectorWidget, Core::Context("LanguageClient.Inspector")); - inspectorWidget->show(); + instance()->m_inspector.show(clientName); } QList LanguageClientManager::reachableClients() diff --git a/src/plugins/languageclient/lspinspector.cpp b/src/plugins/languageclient/lspinspector.cpp index c19f7d4bce9..245791676c4 100644 --- a/src/plugins/languageclient/lspinspector.cpp +++ b/src/plugins/languageclient/lspinspector.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -335,11 +336,18 @@ private: QListWidget *m_clients = nullptr; }; -QWidget *LspInspector::createWidget(const QString &defaultClient) +void LspInspector::show(const QString &defaultClient) { - auto *inspector = new LspInspectorWidget(this); - inspector->selectClient(defaultClient); - return inspector; + if (!m_currentWidget) { + m_currentWidget = new LspInspectorWidget(this); + m_currentWidget->setAttribute(Qt::WA_DeleteOnClose); + Core::ICore::registerWindow(m_currentWidget, Core::Context("LanguageClient.Inspector")); + } else { + QApplication::setActiveWindow(m_currentWidget); + } + if (!defaultClient.isEmpty()) + static_cast(m_currentWidget.data())->selectClient(defaultClient); + m_currentWidget->show(); } void LspInspector::log(const LspLogMessage::MessageSender sender, diff --git a/src/plugins/languageclient/lspinspector.h b/src/plugins/languageclient/lspinspector.h index f515ef298ca..8d7e343d3a2 100644 --- a/src/plugins/languageclient/lspinspector.h +++ b/src/plugins/languageclient/lspinspector.h @@ -5,6 +5,7 @@ #include "dynamiccapabilities.h" +#include #include #include @@ -47,8 +48,7 @@ class LspInspector : public QObject public: LspInspector() {} - QWidget *createWidget(const QString &defaultClient = {}); - + void show(const QString &defaultClient = {}); void log(const LspLogMessage::MessageSender sender, const QString &clientName, @@ -70,6 +70,7 @@ signals: private: QMap> m_logs; QMap m_capabilities; + QPointer m_currentWidget; int m_logSize = 100; // default log size if no widget is currently visible }; diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 04ce9a38770..cea595d2d89 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -629,12 +629,23 @@ static PackageDescription parsePackage(const QJsonObject &cmakeEntry) [&](const QVariant &version) { return version.toString(); }); + + //Parse the default value depending on the operating system + QString defaultPathString; + if (cmakeEntry["defaultValue"].isObject()) + defaultPathString + = cmakeEntry["defaultValue"] + .toObject()[HostOsInfo::isWindowsHost() ? QString("windows") : QString("unix")] + .toString(""); + else + defaultPathString = cmakeEntry["defaultValue"].toString(); + return {cmakeEntry["label"].toString(), cmakeEntry["envVar"].toString(), cmakeEntry["cmakeVar"].toString(), cmakeEntry["description"].toString(), cmakeEntry["setting"].toString(), - FilePath::fromUserInput(cmakeEntry["defaultValue"].toString()), + FilePath::fromUserInput(defaultPathString), FilePath::fromUserInput(cmakeEntry["validation"].toString()), versions, parseVersionDetection(cmakeEntry), diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h index 356e7b3e4d3..c4da86afb40 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h @@ -25,15 +25,6 @@ constexpr auto armgcc_ek_ra6m3g_baremetal_json = R"( "unix": "/opt/SEGGER/JLink" }, "optional": true - }, - { - "cmakeVar": "EK_RA6M3G_E2_PROJECT_PATH", - "defaultValue": "%{Env:HOME}/e2_studio/workspace/", - "id": "EK_RA6M3G_E2_PROJECT_PATH", - "label": "Path to project for Renesas e2 Studio", - "optional": true, - "setting": "RenesasE2ProjectPath", - "type": "path" } ] }, diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h index 03b9626dd50..311cdc5dcb4 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h @@ -8,25 +8,30 @@ constexpr auto iar_ek_ra6m3g_baremetal_json = R"( "qulVersion": "2.3.0", "compatVersion": "1", "platform": { - "id": "TVIIC2D6M-BAREMETAL", - "vendor": "CYPRESS", + "id": "EK-RA6M3G-BAREMETAL", + "vendor": "RENESAS", "colorDepths": [ - 32 + 16 ], "cmakeEntries": [ { - "id": "INFINEON_AUTO_FLASH_UTILITY_DIR", - "label": "Cypress Auto Flash Utility", + "cmakeVar": "JLINK_PATH", + "setting": "JLinkPath", + "envVar": "JLINK_PATH", + "label": "Path to SEGGER J-Link", "type": "path", - "cmakeVar": "INFINEON_AUTO_FLASH_UTILITY_DIR", - "optional": false + "defaultValue": { + "windows": "%{Env:PROGRAMSANDFILES}/SEGGER/JLink", + "unix": "/opt/SEGGER/JLink" + }, + "optional": true } ] }, "toolchain": { "id": "iar", "versions": [ - "8.22.3" + "9.20.4" ], "compiler": { "id": "IARToolchain", @@ -51,15 +56,15 @@ constexpr auto iar_ek_ra6m3g_baremetal_json = R"( } }, "boardSdk": { - "envVar": "TVII_GRAPHICS_DRIVER_DIR", - "versions": [ - "V1e.1.0" - ], - "id": "TVII_GRAPHICS_DRIVER_DIR", - "label": "Graphics Driver for Traveo II Cluster Series", "cmakeVar": "QUL_BOARD_SDK_DIR", + "envVar": "EK_RA6M3G_FSP_PATH", + "id": "EK_RA6M3G_FSP_PATH", + "label": "Flexible Software Package for Renesas RA MCU Family", + "optional": false, "type": "path", - "optional": false + "versions": [ + "3.8.0" + ] } } )"; diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 8b34b95951c..0e441a2d60b 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -1444,4 +1444,14 @@ void McuSupportTest::test_legacy_createThirdPartyPackage() QVERIFY(qunsetenv(envVar.toLocal8Bit())); } +void McuSupportTest::test_defaultValueForEachOperationSystem() +{ + const auto packageDescription = parseDescriptionJson(armgcc_mimxrt1050_evk_freertos_json); + auto default_path_entry = packageDescription.platform.entries[0].defaultPath.toString(); + + if (HostOsInfo::isWindowsHost()) + QCOMPARE(QString("%{Env:ROOT}/nxp/MCUXpressoIDE*"), default_path_entry); + else + QCOMPARE(QString("/usr/local/mcuxpressoide"), default_path_entry); +}; } // namespace McuSupport::Internal::Test diff --git a/src/plugins/mcusupport/test/unittest.h b/src/plugins/mcusupport/test/unittest.h index 36b835c6e7d..732d636f3ac 100644 --- a/src/plugins/mcusupport/test/unittest.h +++ b/src/plugins/mcusupport/test/unittest.h @@ -95,6 +95,8 @@ private slots: void test_legacy_createThirdPartyPackage_data(); void test_legacy_createThirdPartyPackage(); + void test_defaultValueForEachOperationSystem(); + private: QVersionNumber currentQulVersion{2, 0}; PackageMock *freeRtosPackage{new PackageMock}; diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index 4fc22f232d6..b682d7a50e5 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -159,6 +159,24 @@ static int queue(const QList &projects, const QList &stepIds, .arg(pro->displayName()) + QLatin1Char('\n')); } } + for (const Project *pro : projects) { + for (const Target *const t : targetsForSelection(pro, configSelection)) { + for (const BuildConfiguration *bc : buildConfigsForSelection(t, configSelection)) { + const IDevice::Ptr device = BuildDeviceKitAspect::device(bc->kit()) + .constCast(); + + if (device && !device->prepareForBuild(t)) { + preambleMessage.append( + BuildManager::tr("The build device failed to prepare for the build of %1 " + "(%2).") + .arg(pro->displayName()) + .arg(t->displayName()) + + QLatin1Char('\n')); + } + } + } + } + for (const Id id : stepIds) { const bool isBuild = id == Constants::BUILDSTEPS_BUILD; const bool isClean = id == Constants::BUILDSTEPS_CLEAN; diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 1e6cc6b2df7..47fe983f06f 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -12,6 +12,9 @@ #include "../kitinformation.h" #include + +#include + #include #include #include @@ -822,6 +825,12 @@ bool IDevice::ensureReachable(const FilePath &other) const return false; } +bool IDevice::prepareForBuild(const Target *target) +{ + Q_UNUSED(target) + return true; +} + void DeviceProcessSignalOperation::setDebuggerCommand(const FilePath &cmd) { m_debuggerCommand = cmd; diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index f98eebb5fa3..06f1e28929d 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -42,6 +42,7 @@ class FileTransferInterface; class FileTransferSetupData; class Kit; class SshParameters; +class Target; class Task; namespace Internal { class IDevicePrivate; } @@ -263,6 +264,8 @@ public: virtual bool ensureReachable(const Utils::FilePath &other) const; + virtual bool prepareForBuild(const Target *target); + protected: IDevice(); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index a84f0fb8ebe..c4704bd7c4a 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2277,6 +2277,9 @@ void ProjectExplorerPlugin::extensionsInitialized() }); mtools->addAction(cmd); + // Load devices immediately, as other plugins might want to use them + DeviceManager::instance()->load(); + // delay restoring kits until UI is shown for improved perceived startup performance QTimer::singleShot(0, this, &ProjectExplorerPlugin::restoreKits); } @@ -2285,7 +2288,6 @@ void ProjectExplorerPlugin::restoreKits() { dd->determineSessionToRestoreAtStartup(); ExtraAbi::load(); // Load this before Toolchains! - DeviceManager::instance()->load(); ToolChainManager::restoreToolChains(); KitManager::restoreKits(); QTimer::singleShot(0, dd, &ProjectExplorerPluginPrivate::restoreSession); // delay a bit... diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp index 4c88d52b821..0010aa53343 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp @@ -69,42 +69,40 @@ static FilePath buildDir(const FilePath &projectFilePath, const Kit *k) projectFilePath, projectName, k, QString(), BuildConfiguration::Unknown, "qbs"); } -static bool hasBuildGraph(const QString &dir) +static bool hasBuildGraph(const FilePath &dir) { - const QString &dirName = QFileInfo(dir).fileName(); - return QFileInfo::exists(dir + QLatin1Char('/') + dirName + QLatin1String(".bg")); + return dir.pathAppended(dir.fileName() + ".bg").exists(); } -static QStringList candidatesForDirectory(const QString &dir) +static FilePaths candidatesForDirectory(const FilePath &dir) { - QStringList candidates; - const QStringList &subDirs = QDir(dir).entryList(QDir::Dirs | QDir::NoDotAndDotDot); - for (const QString &subDir : subDirs) { - const QString absSubDir = dir + QLatin1Char('/') + subDir; - if (hasBuildGraph(absSubDir)) - candidates << absSubDir; + FilePaths candidates; + const FilePaths subDirs = dir.dirEntries(QDir::Dirs | QDir::NoDotAndDotDot); + for (const FilePath &subDir : subDirs) { + if (hasBuildGraph(subDir)) + candidates << subDir; } return candidates; } FilePaths QbsProjectImporter::importCandidates() { - const QString projectDir = projectFilePath().toFileInfo().absolutePath(); - QStringList candidates = candidatesForDirectory(projectDir); + const FilePath projectDir = projectFilePath().absolutePath(); + FilePaths candidates = candidatesForDirectory(projectDir); - QSet seenCandidates; + QSet seenCandidates; seenCandidates.insert(projectDir); const auto &kits = KitManager::kits(); for (Kit * const k : kits) { - QFileInfo fi = buildDir(projectFilePath(), k).toFileInfo(); - const QString candidate = fi.absolutePath(); + FilePath bdir = buildDir(projectFilePath(), k); + const FilePath candidate = bdir.absolutePath(); if (!seenCandidates.contains(candidate)) { seenCandidates.insert(candidate); candidates << candidatesForDirectory(candidate); } } qCDebug(qbsPmLog) << "build directory candidates:" << candidates; - return Utils::transform(candidates, &FilePath::fromString); + return candidates; } QList QbsProjectImporter::examineDirectory(const FilePath &importPath, diff --git a/src/plugins/qmakeprojectmanager/CMakeLists.txt b/src/plugins/qmakeprojectmanager/CMakeLists.txt index 824506d90e7..5ee7324b559 100644 --- a/src/plugins/qmakeprojectmanager/CMakeLists.txt +++ b/src/plugins/qmakeprojectmanager/CMakeLists.txt @@ -3,10 +3,10 @@ add_qtc_plugin(QmakeProjectManager PLUGIN_DEPENDS Core CppEditor QtSupport ResourceEditor TextEditor SOURCES addlibrarywizard.cpp addlibrarywizard.h - customwidgetwizard/classdefinition.cpp customwidgetwizard/classdefinition.h customwidgetwizard/classdefinition.ui + customwidgetwizard/classdefinition.cpp customwidgetwizard/classdefinition.h customwidgetwizard/classlist.cpp customwidgetwizard/classlist.h - customwidgetwizard/customwidgetpluginwizardpage.cpp customwidgetwizard/customwidgetpluginwizardpage.h customwidgetwizard/customwidgetpluginwizardpage.ui - customwidgetwizard/customwidgetwidgetswizardpage.cpp customwidgetwizard/customwidgetwidgetswizardpage.h customwidgetwizard/customwidgetwidgetswizardpage.ui + customwidgetwizard/customwidgetpluginwizardpage.cpp customwidgetwizard/customwidgetpluginwizardpage.h + customwidgetwizard/customwidgetwidgetswizardpage.cpp customwidgetwizard/customwidgetwidgetswizardpage.h customwidgetwizard/customwidgetwizard.cpp customwidgetwizard/customwidgetwizard.h customwidgetwizard/customwidgetwizarddialog.cpp customwidgetwizard/customwidgetwizarddialog.h customwidgetwizard/filenamingparameters.h diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.cpp b/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.cpp index d1e868412af..29e0ee3ee2a 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.cpp +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.cpp @@ -3,7 +3,15 @@ #include "classdefinition.h" +#include +#include + +#include #include +#include +#include +#include +#include namespace QmakeProjectManager { namespace Internal { @@ -12,44 +20,102 @@ ClassDefinition::ClassDefinition(QWidget *parent) : QTabWidget(parent), m_domXmlChanged(false) { - m_ui.setupUi(this); - m_ui.iconPathChooser->setExpectedKind(Utils::PathChooser::File); - m_ui.iconPathChooser->setHistoryCompleter(QLatin1String("Qmake.Icon.History")); - m_ui.iconPathChooser->setPromptDialogTitle(tr("Select Icon")); - m_ui.iconPathChooser->setPromptDialogFilter(tr("Icon files (*.png *.ico *.jpg *.xpm *.tif *.svg)")); + using namespace Utils::Layouting; - connect(m_ui.libraryRadio, &QRadioButton::toggled, this, &ClassDefinition::enableButtons); - connect(m_ui.skeletonCheck, &QCheckBox::toggled, this, &ClassDefinition::enableButtons); - connect(m_ui.widgetLibraryEdit, &QLineEdit::textChanged, + // "Sources" tab + auto sourceTab = new QWidget; + m_libraryRadio = new QRadioButton(tr("&Link library")); + auto includeRadio = new QRadioButton(tr("Include pro&ject")); + includeRadio->setChecked(true); + m_skeletonCheck = new QCheckBox(tr("Create s&keleton")); + m_widgetLibraryLabel = new QLabel(tr("Widget librar&y:")); + m_widgetLibraryEdit = new QLineEdit; + m_widgetProjectLabel = new QLabel(tr("Widget project &file:")); + m_widgetProjectEdit = new QLineEdit; + m_widgetHeaderEdit = new QLineEdit; + m_widgetSourceLabel = new QLabel(tr("Widge&t source file:")); + m_widgetSourceEdit = new QLineEdit; + m_widgetBaseClassLabel = new QLabel(tr("Widget &base class:")); + m_widgetBaseClassEdit = new QLineEdit("QWidget"); + m_pluginClassEdit = new QLineEdit; + m_pluginHeaderEdit = new QLineEdit; + m_pluginSourceEdit = new QLineEdit; + m_iconPathChooser = new Utils::PathChooser; + m_iconPathChooser->setExpectedKind(Utils::PathChooser::File); + m_iconPathChooser->setHistoryCompleter(QLatin1String("Qmake.Icon.History")); + m_iconPathChooser->setPromptDialogTitle(tr("Select Icon")); + m_iconPathChooser->setPromptDialogFilter(tr("Icon files (*.png *.ico *.jpg *.xpm *.tif *.svg)")); + Form { + empty, Row { Column { m_libraryRadio, includeRadio }, m_skeletonCheck}, br, + m_widgetLibraryLabel, m_widgetLibraryEdit, br, + m_widgetProjectLabel, m_widgetProjectEdit, br, + tr("Widget h&eader file:"), m_widgetHeaderEdit, br, + m_widgetSourceLabel, m_widgetSourceEdit, br, + m_widgetBaseClassLabel, m_widgetBaseClassEdit, br, + tr("Plugin class &name:"), m_pluginClassEdit, br, + tr("Plugin &header file:"), m_pluginHeaderEdit, br, + tr("Plugin sou&rce file:"), m_pluginSourceEdit, br, + tr("Icon file:"), m_iconPathChooser, br, + }.attachTo(sourceTab); + addTab(sourceTab, tr("&Sources")); + + // "Description" tab + auto descriptionTab = new QWidget; + m_groupEdit = new QLineEdit; + m_tooltipEdit = new QLineEdit; + m_whatsthisEdit = new QTextEdit; + m_containerCheck = new QCheckBox(tr("The widget is a &container")); + Form { + tr("G&roup:"), m_groupEdit, br, + tr("&Tooltip:"), m_tooltipEdit, br, + tr("W&hat's this:"), m_whatsthisEdit, br, + empty, m_containerCheck, br, + }.attachTo(descriptionTab); + addTab(descriptionTab, tr("&Description")); + + // "Property defaults" tab + auto propertyDefaultsTab = new QWidget; + auto domXmlLabel = new QLabel(tr("dom&XML:")); + m_domXmlEdit = new QTextEdit; + domXmlLabel->setBuddy(m_domXmlEdit); + Column { + domXmlLabel, + m_domXmlEdit, + }.attachTo(propertyDefaultsTab); + addTab(propertyDefaultsTab, tr("Property defa&ults")); + + connect(m_libraryRadio, &QRadioButton::toggled, this, &ClassDefinition::enableButtons); + connect(m_skeletonCheck, &QCheckBox::toggled, this, &ClassDefinition::enableButtons); + connect(m_widgetLibraryEdit, &QLineEdit::textChanged, this, &ClassDefinition::widgetLibraryChanged); - connect(m_ui.widgetHeaderEdit, &QLineEdit::textChanged, + connect(m_widgetHeaderEdit, &QLineEdit::textChanged, this, &ClassDefinition::widgetHeaderChanged); - connect(m_ui.pluginClassEdit, &QLineEdit::textChanged, + connect(m_pluginClassEdit, &QLineEdit::textChanged, this, &ClassDefinition::pluginClassChanged); - connect(m_ui.pluginHeaderEdit, &QLineEdit::textChanged, + connect(m_pluginHeaderEdit, &QLineEdit::textChanged, this, &ClassDefinition::pluginHeaderChanged); - connect(m_ui.domXmlEdit, &QTextEdit::textChanged, + connect(m_domXmlEdit, &QTextEdit::textChanged, this, [this] { m_domXmlChanged = true; }); } void ClassDefinition::enableButtons() { - const bool enLib = m_ui.libraryRadio->isChecked(); - m_ui.widgetLibraryLabel->setEnabled(enLib); - m_ui.widgetLibraryEdit->setEnabled(enLib); + const bool enLib = m_libraryRadio->isChecked(); + m_widgetLibraryLabel->setEnabled(enLib); + m_widgetLibraryEdit->setEnabled(enLib); - const bool enSrc = m_ui.skeletonCheck->isChecked(); - m_ui.widgetSourceLabel->setEnabled(enSrc); - m_ui.widgetSourceEdit->setEnabled(enSrc); - m_ui.widgetBaseClassLabel->setEnabled(enSrc); - m_ui.widgetBaseClassEdit->setEnabled(enSrc); + const bool enSrc = m_skeletonCheck->isChecked(); + m_widgetSourceLabel->setEnabled(enSrc); + m_widgetSourceEdit->setEnabled(enSrc); + m_widgetBaseClassLabel->setEnabled(enSrc); + m_widgetBaseClassEdit->setEnabled(enSrc); const bool enPrj = !enLib || enSrc; - m_ui.widgetProjectLabel->setEnabled(enPrj); - m_ui.widgetProjectEdit->setEnabled(enPrj); - m_ui.widgetProjectEdit->setText( - QFileInfo(m_ui.widgetProjectEdit->text()).completeBaseName() + - (m_ui.libraryRadio->isChecked() ? QLatin1String(".pro") : QLatin1String(".pri"))); + m_widgetProjectLabel->setEnabled(enPrj); + m_widgetProjectEdit->setEnabled(enPrj); + m_widgetProjectEdit->setText( + QFileInfo(m_widgetProjectEdit->text()).completeBaseName() + + (m_libraryRadio->isChecked() ? QLatin1String(".pro") : QLatin1String(".pri"))); } static inline QString xmlFromClassName(const QString &name) @@ -68,59 +134,59 @@ static inline QString xmlFromClassName(const QString &name) void ClassDefinition::setClassName(const QString &name) { - m_ui.widgetLibraryEdit->setText(name.toLower()); - m_ui.widgetHeaderEdit->setText(m_fileNamingParameters.headerFileName(name)); - m_ui.pluginClassEdit->setText(name + QLatin1String("Plugin")); + m_widgetLibraryEdit->setText(name.toLower()); + m_widgetHeaderEdit->setText(m_fileNamingParameters.headerFileName(name)); + m_pluginClassEdit->setText(name + QLatin1String("Plugin")); if (!m_domXmlChanged) { - m_ui.domXmlEdit->setText(xmlFromClassName(name)); + m_domXmlEdit->setText(xmlFromClassName(name)); m_domXmlChanged = false; } } void ClassDefinition::widgetLibraryChanged(const QString &text) { - m_ui.widgetProjectEdit->setText(text + - (m_ui.libraryRadio->isChecked() ? QLatin1String(".pro") : QLatin1String(".pri"))); + m_widgetProjectEdit->setText(text + + (m_libraryRadio->isChecked() ? QLatin1String(".pro") : QLatin1String(".pri"))); } void ClassDefinition::widgetHeaderChanged(const QString &text) { - m_ui.widgetSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(text)); + m_widgetSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(text)); } void ClassDefinition::pluginClassChanged(const QString &text) { - m_ui.pluginHeaderEdit->setText(m_fileNamingParameters.headerFileName(text)); + m_pluginHeaderEdit->setText(m_fileNamingParameters.headerFileName(text)); } void ClassDefinition::pluginHeaderChanged(const QString &text) { - m_ui.pluginSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(text)); + m_pluginSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(text)); } PluginOptions::WidgetOptions ClassDefinition::widgetOptions(const QString &className) const { PluginOptions::WidgetOptions wo; - wo.createSkeleton = m_ui.skeletonCheck->isChecked(); + wo.createSkeleton = m_skeletonCheck->isChecked(); wo.sourceType = - m_ui.libraryRadio->isChecked() ? + m_libraryRadio->isChecked() ? PluginOptions::WidgetOptions::LinkLibrary : PluginOptions::WidgetOptions::IncludeProject; - wo.widgetLibrary = m_ui.widgetLibraryEdit->text(); - wo.widgetProjectFile = m_ui.widgetProjectEdit->text(); + wo.widgetLibrary = m_widgetLibraryEdit->text(); + wo.widgetProjectFile = m_widgetProjectEdit->text(); wo.widgetClassName = className; - wo.widgetHeaderFile = m_ui.widgetHeaderEdit->text(); - wo.widgetSourceFile = m_ui.widgetSourceEdit->text(); - wo.widgetBaseClassName = m_ui.widgetBaseClassEdit->text(); - wo.pluginClassName = m_ui.pluginClassEdit->text(); - wo.pluginHeaderFile = m_ui.pluginHeaderEdit->text(); - wo.pluginSourceFile = m_ui.pluginSourceEdit->text(); - wo.iconFile = m_ui.iconPathChooser->filePath().toString(); - wo.group = m_ui.groupEdit->text(); - wo.toolTip = m_ui.tooltipEdit->text(); - wo.whatsThis = m_ui.whatsthisEdit->toPlainText(); - wo.isContainer = m_ui.containerCheck->isChecked(); - wo.domXml = m_ui.domXmlEdit->toPlainText(); + wo.widgetHeaderFile = m_widgetHeaderEdit->text(); + wo.widgetSourceFile = m_widgetSourceEdit->text(); + wo.widgetBaseClassName = m_widgetBaseClassEdit->text(); + wo.pluginClassName = m_pluginClassEdit->text(); + wo.pluginHeaderFile = m_pluginHeaderEdit->text(); + wo.pluginSourceFile = m_pluginSourceEdit->text(); + wo.iconFile = m_iconPathChooser->filePath().toString(); + wo.group = m_groupEdit->text(); + wo.toolTip = m_tooltipEdit->text(); + wo.whatsThis = m_whatsthisEdit->toPlainText(); + wo.isContainer = m_containerCheck->isChecked(); + wo.domXml = m_domXmlEdit->toPlainText(); return wo; } diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.h b/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.h index aa2e162dd5c..a152b2b533b 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.h +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.h @@ -3,12 +3,21 @@ #pragma once -#include "ui_classdefinition.h" #include "filenamingparameters.h" #include "pluginoptions.h" #include +QT_BEGIN_NAMESPACE +class QCheckBox; +class QLabel; +class QLineEdit; +class QRadioButton; +class QTextEdit; +QT_END_NAMESPACE + +namespace Utils { class PathChooser; } + namespace QmakeProjectManager { namespace Internal { @@ -34,9 +43,29 @@ private Q_SLOTS: void pluginHeaderChanged(const QString &text); private: - Ui::ClassDefinition m_ui; FileNamingParameters m_fileNamingParameters; bool m_domXmlChanged; + + Utils::PathChooser *m_iconPathChooser; + QRadioButton *m_libraryRadio; + QCheckBox *m_skeletonCheck; + QLabel *m_widgetLibraryLabel; + QLineEdit *m_widgetLibraryEdit; + QLabel *m_widgetSourceLabel; + QLineEdit *m_widgetSourceEdit; + QLabel *m_widgetBaseClassLabel; + QLineEdit *m_widgetBaseClassEdit; + QLabel *m_widgetProjectLabel; + QLineEdit *m_widgetProjectEdit; + QLineEdit *m_widgetHeaderEdit; + QLineEdit *m_pluginClassEdit; + QLineEdit *m_pluginSourceEdit; + QLineEdit *m_pluginHeaderEdit; + QLineEdit *m_groupEdit; + QLineEdit *m_tooltipEdit; + QTextEdit *m_whatsthisEdit; + QCheckBox *m_containerCheck; + QTextEdit *m_domXmlEdit; }; } diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.ui b/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.ui deleted file mode 100644 index f459bbc33ef..00000000000 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/classdefinition.ui +++ /dev/null @@ -1,324 +0,0 @@ - - - QmakeProjectManager::Internal::ClassDefinition - - - true - - - - 0 - 0 - 649 - 427 - - - - - - - The header file - - - 0 - - - - &Sources - - - - - - - - Widget librar&y: - - - widgetLibraryEdit - - - - - - - - - - Widget project &file: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - widgetProjectEdit - - - - - - - - - - Widget h&eader file: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - widgetHeaderEdit - - - - - - - The header file has to be specified in source code. - - - - - - - Widge&t source file: - - - widgetSourceEdit - - - - - - - - - - Widget &base class: - - - widgetBaseClassEdit - - - - - - - QWidget - - - - - - - Plugin class &name: - - - pluginClassEdit - - - - - - - - - - Plugin &header file: - - - pluginHeaderEdit - - - - - - - - - - Plugin sou&rce file: - - - pluginSourceEdit - - - - - - - - - - Icon file: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - &Link library - - - false - - - - - - - Create s&keleton - - - true - - - - - - - Include pro&ject - - - true - - - - - - - - - - - - &Description - - - - QFormLayout::ExpandingFieldsGrow - - - - - G&roup: - - - groupEdit - - - - - - - - - - &Tooltip: - - - tooltipEdit - - - - - - - - - - W&hat's this: - - - whatsthisEdit - - - - - - - - 0 - 0 - - - - - 0 - 36 - - - - - 16777215 - 100 - - - - - - - - The widget is a &container - - - - - - - - Property defa&ults - - - - - - - - - dom&XML: - - - domXmlEdit - - - - - - - - - Utils::PathChooser - QWidget -
utils/pathchooser.h
-
-
- - libraryRadio - includeRadio - skeletonCheck - widgetLibraryEdit - widgetProjectEdit - widgetHeaderEdit - widgetSourceEdit - widgetBaseClassEdit - pluginClassEdit - pluginHeaderEdit - pluginSourceEdit - groupEdit - tooltipEdit - whatsthisEdit - containerCheck - domXmlEdit - - - -
diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.cpp b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.cpp index 307872e04ac..e11f474db60 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.cpp +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.cpp @@ -3,10 +3,13 @@ #include "customwidgetpluginwizardpage.h" #include "customwidgetwidgetswizardpage.h" -#include "ui_customwidgetpluginwizardpage.h" +#include #include +#include +#include + namespace QmakeProjectManager { namespace Internal { @@ -18,41 +21,56 @@ static inline QString createPluginName(const QString &prefix) CustomWidgetPluginWizardPage::CustomWidgetPluginWizardPage(QWidget *parent) : QWizardPage(parent), - m_ui(new Ui::CustomWidgetPluginWizardPage), m_classCount(-1), m_complete(false) { - m_ui->setupUi(this); - connect(m_ui->collectionClassEdit, &QLineEdit::textEdited, + m_collectionClassLabel = new QLabel(tr("Collection class:")); + m_collectionClassEdit = new QLineEdit; + m_collectionHeaderLabel = new QLabel(tr("Collection header file:")); + m_collectionHeaderEdit = new QLineEdit; + m_collectionSourceLabel = new QLabel(tr("Collection source file:")); + m_collectionSourceEdit = new QLineEdit; + m_pluginNameEdit = new QLineEdit; + m_resourceFileEdit = new QLineEdit(tr("icons.qrc")); + + using namespace Utils::Layouting; + Column { + tr("Specify the properties of the plugin library and the collection class."), + Space(10), + Form { + m_collectionClassLabel, m_collectionClassEdit, br, + m_collectionHeaderLabel, m_collectionHeaderEdit, br, + m_collectionSourceLabel, m_collectionSourceEdit, br, + tr("Plugin name:"), m_pluginNameEdit, br, + tr("Resource file:"), m_resourceFileEdit, br, + } + }.attachTo(this); + + connect(m_collectionClassEdit, &QLineEdit::textEdited, this, &CustomWidgetPluginWizardPage::slotCheckCompleteness); - connect(m_ui->collectionClassEdit, &QLineEdit::textChanged, + connect(m_collectionClassEdit, &QLineEdit::textChanged, this, [this](const QString &collectionClass) { - m_ui->collectionHeaderEdit->setText(m_fileNamingParameters.headerFileName(collectionClass)); - m_ui->pluginNameEdit->setText(createPluginName(collectionClass)); + m_collectionHeaderEdit->setText(m_fileNamingParameters.headerFileName(collectionClass)); + m_pluginNameEdit->setText(createPluginName(collectionClass)); }); - connect(m_ui->pluginNameEdit, &QLineEdit::textEdited, + connect(m_pluginNameEdit, &QLineEdit::textEdited, this, &CustomWidgetPluginWizardPage::slotCheckCompleteness); - connect(m_ui->collectionHeaderEdit, &QLineEdit::textChanged, + connect(m_collectionHeaderEdit, &QLineEdit::textChanged, this, [this](const QString &text) { - m_ui->collectionSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(text)); + m_collectionSourceEdit->setText(m_fileNamingParameters.headerToSourceFileName(text)); }); setProperty(Utils::SHORT_TITLE_PROPERTY, tr("Plugin Details")); } -CustomWidgetPluginWizardPage::~CustomWidgetPluginWizardPage() -{ - delete m_ui; -} - QString CustomWidgetPluginWizardPage::collectionClassName() const { - return m_ui->collectionClassEdit->text(); + return m_collectionClassEdit->text(); } QString CustomWidgetPluginWizardPage::pluginName() const { - return m_ui->pluginNameEdit->text(); + return m_pluginNameEdit->text(); } void CustomWidgetPluginWizardPage::init(const CustomWidgetWidgetsWizardPage *widgetsPage) @@ -60,37 +78,37 @@ void CustomWidgetPluginWizardPage::init(const CustomWidgetWidgetsWizardPage *wid m_classCount = widgetsPage->classCount(); const QString empty; if (m_classCount == 1) { - m_ui->pluginNameEdit->setText(createPluginName(widgetsPage->classNameAt(0))); + m_pluginNameEdit->setText(createPluginName(widgetsPage->classNameAt(0))); setCollectionEnabled(false); } else { - m_ui->pluginNameEdit->setText(empty); + m_pluginNameEdit->setText(empty); setCollectionEnabled(true); } - m_ui->collectionClassEdit->setText(empty); - m_ui->collectionHeaderEdit->setText(empty); - m_ui->collectionSourceEdit->setText(empty); + m_collectionClassEdit->setText(empty); + m_collectionHeaderEdit->setText(empty); + m_collectionSourceEdit->setText(empty); slotCheckCompleteness(); } void CustomWidgetPluginWizardPage::setCollectionEnabled(bool enColl) { - m_ui->collectionClassLabel->setEnabled(enColl); - m_ui->collectionClassEdit->setEnabled(enColl); - m_ui->collectionHeaderLabel->setEnabled(enColl); - m_ui->collectionHeaderEdit->setEnabled(enColl); - m_ui->collectionSourceLabel->setEnabled(enColl); - m_ui->collectionSourceEdit->setEnabled(enColl); + m_collectionClassLabel->setEnabled(enColl); + m_collectionClassEdit->setEnabled(enColl); + m_collectionHeaderLabel->setEnabled(enColl); + m_collectionHeaderEdit->setEnabled(enColl); + m_collectionSourceLabel->setEnabled(enColl); + m_collectionSourceEdit->setEnabled(enColl); } QSharedPointer CustomWidgetPluginWizardPage::basicPluginOptions() const { QSharedPointer po(new PluginOptions); po->pluginName = pluginName(); - po->resourceFile = m_ui->resourceFileEdit->text(); + po->resourceFile = m_resourceFileEdit->text(); po->collectionClassName = collectionClassName(); - po->collectionHeaderFile = m_ui->collectionHeaderEdit->text(); - po->collectionSourceFile = m_ui->collectionSourceEdit->text(); + po->collectionHeaderFile = m_collectionHeaderEdit->text(); + po->collectionSourceFile = m_collectionSourceEdit->text(); return po; } diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.h b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.h index 344985fae16..d3e64531bbf 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.h +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.h @@ -8,21 +8,23 @@ #include #include +QT_BEGIN_NAMESPACE +class QLineEdit; +class QLabel; +QT_END_NAMESPACE + namespace QmakeProjectManager { namespace Internal { struct PluginOptions; class CustomWidgetWidgetsWizardPage; -namespace Ui { class CustomWidgetPluginWizardPage; } - class CustomWidgetPluginWizardPage : public QWizardPage { Q_OBJECT public: explicit CustomWidgetPluginWizardPage(QWidget *parent = nullptr); - ~CustomWidgetPluginWizardPage() override; void init(const CustomWidgetWidgetsWizardPage *widgetsPage); @@ -40,10 +42,18 @@ private: inline QString pluginName() const; void setCollectionEnabled(bool enColl); - Ui::CustomWidgetPluginWizardPage *m_ui; FileNamingParameters m_fileNamingParameters; int m_classCount; bool m_complete; + + QLabel *m_collectionClassLabel; + QLineEdit *m_collectionClassEdit; + QLabel *m_collectionHeaderLabel; + QLineEdit *m_collectionHeaderEdit; + QLabel *m_collectionSourceLabel; + QLineEdit *m_collectionSourceEdit; + QLineEdit *m_pluginNameEdit; + QLineEdit *m_resourceFileEdit; }; } // namespace Internal diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.ui b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.ui deleted file mode 100644 index 2f70b02a432..00000000000 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetpluginwizardpage.ui +++ /dev/null @@ -1,157 +0,0 @@ - - - QmakeProjectManager::Internal::CustomWidgetPluginWizardPage - - - - 0 - 0 - 591 - 446 - - - - WizardPage - - - Plugin and Collection Class Information - - - - - - Specify the properties of the plugin library and the collection class. - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 10 - - - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Collection class: - - - collectionClassEdit - - - - - - - - - - - - - - Collection header file: - - - collectionHeaderEdit - - - - - - - - - - Collection source file: - - - collectionSourceEdit - - - - - - - - - - Plugin name: - - - pluginNameEdit - - - - - - - - - - Resource file: - - - resourceFileEdit - - - - - - - icons.qrc - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.cpp b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.cpp index 0709532d682..70a1e5a7c0a 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.cpp +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.cpp @@ -2,33 +2,35 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "customwidgetwidgetswizardpage.h" -#include "ui_customwidgetwidgetswizardpage.h" #include "classdefinition.h" +#include "classlist.h" +#include #include #include -#include - -#include #include +#include +#include +#include +#include namespace QmakeProjectManager { namespace Internal { CustomWidgetWidgetsWizardPage::CustomWidgetWidgetsWizardPage(QWidget *parent) : QWizardPage(parent), - m_ui(new Ui::CustomWidgetWidgetsWizardPage), m_tabStackLayout(new QStackedLayout), m_complete(false) { - m_ui->setupUi(this); - m_ui->tabStackWidget->setLayout(m_tabStackLayout); - m_ui->addButton->setIcon(Utils::Icons::PLUS_TOOLBAR.icon()); - connect(m_ui->addButton, &QAbstractButton::clicked, m_ui->classList, &ClassList::startEditingNewClassItem); - m_ui->deleteButton->setIcon(Utils::Icons::MINUS_TOOLBAR.icon()); - connect(m_ui->deleteButton, &QAbstractButton::clicked, m_ui->classList, &ClassList::removeCurrentClass); - m_ui->deleteButton->setEnabled(false); + auto classListLabel = new QLabel(tr("Widget &Classes:")); + auto addButton = new QToolButton; + addButton->setIcon(Utils::Icons::PLUS.icon()); + m_deleteButton = new QToolButton; + m_deleteButton->setIcon(Utils::Icons::MINUS.icon()); + m_deleteButton->setEnabled(false); + m_classList = new ClassList; + classListLabel->setBuddy(m_classList); // Disabled dummy for column>. auto *dummy = new ClassDefinition; @@ -36,23 +38,33 @@ CustomWidgetWidgetsWizardPage::CustomWidgetWidgetsWizardPage(QWidget *parent) : dummy->setEnabled(false); m_tabStackLayout->addWidget(dummy); - connect(m_ui->classList, &ClassList::currentRowChanged, + using namespace Utils::Layouting; + Column { + tr("Specify the list of custom widgets and their properties."), + Space(10), + Row { + Column { + Row { classListLabel, addButton, m_deleteButton }, + m_classList, + }, + m_tabStackLayout, + } + }.attachTo(this); + + connect(m_deleteButton, &QAbstractButton::clicked, m_classList, &ClassList::removeCurrentClass); + connect(addButton, &QAbstractButton::clicked, m_classList, &ClassList::startEditingNewClassItem); + connect(m_classList, &ClassList::currentRowChanged, this, &CustomWidgetWidgetsWizardPage::slotCurrentRowChanged); - connect(m_ui->classList, &ClassList::classAdded, + connect(m_classList, &ClassList::classAdded, this, &CustomWidgetWidgetsWizardPage::slotClassAdded); - connect(m_ui->classList, &ClassList::classDeleted, + connect(m_classList, &ClassList::classDeleted, this, &CustomWidgetWidgetsWizardPage::slotClassDeleted); - connect(m_ui->classList, &ClassList::classRenamed, + connect(m_classList, &ClassList::classRenamed, this, &CustomWidgetWidgetsWizardPage::slotClassRenamed); setProperty(Utils::SHORT_TITLE_PROPERTY, tr("Custom Widgets")); } -CustomWidgetWidgetsWizardPage::~CustomWidgetWidgetsWizardPage() -{ - delete m_ui; -} - bool CustomWidgetWidgetsWizardPage::isComplete() const { return m_complete; @@ -61,13 +73,13 @@ bool CustomWidgetWidgetsWizardPage::isComplete() const void CustomWidgetWidgetsWizardPage::initializePage() { // Takes effect only if visible. - QTimer::singleShot(0, m_ui->classList, &ClassList::startEditingNewClassItem); + QTimer::singleShot(0, m_classList, &ClassList::startEditingNewClassItem); } void CustomWidgetWidgetsWizardPage::slotCurrentRowChanged(int row) { const bool onDummyItem = row == m_tabStackLayout->count() - 1; - m_ui->deleteButton->setEnabled(!onDummyItem); + m_deleteButton->setEnabled(!onDummyItem); m_tabStackLayout->setCurrentIndex(row); } @@ -100,7 +112,7 @@ void CustomWidgetWidgetsWizardPage::slotClassRenamed(int index, const QString &n QString CustomWidgetWidgetsWizardPage::classNameAt(int i) const { - return m_ui->classList->className(i); + return m_classList->className(i); } QList CustomWidgetWidgetsWizardPage::widgetOptions() const diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.h b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.h index 27a4a93e558..be27f8ffcc7 100644 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.h +++ b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.h @@ -10,6 +10,7 @@ #include QT_BEGIN_NAMESPACE +class QToolButton; class QStackedLayout; QT_END_NAMESPACE @@ -17,6 +18,7 @@ namespace QmakeProjectManager { namespace Internal { class ClassDefinition; +class ClassList; struct PluginOptions; namespace Ui { class CustomWidgetWidgetsWizardPage; } @@ -27,7 +29,6 @@ class CustomWidgetWidgetsWizardPage : public QWizardPage public: explicit CustomWidgetWidgetsWizardPage(QWidget *parent = nullptr); - ~CustomWidgetWidgetsWizardPage() override; QList widgetOptions() const; @@ -51,11 +52,12 @@ private Q_SLOTS: private: void updatePluginTab(); - Ui::CustomWidgetWidgetsWizardPage *m_ui; QList m_uiClassDefs; QStackedLayout *m_tabStackLayout; FileNamingParameters m_fileNamingParameters; bool m_complete; + QToolButton *m_deleteButton; + ClassList *m_classList; }; } diff --git a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.ui b/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.ui deleted file mode 100644 index 3b08551f1ee..00000000000 --- a/src/plugins/qmakeprojectmanager/customwidgetwizard/customwidgetwidgetswizardpage.ui +++ /dev/null @@ -1,105 +0,0 @@ - - - QmakeProjectManager::Internal::CustomWidgetWidgetsWizardPage - - - - 0 - 0 - 668 - 475 - - - - Custom Qt Widget Wizard - - - Custom Widget List - - - - - - - 400 - 200 - - - - - - - - - 0 - 400 - - - - - - - - Specify the list of custom widgets and their properties. - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 0 - 10 - - - - - - - - - - Widget &Classes: - - - classList - - - - - - - ... - - - - - - - ... - - - - - - - - - - QmakeProjectManager::Internal::ClassList - QListWidget -
qmakeprojectmanager/customwidgetwizard/classlist.h
-
-
- - classList - - - -
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp index 6b0308fc7b3..8948343eae6 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp @@ -33,11 +33,13 @@ #include using namespace ProjectExplorer; -using namespace QmakeProjectManager; using namespace QtSupport; using namespace Utils; -namespace { +namespace QmakeProjectManager::Internal { + +const Utils::Id QT_IS_TEMPORARY("Qmake.TempQt"); +const char IOSQT[] = "Qt4ProjectManager.QtVersion.Ios"; // ugly struct DirectoryData { @@ -52,38 +54,29 @@ struct DirectoryData QMakeStepConfig::OsType osType; }; -} // namespace - -namespace QmakeProjectManager::Internal { - -const Utils::Id QT_IS_TEMPORARY("Qmake.TempQt"); -const char IOSQT[] = "Qt4ProjectManager.QtVersion.Ios"; // ugly - QmakeProjectImporter::QmakeProjectImporter(const FilePath &path) : QtProjectImporter(path) { } FilePaths QmakeProjectImporter::importCandidates() { - QStringList candidates; + FilePaths candidates; - QFileInfo pfi = projectFilePath().toFileInfo(); - const QString prefix = pfi.baseName(); - candidates << pfi.absolutePath(); + const FilePath pfp = projectFilePath(); + const QString prefix = pfp.baseName(); + candidates << pfp.absolutePath(); - foreach (Kit *k, KitManager::kits()) { + for (Kit *k : KitManager::kits()) { const FilePath sbdir = QmakeBuildConfiguration::shadowBuildDirectory (projectFilePath(), k, QString(), BuildConfiguration::Unknown); - const QString baseDir = sbdir.toFileInfo().absolutePath(); - - foreach (const QString &dir, QDir(baseDir).entryList()) { - const QString path = baseDir + QLatin1Char('/') + dir; - if (dir.startsWith(prefix) && !candidates.contains(path)) + const FilePath baseDir = sbdir.absolutePath(); + for (const FilePath &path : baseDir.dirEntries(QDir::Filters())) { + if (path.fileName().startsWith(prefix) && !candidates.contains(path)) candidates << path; } } - return Utils::transform(candidates, &FilePath::fromString); + return candidates; } QList QmakeProjectImporter::examineDirectory(const FilePath &importPath, diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs index 8d7a0b9edbf..70bfc300b11 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.qbs @@ -50,10 +50,10 @@ Project { name: "Custom Widget Wizard" prefix: "customwidgetwizard/" files: [ - "classdefinition.cpp", "classdefinition.h", "classdefinition.ui", + "classdefinition.cpp", "classdefinition.h", "classlist.cpp", "classlist.h", - "customwidgetpluginwizardpage.cpp", "customwidgetpluginwizardpage.h", "customwidgetpluginwizardpage.ui", - "customwidgetwidgetswizardpage.cpp", "customwidgetwidgetswizardpage.h", "customwidgetwidgetswizardpage.ui", + "customwidgetpluginwizardpage.cpp", "customwidgetpluginwizardpage.h", + "customwidgetwidgetswizardpage.cpp", "customwidgetwidgetswizardpage.h", "customwidgetwizard.cpp", "customwidgetwizard.h", "customwidgetwizarddialog.cpp", "customwidgetwizarddialog.h", "filenamingparameters.h", diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index 0decde20297..0646e8de73d 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -144,7 +144,6 @@ void CurveEditorView::variantPropertiesChanged([[maybe_unused]] const QList &propertyList) { for (const auto &property : propertyList) { - if (property.name() == "keyframes" && property.parentModelNode().isValid()) { + if (property.name() == "keyframes") { ModelNode parent = property.parentModelNode(); if (dirtyfiesView(parent)) updateKeyframes(); @@ -260,10 +259,7 @@ ModelNode getTargetNode(PropertyTreeItem *item, const QmlTimeline &timeline) QmlTimelineKeyframeGroup timelineKeyframeGroup(QmlTimeline &timeline, PropertyTreeItem *item) { ModelNode node = getTargetNode(item, timeline); - if (node.isValid()) - return timeline.keyframeGroup(node, item->name().toLatin1()); - - return QmlTimelineKeyframeGroup(); + return timeline.keyframeGroup(node, item->name().toLatin1()); } void attachEasingCurve(const QmlTimelineKeyframeGroup &group, double frame, const QEasingCurve &curve) @@ -277,23 +273,21 @@ void attachEasingCurve(const QmlTimelineKeyframeGroup &group, double frame, cons void commitAuxiliaryData(ModelNode &node, TreeItem *item) { - if (node.isValid()) { - if (item->locked()) - node.setLocked(true); - else - node.setLocked(false); + if (item->locked()) + node.setLocked(true); + else + node.setLocked(false); - if (item->pinned()) - node.setAuxiliaryData(pinnedProperty, true); - else - node.removeAuxiliaryData(pinnedProperty); + if (item->pinned()) + node.setAuxiliaryData(pinnedProperty, true); + else + node.removeAuxiliaryData(pinnedProperty); - if (auto *pitem = item->asPropertyItem()) { - if (pitem->hasUnified()) - node.setAuxiliaryData(unifiedProperty, pitem->unifyString()); - else - node.removeAuxiliaryData(unifiedProperty); - } + if (auto *pitem = item->asPropertyItem()) { + if (pitem->hasUnified()) + node.setAuxiliaryData(unifiedProperty, pitem->unifyString()); + else + node.removeAuxiliaryData(unifiedProperty); } } diff --git a/src/plugins/qmldesigner/components/pathtool/pathtoolview.cpp b/src/plugins/qmldesigner/components/pathtool/pathtoolview.cpp index b6d30acfd87..20538573148 100644 --- a/src/plugins/qmldesigner/components/pathtool/pathtoolview.cpp +++ b/src/plugins/qmldesigner/components/pathtool/pathtoolview.cpp @@ -21,13 +21,12 @@ PathToolView::PathToolView(PathTool *pathTool) static bool isInEditedPath(const NodeAbstractProperty &propertyParent, const ModelNode &editingPathViewModelNode) { - if (editingPathViewModelNode.isValid()) { - if (editingPathViewModelNode.hasNodeProperty("path")) { - ModelNode pathModelNode = editingPathViewModelNode.nodeProperty("path").modelNode(); - if (pathModelNode.metaInfo().isQtQuickPath()) { - if (propertyParent.name() == "pathElements" && propertyParent.parentModelNode() == pathModelNode) - return true; - } + if (editingPathViewModelNode.hasNodeProperty("path")) { + ModelNode pathModelNode = editingPathViewModelNode.nodeProperty("path").modelNode(); + if (pathModelNode.metaInfo().isQtQuickPath()) { + if (propertyParent.name() == "pathElements" + && propertyParent.parentModelNode() == pathModelNode) + return true; } } diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp index dd93f7f9003..84e7b8284e0 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp @@ -34,7 +34,7 @@ int GradientModel::rowCount(const QModelIndex & /*parent*/) const QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode(); - if (gradientNode.isValid() && gradientNode.hasNodeListProperty("stops")) + if (gradientNode.hasNodeListProperty("stops")) return gradientNode.nodeListProperty("stops").toModelNodeList().count(); } } diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index ad52e4aa52f..6c41274a51a 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -808,7 +808,7 @@ NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node) if (!node.isValid()) return node.metaInfo(); - if (auto metaInfo = node.metaInfo(); metaInfo.isValid()) + if (auto metaInfo = node.metaInfo()) return metaInfo; AbstractView *view = node.view(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index d3fcbb644d2..be62ce4684c 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -38,13 +38,10 @@ PropertyEditorValue::PropertyEditorValue(QObject *parent) QVariant PropertyEditorValue::value() const { QVariant returnValue = m_value; - if (modelNode().isValid()) { - if (auto metaInfo = modelNode().metaInfo(); - metaInfo.isValid() && metaInfo.hasProperty(name()) - && metaInfo.property(name()).propertyType().isUrl()) { - returnValue = returnValue.toUrl().toString(); - } + if (auto metaInfo = modelNode().metaInfo(); metaInfo.property(name()).propertyType().isUrl()) { + returnValue = returnValue.toUrl().toString(); } + return returnValue; } @@ -82,30 +79,24 @@ static void fixAmbigousColorNames(const QmlDesigner::ModelNode &modelNode, const QmlDesigner::PropertyName &name, QVariant *value) { - if (modelNode.isValid()) { - if (auto metaInfo = modelNode.metaInfo(); - metaInfo.isValid() && metaInfo.property(name).propertyType().isColor()) { - if ((value->type() == QVariant::Color)) { - QColor color = value->value(); - int alpha = color.alpha(); - color = QColor(color.name()); - color.setAlpha(alpha); - *value = color; - } else if (value->toString() != QStringLiteral("transparent")) { - *value = QColor(value->toString()).name(QColor::HexArgb); - } + if (auto metaInfo = modelNode.metaInfo(); metaInfo.property(name).propertyType().isColor()) { + if ((value->type() == QVariant::Color)) { + QColor color = value->value(); + int alpha = color.alpha(); + color = QColor(color.name()); + color.setAlpha(alpha); + *value = color; + } else if (value->toString() != QStringLiteral("transparent")) { + *value = QColor(value->toString()).name(QColor::HexArgb); } } } static void fixUrl(const QmlDesigner::ModelNode &modelNode, const QmlDesigner::PropertyName &name, QVariant *value) { - if (modelNode.isValid()) { - if (auto metaInfo = modelNode.metaInfo(); - metaInfo.isValid() && metaInfo.property(name).propertyType().isUrl()) - - if (!value->isValid()) - *value = QStringLiteral(""); + if (auto metaInfo = modelNode.metaInfo(); metaInfo.property(name).propertyType().isUrl()) { + if (!value->isValid()) + *value = QStringLiteral(""); } } @@ -124,12 +115,8 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value) { if (!compareVariants(value, m_value ) || isBound()) { QVariant newValue = value; - if (modelNode().isValid()) { - if (auto metaInfo = modelNode().metaInfo(); - metaInfo.isValid() && metaInfo.hasProperty(name()) - && metaInfo.property(name()).propertyType().isUrl()) { - newValue = QUrl(newValue.toString()); - } + if (auto metaInfo = modelNode().metaInfo(); metaInfo.property(name()).propertyType().isUrl()) { + newValue = QUrl(newValue.toString()); } if (cleverDoubleCompare(newValue, m_value)) @@ -212,7 +199,7 @@ bool PropertyEditorValue::isBound() const bool PropertyEditorValue::isInModel() const { - return modelNode().isValid() && modelNode().hasProperty(name()); + return modelNode().hasProperty(name()); } QmlDesigner::PropertyName PropertyEditorValue::name() const @@ -248,7 +235,7 @@ bool PropertyEditorValue::isTranslated() const metaInfo.isValid() && metaInfo.hasProperty(name()) && metaInfo.property(name()).propertyType().isString()) { const QmlDesigner::QmlObjectNode objectNode(modelNode()); - if (objectNode.isValid() && objectNode.hasBindingProperty(name())) { + if (objectNode.hasBindingProperty(name())) { const QRegularExpression rx( QRegularExpression::anchoredPattern("qsTr(|Id|anslate)\\(\".*\"\\)")); //qsTr() @@ -422,7 +409,7 @@ QString PropertyEditorValue::getTranslationContext() const metaInfo.isValid() && metaInfo.hasProperty(name()) && metaInfo.property(name()).propertyType().isString()) { const QmlDesigner::QmlObjectNode objectNode(modelNode()); - if (objectNode.isValid() && objectNode.hasBindingProperty(name())) { + if (objectNode.hasBindingProperty(name())) { const QRegularExpression rx(QRegularExpression::anchoredPattern( "qsTranslate\\(\"(.*)\"\\s*,\\s*\".*\"\\s*\\)")); const QRegularExpressionMatch match = rx.match(expression()); @@ -438,7 +425,7 @@ bool PropertyEditorValue::isIdList() const { if (modelNode().isValid() && modelNode().metaInfo().isValid() && modelNode().metaInfo().hasProperty(name())) { const QmlDesigner::QmlObjectNode objectNode(modelNode()); - if (objectNode.isValid() && objectNode.hasBindingProperty(name())) { + if (objectNode.hasBindingProperty(name())) { static const QRegularExpression rx(QRegularExpression::anchoredPattern( "^[a-z_]\\w*|^[A-Z]\\w*\\.{1}([a-z_]\\w*\\.?)+")); const QString exp = objectNode.propertyAffectedByCurrentState(name()) ? expression() : modelNode().bindingProperty(name()).expression(); @@ -586,11 +573,7 @@ bool PropertyEditorNodeWrapper::exists() QString PropertyEditorNodeWrapper::type() { - if (!(m_modelNode.isValid())) - return QString(); - return m_modelNode.simplifiedTypeName(); - } QmlDesigner::ModelNode PropertyEditorNodeWrapper::parentModelNode() const @@ -635,8 +618,7 @@ void PropertyEditorNodeWrapper::add(const QString &type) void PropertyEditorNodeWrapper::remove() { if ((m_editorValue && m_editorValue->modelNode().isValid())) { - if (QmlDesigner::QmlObjectNode(m_modelNode).isValid()) - QmlDesigner::QmlObjectNode(m_modelNode).destroy(); + QmlDesigner::QmlObjectNode(m_modelNode).destroy(); m_editorValue->modelNode().removeProperty(m_editorValue->name()); } else { qWarning("PropertyEditorNodeWrapper::remove failed - node invalid"); @@ -675,13 +657,12 @@ void PropertyEditorNodeWrapper::setup() Q_ASSERT(m_editorValue); Q_ASSERT(m_editorValue->modelNode().isValid()); if ((m_editorValue->modelNode().isValid() && m_modelNode.isValid())) { - QmlDesigner::QmlObjectNode qmlObjectNode(m_modelNode); const QStringList propertyNames = m_valuesPropertyMap.keys(); for (const QString &propertyName : propertyNames) m_valuesPropertyMap.clear(propertyName); qDeleteAll(m_valuesPropertyMap.children()); - if (qmlObjectNode.isValid()) { + if (QmlDesigner::QmlObjectNode qmlObjectNode = m_modelNode) { for (const auto &property : m_modelNode.metaInfo().properties()) { const auto &propertyName = property.name(); auto valueObject = new PropertyEditorValue(&m_valuesPropertyMap); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index 183197a452d..66036118aa9 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -161,8 +161,8 @@ void PropertyEditorView::changeValue(const QString &name) QVariant castedValue; - if (metaInfo.isValid() && metaInfo.hasProperty(propertyName)) { - castedValue = metaInfo.property(propertyName).castedValue(value->value()); + if (auto property = metaInfo.property(propertyName)) { + castedValue = property.castedValue(value->value()); } else if (propertyIsAttachedLayoutProperty(propertyName)) { castedValue = value->value(); } else { @@ -177,8 +177,7 @@ void PropertyEditorView::changeValue(const QString &name) bool propertyTypeUrl = false; - if (metaInfo.isValid() && metaInfo.hasProperty(propertyName) - && metaInfo.property(propertyName).propertyType().isUrl()) { + if (metaInfo.property(propertyName).propertyType().isUrl()) { // turn absolute local file paths into relative paths propertyTypeUrl = true; QString filePath = castedValue.toUrl().toString(); @@ -247,9 +246,8 @@ void PropertyEditorView::changeExpression(const QString &propertyName) return; } - if (auto metaInfo = qmlObjectNode->modelNode().metaInfo(); - metaInfo.isValid() && metaInfo.hasProperty(name)) { - const auto &propertType = metaInfo.property(name).propertyType(); + if (auto property = qmlObjectNode->modelNode().metaInfo().property(name)) { + const auto &propertType = property.propertyType(); if (propertType.isColor()) { if (QColor(value->expression().remove('"')).isValid()) { qmlObjectNode->setVariantProperty(name, QColor(value->expression().remove('"'))); @@ -642,7 +640,7 @@ void PropertyEditorView::propertiesRemoved(const QList& proper if ("width" == property.name() || "height" == property.name()) { const QmlItemNode qmlItemNode = m_selectedNode; - if (qmlItemNode.isValid() && qmlItemNode.isInLayout()) + if (qmlItemNode.isInLayout()) resetPuppet(); } diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp index 270d51239dd..f2adcf4f363 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp @@ -100,20 +100,13 @@ QVariant StatesEditorModel::data(const QModelIndex &index, int role) const return index.internalId(); case HasWhenCondition: - return stateNode.isValid() && stateNode.hasProperty("when"); + return stateNode.hasProperty("when"); - case WhenConditionString: { - if (stateNode.isValid() && stateNode.hasBindingProperty("when")) - return stateNode.bindingProperty("when").expression(); - else - return QString(); - } + case WhenConditionString: + return stateNode.bindingProperty("when").expression(); case IsDefault: { - QmlModelState modelState(stateNode); - if (modelState.isValid()) - return modelState.isDefault(); - return false; + return QmlModelState(stateNode).isDefault(); } case ModelHasDefaultState: diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index 054a1f4e005..f70789310cc 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -346,9 +346,7 @@ void StatesEditorView::resetWhenCondition(int internalNodeId) if (hasModelNodeForInternalId(internalNodeId)) { QmlModelState state(modelNodeForInternalId(internalNodeId)); try { - if (state.isValid() && state.modelNode().hasProperty("when")) - state.modelNode().removeProperty("when"); - + state.modelNode().removeProperty("when"); } catch (const RewritingException &e) { e.showException(); } @@ -409,9 +407,7 @@ void StatesEditorView::setAnnotation(int internalNodeId) QmlModelState state(modelNodeForInternalId(internalNodeId)); try { if (state.isValid()) { - ModelNode modelNode = state.modelNode(); - - if (modelNode.isValid()) { + if (ModelNode modelNode = state.modelNode()) { if (!m_editor) m_editor = new AnnotationEditor(this); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineactions.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineactions.cpp index 1a38096ddaa..33c8424a0b0 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineactions.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineactions.cpp @@ -142,15 +142,12 @@ void TimelineActions::copyKeyframes(const QList &keyframes) bool isKeyframe(const ModelNode &node) { - return node.isValid() && node.metaInfo().isQtQuickTimelineKeyframe(); + return node.metaInfo().isQtQuickTimelineKeyframe(); } QVariant getValue(const ModelNode &node) { - if (node.isValid()) - return node.variantProperty("value").value(); - - return QVariant(); + return node.variantProperty("value").value(); } qreal getTime(const ModelNode &node) diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp index 15f23a4e30b..dfa00985dd3 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp @@ -769,7 +769,7 @@ void TimelineGraphicsScene::deleteKeyframes(const QList &frames) ModelNode frame = keyframe; ModelNode parent = frame.parentProperty().parentModelNode(); keyframe.destroy(); - if (parent.isValid() && parent.defaultNodeListProperty().isEmpty()) + if (parent.defaultNodeListProperty().isEmpty()) parent.destroy(); } } diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp index 89e2fcec756..8acc90def2b 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinepropertyitem.cpp @@ -257,10 +257,7 @@ void TimelinePropertyItem::updateFrames() bool TimelinePropertyItem::isSelected() const { - if (m_frames.isValid() && m_frames.target().isValid()) - return m_frames.target().isSelected(); - - return false; + return m_frames.target().isSelected(); } QString convertVariant(const QVariant &variant) @@ -564,7 +561,7 @@ void TimelineKeyframeItem::enableUpdates() bool TimelineKeyframeItem::hasManualBezier() const { - return m_frame.isValid() && m_frame.hasProperty("easing.bezierCurve"); + return m_frame.hasProperty("easing.bezierCurve"); } void TimelineKeyframeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp index c7e2cd267b5..3c625dec88f 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinesectionitem.cpp @@ -187,7 +187,7 @@ AbstractView *TimelineSectionItem::view() const bool TimelineSectionItem::isSelected() const { - return m_targetNode.isValid() && m_targetNode.isSelected(); + return m_targetNode.isSelected(); } ModelNode TimelineSectionItem::targetNode() const @@ -967,7 +967,7 @@ void TimelineBarItem::commitPosition(const QPointF & /*point*/) bool TimelineBarItem::isLocked() const { - return sectionItem()->targetNode().isValid() && sectionItem()->targetNode().locked(); + return sectionItem()->targetNode().locked(); } TimelineBarItem *TimelineBarItem::asTimelineBarItem() @@ -994,13 +994,10 @@ void TimelineBarItem::paint(QPainter *painter, const QColor indicatorColor = Theme::getColor(Theme::PanelTextColorLight); ModelNode target = sectionItem()->targetNode(); - if (target.isValid()) { - QColor overrideColor = target.auxiliaryDataWithDefault(timelineOverrideColorProperty) - .value(); - if (overrideColor.isValid()) { - brushColorSelected = overrideColor; - brushColor = brushColorSelected.darker(120); - } + QColor overrideColor = target.auxiliaryDataWithDefault(timelineOverrideColorProperty).value(); + if (overrideColor.isValid()) { + brushColorSelected = overrideColor; + brushColor = brushColorSelected.darker(120); } const QRectF itemRect = rect(); @@ -1079,8 +1076,7 @@ void TimelineBarItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) QAction* resetColor = menu.addAction(tr("Reset Color")); auto reset = [this]() { ModelNode target = sectionItem()->targetNode(); - if (target.isValid()) - target.removeAuxiliaryData(timelineOverrideColorProperty); + target.removeAuxiliaryData(timelineOverrideColorProperty); }; QObject::connect(resetColor, &QAction::triggered, reset); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinesettingsmodel.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinesettingsmodel.cpp index 9aaa1a38cdc..e0f031f4e45 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinesettingsmodel.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinesettingsmodel.cpp @@ -208,9 +208,9 @@ void TimelineSettingsModel::addState(const ModelNode &state) QList items; QmlTimeline timeline = timelineView()->timelineForState(state); - const QString timelineId = timeline.isValid() ? timeline.modelNode().id() : QString(""); + const QString timelineId = timeline.modelNode().id(); ModelNode animation = animationForTimelineAndState(timeline, state); - const QString animationId = animation.isValid() ? animation.id() : QString(""); + const QString animationId = animation.id(); QStandardItem *stateItem = createStateItem(state); auto *timelinelItem = new QStandardItem(timelineId); @@ -318,34 +318,24 @@ void TimelineSettingsModel::updateAnimation(int row) ModelNode oldAnimation = animationForTimelineAndState(oldTimeline, modelState); if (modelState.isBaseState()) { - if (oldAnimation.isValid()) - oldAnimation.variantProperty("running").setValue(false); - if (animation.isValid()) - animation.variantProperty("running").setValue(true); - if (timeline.isValid() && timeline.modelNode().hasProperty("currentFrame")) - timeline.modelNode().removeProperty("currentFrame"); + oldAnimation.variantProperty("running").setValue(false); + animation.variantProperty("running").setValue(true); + timeline.modelNode().removeProperty("currentFrame"); } else { - if (oldAnimation.isValid() && modelState.affectsModelNode(oldAnimation)) { + if (modelState.affectsModelNode(oldAnimation)) { QmlPropertyChanges propertyChanges(modelState.propertyChanges(oldAnimation)); - if (propertyChanges.isValid() && propertyChanges.modelNode().hasProperty("running")) - propertyChanges.modelNode().removeProperty("running"); + propertyChanges.modelNode().removeProperty("running"); } - ModelNode baseAnimation(animationForRow(0)); - - if (baseAnimation.isValid()) { + if (ModelNode baseAnimation = animationForRow(0)) { QmlPropertyChanges propertyChanges(modelState.propertyChanges(baseAnimation)); - if (propertyChanges.isValid()) { - propertyChanges.modelNode().variantProperty("running").setValue(false); - if (propertyChanges.modelNode().hasProperty("currentFrame")) - propertyChanges.modelNode().removeProperty("currentFrame"); - } + propertyChanges.modelNode().variantProperty("running").setValue(false); + propertyChanges.modelNode().removeProperty("currentFrame"); } if (animation.isValid()) { /* If animation is invalid 'none' was selected */ QmlPropertyChanges propertyChanges(modelState.propertyChanges(animation)); - if (propertyChanges.isValid()) - propertyChanges.modelNode().variantProperty("running").setValue(true); + propertyChanges.modelNode().variantProperty("running").setValue(true); } } }); @@ -363,20 +353,17 @@ void TimelineSettingsModel::updateFixedFrameRow(int row) int fixedFrame = fixedFrameForRow(row); if (modelState.isBaseState()) { - if (animation.isValid()) - animation.variantProperty("running").setValue(false); - if (timeline.isValid()) - timeline.modelNode().variantProperty("currentFrame").setValue(fixedFrame); + animation.variantProperty("running").setValue(false); + timeline.modelNode().variantProperty("currentFrame").setValue(fixedFrame); } else { - if (animation.isValid() && modelState.affectsModelNode(animation)) { + if (modelState.affectsModelNode(animation)) { QmlPropertyChanges propertyChanges(modelState.propertyChanges(animation)); - if (propertyChanges.isValid() && propertyChanges.modelNode().hasProperty("running")) + if (propertyChanges.modelNode().hasProperty("running")) propertyChanges.modelNode().removeProperty("running"); } QmlPropertyChanges propertyChanges(modelState.propertyChanges(timeline)); - if (propertyChanges.isValid()) - propertyChanges.modelNode().variantProperty("currentFrame").setValue(fixedFrame); + propertyChanges.modelNode().variantProperty("currentFrame").setValue(fixedFrame); } }); @@ -394,10 +381,8 @@ void TimelineSettingsModel::resetRow(int row) QmlTimeline timeline(timelineForRow(row)); ModelNode animation = animationForTimelineAndState(timeline, modelState); - if (animationItem) { - const QString animationId = animation.isValid() ? animation.id() : QString(); - animationItem->setText(animationId); - } + if (animationItem) + animationItem->setText(animation.id()); if (fixedFrameItem) { auto fixedValue = propertyValueForState(timeline, modelState, "currentFrame"); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp index 1f3e5184fcd..2dff844ef14 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp @@ -98,22 +98,16 @@ void TimelineView::nodeAboutToBeRemoved(const ModelNode &removedNode) if (lastId != currentId) m_timelineWidget->setTimelineId(currentId); - } else if (removedNode.parentProperty().isValid() - && QmlTimeline::isValidQmlTimeline( - removedNode.parentProperty().parentModelNode())) { - if (removedNode.hasBindingProperty("target")) { - const ModelNode target = removedNode.bindingProperty("target").resolveToModelNode(); - if (target.isValid()) { - QmlTimeline timeline(removedNode.parentProperty().parentModelNode()); - if (timeline.hasKeyframeGroupForTarget(target)) - QTimer::singleShot(0, [this, target, timeline]() { - if (timeline.hasKeyframeGroupForTarget(target)) - m_timelineWidget->graphicsScene()->invalidateSectionForTarget( - target); - else - m_timelineWidget->graphicsScene()->invalidateScene(); - }); - } + } else if (QmlTimeline::isValidQmlTimeline(removedNode.parentProperty().parentModelNode())) { + if (const ModelNode target = removedNode.bindingProperty("target").resolveToModelNode()) { + QmlTimeline timeline(removedNode.parentProperty().parentModelNode()); + if (timeline.hasKeyframeGroupForTarget(target)) + QTimer::singleShot(0, [this, target, timeline]() { + if (timeline.hasKeyframeGroupForTarget(target)) + m_timelineWidget->graphicsScene()->invalidateSectionForTarget(target); + else + m_timelineWidget->graphicsScene()->invalidateScene(); + }); } } } @@ -190,7 +184,6 @@ void TimelineView::variantPropertiesChanged(const QList &proper for (const auto &property : propertyList) { if ((property.name() == "frame" || property.name() == "value") && property.parentModelNode().type() == "QtQuick.Timeline.Keyframe" - && property.parentModelNode().isValid() && property.parentModelNode().hasParentProperty()) { const ModelNode framesNode = property.parentModelNode().parentProperty().parentModelNode(); diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorgraphicslayout.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorgraphicslayout.cpp index 8db8f94f0f2..ef390fe2dde 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorgraphicslayout.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorgraphicslayout.cpp @@ -94,10 +94,8 @@ void TransitionEditorGraphicsLayout::setTransition(const ModelNode &transition) m_rulerItem->setParentItem(this); qreal duration = 2000; - if (transition.isValid()) { - if (auto data = transition.auxiliaryData(transitionDurationProperty)) - duration = data->toDouble(); - } + if (auto data = transition.auxiliaryData(transitionDurationProperty)) + duration = data->toDouble(); setDuration(duration); m_layout->addItem(m_rulerItem); @@ -107,11 +105,9 @@ void TransitionEditorGraphicsLayout::setTransition(const ModelNode &transition) m_layout->invalidate(); - if (transition.isValid() && !transition.directSubModelNodes().isEmpty()) { - for (const ModelNode ¶llel : transition.directSubModelNodes()) { - auto item = TransitionEditorSectionItem::create(parallel, this); - m_layout->addItem(item); - } + for (const ModelNode ¶llel : transition.directSubModelNodes()) { + auto item = TransitionEditorSectionItem::create(parallel, this); + m_layout->addItem(item); } m_placeholder2->setParentItem(this); diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorgraphicsscene.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorgraphicsscene.cpp index dd7cff14630..84b3c9307a8 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorgraphicsscene.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorgraphicsscene.cpp @@ -126,8 +126,7 @@ void TransitionEditorGraphicsScene::invalidateLayout() void TransitionEditorGraphicsScene::setDuration(int duration) { - if (m_transition.isValid()) - m_transition.setAuxiliaryData(transitionDurationProperty, duration); + m_transition.setAuxiliaryData(transitionDurationProperty, duration); m_layout->setDuration(duration); qreal scaling = m_layout->rulerScaling(); setZoom(scaling); diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsectionitem.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsectionitem.cpp index a6220286f11..70cf5c1b287 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsectionitem.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsectionitem.cpp @@ -244,7 +244,7 @@ AbstractView *TransitionEditorSectionItem::view() const bool TransitionEditorSectionItem::isSelected() const { - return m_targetNode.isValid() && m_targetNode.isSelected(); + return m_targetNode.isSelected(); } ModelNode TransitionEditorSectionItem::targetNode() const diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsettingsdialog.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsettingsdialog.cpp index 1b35506dc1b..ec4e07c62d9 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsettingsdialog.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorsettingsdialog.cpp @@ -76,8 +76,7 @@ TransitionEditorSettingsDialog::TransitionEditorSettingsDialog(QWidget *parent, }); connect(transitionRemoveAction, &QAction::triggered, this, [this]() { - ModelNode transition = getTransitionFromTabWidget(ui->timelineTab); - if (transition.isValid()) { + if (ModelNode transition = getTransitionFromTabWidget(ui->timelineTab)) { transition.destroy(); setupTransitions({}); } diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditortoolbar.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditortoolbar.cpp index 8475bb0d421..383d313ffdf 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditortoolbar.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditortoolbar.cpp @@ -105,11 +105,9 @@ QString TransitionEditorToolBar::currentTransitionId() const void TransitionEditorToolBar::updateComboBox(const ModelNode &root) { - if (root.isValid() && root.hasProperty("transitions")) { - NodeAbstractProperty transitions = root.nodeAbstractProperty("transitions"); - if (transitions.isValid()) - for (const ModelNode &transition : transitions.directSubNodes()) - m_transitionComboBox->addItem(transition.id()); + if (NodeAbstractProperty transitions = root.nodeAbstractProperty("transitions")) { + for (const ModelNode &transition : transitions.directSubNodes()) + m_transitionComboBox->addItem(transition.id()); } } diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp index 12bf9759a5e..9bf04e8e0c5 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp @@ -78,7 +78,7 @@ void TransitionEditorView::nodeRemoved(const ModelNode & removedNode, widget()->updateData(removedNode); const ModelNode parent = parentProperty.parentModelNode(); - if (parent.isValid() && parent.metaInfo().isQtQuickTransition()) + if (parent.metaInfo().isQtQuickTransition()) asyncUpdate(parent); } @@ -92,7 +92,7 @@ void TransitionEditorView::nodeReparented(const ModelNode &node, const ModelNode parent = newPropertyParent.parentModelNode(); - if (parent.isValid() && parent.metaInfo().isValid() && parent.metaInfo().isQtQuickTransition()) { + if (parent.metaInfo().isQtQuickTransition()) { asyncUpdate(parent); } } @@ -198,10 +198,10 @@ ModelNode TransitionEditorView::addNewTransition() for (const QmlPropertyChanges & change : state.propertyChanges()) { QStringList locList; const ModelNode target = change.target(); - if (target.isValid() && target.hasMetaInfo()) { + if (auto targetMetaInfo = target.metaInfo()) { const QString targetId = target.id(); for (const VariantProperty &property : change.modelNode().variantProperties()) { - auto type = target.metaInfo().property(property.name()).propertyType(); + auto type = targetMetaInfo.property(property.name()).propertyType(); if (type.isInteger() || type.isColor() || type.isFloat()) locList.append(QString::fromUtf8(property.name())); @@ -336,12 +336,7 @@ void TransitionEditorView::openSettingsDialog() QList TransitionEditorView::allTransitions() const { - if (rootModelNode().isValid() && rootModelNode().hasProperty("transitions")) { - NodeAbstractProperty transitions = rootModelNode().nodeAbstractProperty("transitions"); - if (transitions.isValid()) - return transitions.directSubNodes(); - } - return {}; + return rootModelNode().nodeAbstractProperty("transitions").directSubNodes(); } void TransitionEditorView::asyncUpdate(const ModelNode &transition) diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp index 43f8f10545a..b0090e29821 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp @@ -323,13 +323,10 @@ void TransitionEditorWidget::init(int zoom) ModelNode root = transitionEditorView()->rootModelNode(); ModelNode transition; - if (root.isValid() && root.hasProperty("transitions")) { - NodeAbstractProperty transitions = root.nodeAbstractProperty("transitions"); - if (transitions.isValid()) { - const QList directSubNodes = transitions.directSubNodes(); - if (!directSubNodes.isEmpty()) - transition = directSubNodes.constFirst(); - } + if (NodeAbstractProperty transitions = root.nodeAbstractProperty("transitions")) { + const QList directSubNodes = transitions.directSubNodes(); + if (!directSubNodes.isEmpty()) + transition = directSubNodes.constFirst(); } m_graphicsScene->setTransition(transition); @@ -342,10 +339,9 @@ void TransitionEditorWidget::init(int zoom) m_toolbar->setCurrentTransition(transition); qreal duration = 2000; - if (transition.isValid()) { - if (auto data = transition.auxiliaryData(transitionDurationProperty)) - duration = data->toDouble(); - } + if (auto data = transition.auxiliaryData(transitionDurationProperty)) + duration = data->toDouble(); + m_toolbar->setDuration(duration); m_graphicsScene->setZoom(zoom); @@ -358,8 +354,7 @@ void TransitionEditorWidget::updateData(const ModelNode &transition) return; } - if (transition.metaInfo().isValid() - && transition.metaInfo().isQtQuickTransition()) { + if (transition.metaInfo().isQtQuickTransition()) { if (transition.id() == m_toolbar->currentTransitionId()) { m_graphicsScene->setTransition(transition); } else { diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitionform.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitionform.cpp index b6c6d0ff16c..26edb096f40 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitionform.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitionform.cpp @@ -159,29 +159,27 @@ void TransitionForm::setupStatesLists() toList = m_transition.variantProperty("to").value().toString().split(","); } - if (m_transition.isValid()) { - const QmlItemNode root(m_transition.view()->rootModelNode()); - if (root.isValid()) { - const QmlModelStateGroup states = root.states(); - for (const QString &stateName : states.names()) { - auto itemTo = new QListWidgetItem(stateName, ui->listWidgetTo); - ui->listWidgetTo->addItem(itemTo); - itemTo->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - if (starTo || toList.contains(stateName)) - itemTo->setCheckState(Qt::Checked); - else - itemTo->setCheckState(Qt::Unchecked); + if (const QmlItemNode root = m_transition.view()->rootModelNode()) { + const QmlModelStateGroup states = root.states(); + for (const QString &stateName : states.names()) { + auto itemTo = new QListWidgetItem(stateName, ui->listWidgetTo); + ui->listWidgetTo->addItem(itemTo); + itemTo->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + if (starTo || toList.contains(stateName)) + itemTo->setCheckState(Qt::Checked); + else + itemTo->setCheckState(Qt::Unchecked); - auto itemFrom = new QListWidgetItem(stateName, ui->listWidgetFrom); - ui->listWidgetFrom->addItem(itemFrom); - itemFrom->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); - if (starFrom || fromList.contains(stateName)) - itemFrom->setCheckState(Qt::Checked); - else - itemFrom->setCheckState(Qt::Unchecked); - } + auto itemFrom = new QListWidgetItem(stateName, ui->listWidgetFrom); + ui->listWidgetFrom->addItem(itemFrom); + itemFrom->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + if (starFrom || fromList.contains(stateName)) + itemFrom->setCheckState(Qt::Checked); + else + itemFrom->setCheckState(Qt::Unchecked); } } + ui->listWidgetTo->blockSignals(bTo); ui->listWidgetFrom->blockSignals(bFrom); } diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 0ab05e0da66..f908469465f 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -2004,32 +2004,52 @@ FilePaths QtVersionPrivate::qtCorePaths() const QString versionString = m_data.qtVersionString; const QDir::Filters filters = QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot; + static const QStringList nameFilters{"QtCore*.framework", + "libQtCore*", + "libQt5Core*", + "libQt6Core*", + "QtCore*", + "Qt5Core*", + "Qt6Core*"}; - const FilePaths entries = m_data.libraryPath.dirEntries(filters) - + m_data.binPath.dirEntries(filters); + const FilePaths entries = m_data.libraryPath.dirEntries({nameFilters, filters}) + + m_data.binPath.dirEntries(filters); FilePaths staticLibs; FilePaths dynamicLibs; + + auto isDynamicLib = [&versionString](const QString &file) { + return file.endsWith(".dll") || file.endsWith(QString::fromLatin1(".so.") + versionString) + || file.endsWith(".so") +#if defined(Q_OS_OPENBSD) + || file.contains(QRegularExpression("\\.so\\.[0-9]+\\.[0-9]+$")) // QTCREATORBUG-23818 +#endif + || file.endsWith(QLatin1Char('.') + versionString + ".dylib"); + }; + + auto isStaticLib = [](const QString &file) { + return file.endsWith(".a") || file.endsWith(".lib"); + }; + + auto isFramework = [](const QString &file) { + return file.startsWith("QtCore") && file.endsWith(".framework"); + }; + + auto isQtCore = [](const QString &file) { + return file.startsWith("libQtCore") || file.startsWith("QtCore") + || file.startsWith("libQt5Core") || file.startsWith("Qt5Core") + || file.startsWith("libQt6Core") || file.startsWith("Qt6Core"); + }; + for (const FilePath &entry : entries) { const QString file = entry.fileName(); - if (file.startsWith("QtCore") && file.endsWith(".framework") && entry.isReadableDir()) { - // handle Framework + if (isFramework(file) && entry.isReadableDir()) { dynamicLibs.append(entry.pathAppended(file.left(file.lastIndexOf('.')))); - } else if (file.startsWith("libQtCore") || file.startsWith("QtCore") - || file.startsWith("libQt5Core") || file.startsWith("Qt5Core") - || file.startsWith("libQt6Core") || file.startsWith("Qt6Core")) { - if (entry.isReadableFile()) { - if (file.endsWith(".a") || file.endsWith(".lib")) - staticLibs.append(entry); - else if (file.endsWith(".dll") - || file.endsWith(QString::fromLatin1(".so.") + versionString) - || file.endsWith(".so") -#if defined(Q_OS_OPENBSD) - || file.contains(QRegularExpression("\\.so\\.[0-9]+\\.[0-9]+$")) // QTCREATORBUG-23818 -#endif - || file.endsWith(QLatin1Char('.') + versionString + ".dylib")) - dynamicLibs.append(entry); - } + } else if (isQtCore(file)) { + if (isDynamicLib(file) && entry.isReadableFile()) + dynamicLibs.append(entry); + else if (isStaticLib(file) && entry.isReadableFile()) + staticLibs.append(entry); } } // Only handle static libs if we cannot find dynamic ones: diff --git a/src/plugins/squish/squishwizardpages.cpp b/src/plugins/squish/squishwizardpages.cpp index 9421de713da..55d6aa371a8 100644 --- a/src/plugins/squish/squishwizardpages.cpp +++ b/src/plugins/squish/squishwizardpages.cpp @@ -304,6 +304,8 @@ Core::GeneratedFiles SquishFileGenerator::fileList(Utils::MacroExpander *expande const Utils::FilePath &projectDir, QString *errorMessage) { + Q_UNUSED(wizardDir) + errorMessage->clear(); // later on differentiate based on m_mode QString aut = expander->expand(QString{"%{AUT}"}); @@ -335,6 +337,9 @@ bool SquishFileGenerator::writeFile(const ProjectExplorer::JsonWizard *, bool SquishFileGenerator::allDone(const ProjectExplorer::JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage) { + Q_UNUSED(wizard) + Q_UNUSED(errorMessage) + if (m_mode == "TestSuite") { if (file->filePath().fileName() == "suite.conf") QTimer::singleShot(0, [filePath = file->filePath()] { diff --git a/tests/manual/cmakepresets/CMakePresets.json b/tests/manual/cmakepresets/CMakePresets.json index 74f4c1ba22e..9af5b24cd40 100644 --- a/tests/manual/cmakepresets/CMakePresets.json +++ b/tests/manual/cmakepresets/CMakePresets.json @@ -1,8 +1,8 @@ { - "version": 1, + "version": 2, "cmakeMinimumRequired": { "major": 3, - "minor": 19, + "minor": 20, "patch": 0 }, "configurePresets": [ @@ -13,10 +13,10 @@ "binaryDir": "${sourceDir}/build-${presetName}-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", - "CMAKE_PREFIX_PATH": "c:/Qt/6.3.1/mingw_64" + "CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64" }, "environment": { - "PATH": "c:/mingw64/bin;$penv{PATH}" + "PATH": "c:/Qt/Tools/mingw1120_64/bin;$penv{PATH}" }, "debug" : { "find" : true @@ -37,8 +37,38 @@ "value": "x64" }, "cacheVariables": { - "CMAKE_PREFIX_PATH": "c:/Qt/6.3.1/msvc2019_64" + "CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/msvc2019_64" } } + ], + "buildPresets": [ + { + "name": "mingw", + "displayName": "MinGW default", + "configurePreset": "mingw", + "targets": "${sourceDirName}" + }, + { + "name": "mingw-verbose", + "inherits": "mingw", + "displayName": "MinGW verbose", + "verbose": true + }, + { + "name": "mingw-make", + "displayName": "MinGW make 4 CPUs", + "configurePreset": "mingw-make", + "jobs": 4 + }, + { + "name": "visualc-debug", + "configurePreset": "visualc", + "configuration": "Debug" + }, + { + "name": "visualc-relwithdebinfo", + "inherits": "visualc-debug", + "configuration": "RelWithDebInfo" + } ] }