Merge remote-tracking branch 'origin/master' into work

Change-Id: I2235a55a599aaeca5d2b5377300a044b66c17da9
This commit is contained in:
Eike Ziller
2022-09-29 12:03:13 +02:00
94 changed files with 1581 additions and 1247 deletions

View File

@@ -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()

View File

@@ -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()

70
packaging/CMakeLists.txt Normal file
View File

@@ -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)

View File

@@ -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: # <source>..</source> (possibly multi-line)
inputLineNr += 1
sourceXml.append(sourceLine)
if sourceLine.count(r"</source>") == 1:
break
sourceXmlHash = hash(str(sourceXml))
translationXml = []
for translationLine in lineIter: # <translation>..</translation> (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"</translation>") == 1:
if messageLine.count(r"<location") == 1:
pos = Position.LOCATION
elif messageLine.count(r"<source") == 1:
pos = Position.SOURCE
elif messageLine.count(r"<comment") == 1:
pos = Position.COMMENT
elif messageLine.count(r"<extracomment") == 1:
pos = Position.EXTRACOMMENT
elif messageLine.count(r"<translatorcomment") == 1:
pos = Position.TRANSLATORCOMMENT
elif messageLine.count(r"<translation") == 1:
pos = Position.TRANSLATION
elif messageLine.count(r"</message>") == 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):

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()

View File

@@ -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;
}

View File

@@ -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());
}

View File

@@ -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;
}

View File

@@ -10,8 +10,6 @@
#include <qtsupport/qtoutputformatter.h>
#include <utils/qtcassert.h>
#include <QDir>
#include <QFileInfo>
#include <QRegularExpression>
#include <cctype>

View File

@@ -63,6 +63,7 @@
#include <QRegularExpression>
#include <cmath>
#include <new>
#include <set>
#include <unordered_map>
#include <utility>
@@ -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<HighlightingResult>();
}
};
if (isTesting) {

View File

@@ -19,6 +19,8 @@
#include <QtConcurrent>
#include <QTextDocument>
#include <new>
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<HighlightingResults>(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<HighlightingResults>(tokens, safeToResult);
const QList<BlockRange> ifdefedOutBlocks = cleanupDisabledCode(results, &doc, docContents);
ExtraHighlightingResultsCollector(future, results, filePath, ast, &doc, docContents,
clangdVersion).collect();

View File

@@ -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)
{

View File

@@ -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,

View File

@@ -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
)

View File

@@ -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<BuildTypeAspect>();
addAspect<QtSupport::QmlDebuggingAspect>(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<CMakeProject *>(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<const CMakeProject *>(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<const CMakeProject *>(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<BuildStep *> 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<CMakeBuildStep *>(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
*/

View File

@@ -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;

View File

@@ -7,11 +7,14 @@
#include "cmakebuildsystem.h"
#include "cmakekitinformation.h"
#include "cmakeparser.h"
#include "cmakeproject.h"
#include "cmakeprojectconstants.h"
#include "cmaketool.h"
#include <coreplugin/find/itemviewfind.h>
#include <projectexplorer/buildsteplist.h>
#include <projectexplorer/devicesupport/idevice.h>
#include <projectexplorer/environmentwidget.h>
#include <projectexplorer/gnumakeparser.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/processparameters.h>
@@ -29,6 +32,7 @@
#include <QListWidget>
#include <QRegularExpression>
#include <QTreeView>
#include <QCheckBox>
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<CMakeBuildSystem*>(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(&param);
param.setCommandLine(cmakeCommand());
setSummaryText(param.summary(displayName()));
QString summaryText = param.summary(displayName());
if (!m_buildPreset.isEmpty()) {
const CMakeProject *cp = static_cast<const CMakeProject *>(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("<br><b>Preset</b>: %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);

View File

@@ -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<Utils::TreeItem, CMakeTargetItem> m_buildTargetModel;
Utils::Environment m_environment;
Utils::EnvironmentItems m_userEnvironmentChanges;
bool m_clearSystemEnvironment = false;
QString m_buildPreset;
std::optional<QString> m_configuration;
};
class CMakeBuildStepFactory : public ProjectExplorer::BuildStepFactory

View File

@@ -88,54 +88,93 @@ Internal::PresetsData CMakeProject::combinePresets(Internal::PresetsData &cmakeP
result.version = cmakePresetsData.version;
result.cmakeMinimimRequired = cmakePresetsData.cmakeMinimimRequired;
QHash<QString, PresetsDetails::ConfigurePreset> 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<PresetsDetails::ConfigurePreset> &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<QString, PresetsDetails::ConfigurePreset> configurePresetsHash;
QHash<QString, PresetsDetails::BuildPreset> 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)

View File

@@ -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;

View File

@@ -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<class PresetType>
void expand(const PresetType &preset,
Utils::Environment &env,
const Utils::FilePath &sourceDirectory)
{
const QHash<QString, QString> presetEnv = configurePreset.environment
? configurePreset.environment.value()
: QHash<QString, QString>();
const QHash<QString, QString> presetEnv = preset.environment ? preset.environment.value()
: QHash<QString, QString>();
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<class PresetType>
void expand(const PresetType &preset,
Utils::EnvironmentItems &envItems,
const Utils::FilePath &sourceDirectory)
{
const QHash<QString, QString> presetEnv = configurePreset.environment
? configurePreset.environment.value()
: QHash<QString, QString>();
const QHash<QString, QString> presetEnv = preset.environment ? preset.environment.value()
: QHash<QString, QString>();
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<class PresetType>
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<QString, QString> presetEnv = configurePreset.environment
? configurePreset.environment.value()
: QHash<QString, QString>();
const QHash<QString, QString> presetEnv = preset.environment ? preset.environment.value()
: QHash<QString, QString>();
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<PresetsDetails::ConfigurePreset>(const PresetsDetails::ConfigurePreset &preset,
Utils::Environment &env,
const Utils::FilePath &sourceDirectory);
template void expand<PresetsDetails::ConfigurePreset>(const PresetsDetails::ConfigurePreset &preset,
Utils::EnvironmentItems &envItems,
const Utils::FilePath &sourceDirectory);
template void expand<PresetsDetails::ConfigurePreset>(const PresetsDetails::ConfigurePreset &preset,
const Utils::Environment &env,
const Utils::FilePath &sourceDirectory,
QString &value);
// Expand for PresetsDetails::BuildPreset
template void expand<PresetsDetails::BuildPreset>(const PresetsDetails::BuildPreset &preset,
Utils::Environment &env,
const Utils::FilePath &sourceDirectory);
template void expand<PresetsDetails::BuildPreset>(const PresetsDetails::BuildPreset &preset,
Utils::EnvironmentItems &envItems,
const Utils::FilePath &sourceDirectory);
template void expand<PresetsDetails::BuildPreset>(const PresetsDetails::BuildPreset &preset,
const Utils::Environment &env,
const Utils::FilePath &sourceDirectory,
QString &value);
} // namespace CMakeProjectManager::Internal::CMakePresets::Macros

View File

@@ -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<class PresetType>
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<class PresetType>
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<class PresetType>
void expand(const PresetType &preset,
const Utils::Environment &env,
const Utils::FilePath &sourceDirectory,
QString &value);

View File

@@ -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<PresetsDetails::ConfigurePreset> &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<PresetsDetails::BuildPreset> &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<QString, QString>();
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

View File

@@ -67,6 +67,27 @@ public:
std::optional<Debug> debug;
};
class BuildPreset {
public:
void inheritFrom(const BuildPreset &other);
QString name;
std::optional<bool> hidden = false;
std::optional<QStringList> inherits;
std::optional<QHash<QString, QString>> vendor;
std::optional<QString> displayName;
std::optional<QString> description;
std::optional<QHash<QString, QString>> environment;
std::optional<QString> configurePreset;
std::optional<bool> inheritConfigureEnvironment = true;
std::optional<int> jobs;
std::optional<QStringList> targets;
std::optional<QString> configuration;
std::optional<bool> verbose;
std::optional<bool> cleanFirst;
std::optional<QStringList> nativeToolOptions;
};
} // namespace PresetsDetails
class PresetsData
@@ -76,6 +97,7 @@ public:
QVersionNumber cmakeMinimimRequired;
QHash<QString, QString> vendor;
std::vector<PresetsDetails::ConfigurePreset> configurePresets;
std::vector<PresetsDetails::BuildPreset> buildPresets;
};
class PresetsParser

View File

@@ -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();
}

View File

@@ -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 <app/app_version.h>
#include <coreplugin/messagemanager.h>
#include <texteditor/basehoverhandler.h>
#include <utils/executeondestruction.h>
#include <utils/qtcassert.h>
@@ -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)
{

View File

@@ -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,

View File

@@ -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";

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -54,6 +54,7 @@ public:
void selectAll() override;
void switchDeclarationDefinition(bool inNextSplit);
void followSymbolToType(bool inNextSplit);
void showPreProcessorWidget();
void findUsages() override;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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,

View File

@@ -37,6 +37,7 @@
#include <QObject>
#include <QPointer>
#include <QPushButton>
#include <QTimer>
#include <QTreeView>
#include <QWidget>
@@ -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<DebuggerItem> DebuggerItemManager::debuggers()
{
QList<DebuggerItem> result;

View File

@@ -22,6 +22,8 @@ public:
DebuggerItemManager();
~DebuggerItemManager();
void extensionsInitialized();
static const QList<DebuggerItem> debuggers();
static QVariant registerDebugger(const DebuggerItem &item);

View File

@@ -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 }) {

View File

@@ -14,11 +14,14 @@
#include <coreplugin/icore.h>
#include <coreplugin/messagemanager.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/devicesupport/idevicewidget.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/kitmanager.h>
#include <projectexplorer/project.h>
#include <projectexplorer/runcontrol.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
#include <projectexplorer/toolchainmanager.h>
@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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<Client *> LanguageClientManager::reachableClients()

View File

@@ -14,6 +14,7 @@
#include <utils/listmodel.h>
#include <QAction>
#include <QApplication>
#include <QDialog>
#include <QDialogButtonBox>
#include <QElapsedTimer>
@@ -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<LspInspectorWidget *>(m_currentWidget.data())->selectClient(defaultClient);
m_currentWidget->show();
}
void LspInspector::log(const LspLogMessage::MessageSender sender,

View File

@@ -5,6 +5,7 @@
#include "dynamiccapabilities.h"
#include <QPointer>
#include <QTime>
#include <QWidget>
@@ -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<QString, std::list<LspLogMessage>> m_logs;
QMap<QString, Capabilities> m_capabilities;
QPointer<QWidget> m_currentWidget;
int m_logSize = 100; // default log size if no widget is currently visible
};

View File

@@ -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),

View File

@@ -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"
}
]
},

View File

@@ -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"
]
}
}
)";

View File

@@ -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

View File

@@ -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};

View File

@@ -159,6 +159,24 @@ static int queue(const QList<Project *> &projects, const QList<Id> &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<IDevice>();
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;

View File

@@ -12,6 +12,9 @@
#include "../kitinformation.h"
#include <coreplugin/icore.h>
#include <projectexplorer/target.h>
#include <utils/displayname.h>
#include <utils/icon.h>
#include <utils/portlist.h>
@@ -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;

View File

@@ -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();

View File

@@ -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...

View File

@@ -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<QString> seenCandidates;
QSet<FilePath> 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<void *> QbsProjectImporter::examineDirectory(const FilePath &importPath,

View File

@@ -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

View File

@@ -3,7 +3,15 @@
#include "classdefinition.h"
#include <utils/layoutbuilder.h>
#include <utils/pathchooser.h>
#include <QCheckBox>
#include <QFileInfo>
#include <QLabel>
#include <QLineEdit>
#include <QRadioButton>
#include <QTextEdit>
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;
}

View File

@@ -3,12 +3,21 @@
#pragma once
#include "ui_classdefinition.h"
#include "filenamingparameters.h"
#include "pluginoptions.h"
#include <QTabWidget>
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;
};
}

View File

@@ -1,324 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmakeProjectManager::Internal::ClassDefinition</class>
<widget class="QTabWidget" name="QmakeProjectManager::Internal::ClassDefinition">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>649</width>
<height>427</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<property name="whatsThis">
<string>The header file</string>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="sourceTab">
<attribute name="title">
<string>&amp;Sources</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0">
<widget class="QLabel" name="widgetLibraryLabel">
<property name="text">
<string>Widget librar&amp;y:</string>
</property>
<property name="buddy">
<cstring>widgetLibraryEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="widgetLibraryEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="widgetProjectLabel">
<property name="text">
<string>Widget project &amp;file:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>widgetProjectEdit</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="widgetProjectEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="widgetHeaderLabel">
<property name="text">
<string>Widget h&amp;eader file:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>widgetHeaderEdit</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="widgetHeaderEdit">
<property name="whatsThis">
<string>The header file has to be specified in source code.</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="widgetSourceLabel">
<property name="text">
<string>Widge&amp;t source file:</string>
</property>
<property name="buddy">
<cstring>widgetSourceEdit</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="widgetSourceEdit"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="widgetBaseClassLabel">
<property name="text">
<string>Widget &amp;base class:</string>
</property>
<property name="buddy">
<cstring>widgetBaseClassEdit</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="widgetBaseClassEdit">
<property name="text">
<string>QWidget</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="pluginClassLabel">
<property name="text">
<string>Plugin class &amp;name:</string>
</property>
<property name="buddy">
<cstring>pluginClassEdit</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="pluginClassEdit"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="pluginHeaderLabel">
<property name="text">
<string>Plugin &amp;header file:</string>
</property>
<property name="buddy">
<cstring>pluginHeaderEdit</cstring>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLineEdit" name="pluginHeaderEdit"/>
</item>
<item row="8" column="0">
<widget class="QLabel" name="pluginSourceLabel">
<property name="text">
<string>Plugin sou&amp;rce file:</string>
</property>
<property name="buddy">
<cstring>pluginSourceEdit</cstring>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLineEdit" name="pluginSourceEdit"/>
</item>
<item row="9" column="0">
<widget class="QLabel" name="iconLabel">
<property name="text">
<string>Icon file:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="Utils::PathChooser" name="iconPathChooser"/>
</item>
<item row="0" column="1">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QRadioButton" name="libraryRadio">
<property name="text">
<string>&amp;Link library</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1" rowspan="2">
<widget class="QCheckBox" name="skeletonCheck">
<property name="text">
<string>Create s&amp;keleton</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="includeRadio">
<property name="text">
<string>Include pro&amp;ject</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="descriptionTab">
<attribute name="title">
<string>&amp;Description</string>
</attribute>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>G&amp;roup:</string>
</property>
<property name="buddy">
<cstring>groupEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="groupEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>&amp;Tooltip:</string>
</property>
<property name="buddy">
<cstring>tooltipEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="tooltipEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>W&amp;hat's this:</string>
</property>
<property name="buddy">
<cstring>whatsthisEdit</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QTextEdit" name="whatsthisEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>100</height>
</size>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="containerCheck">
<property name="text">
<string>The widget is a &amp;container</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="propertyDefaults">
<attribute name="title">
<string>Property defa&amp;ults</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QTextEdit" name="domXmlEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>dom&amp;XML:</string>
</property>
<property name="buddy">
<cstring>domXmlEdit</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>libraryRadio</tabstop>
<tabstop>includeRadio</tabstop>
<tabstop>skeletonCheck</tabstop>
<tabstop>widgetLibraryEdit</tabstop>
<tabstop>widgetProjectEdit</tabstop>
<tabstop>widgetHeaderEdit</tabstop>
<tabstop>widgetSourceEdit</tabstop>
<tabstop>widgetBaseClassEdit</tabstop>
<tabstop>pluginClassEdit</tabstop>
<tabstop>pluginHeaderEdit</tabstop>
<tabstop>pluginSourceEdit</tabstop>
<tabstop>groupEdit</tabstop>
<tabstop>tooltipEdit</tabstop>
<tabstop>whatsthisEdit</tabstop>
<tabstop>containerCheck</tabstop>
<tabstop>domXmlEdit</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -3,10 +3,13 @@
#include "customwidgetpluginwizardpage.h"
#include "customwidgetwidgetswizardpage.h"
#include "ui_customwidgetpluginwizardpage.h"
#include <utils/layoutbuilder.h>
#include <utils/wizard.h>
#include <QLabel>
#include <QLineEdit>
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<PluginOptions> CustomWidgetPluginWizardPage::basicPluginOptions() const
{
QSharedPointer<PluginOptions> 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;
}

View File

@@ -8,21 +8,23 @@
#include <QWizardPage>
#include <QSharedPointer>
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

View File

@@ -1,157 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmakeProjectManager::Internal::CustomWidgetPluginWizardPage</class>
<widget class="QWizardPage" name="QmakeProjectManager::Internal::CustomWidgetPluginWizardPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>591</width>
<height>446</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<property name="title">
<string>Plugin and Collection Class Information</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="subTitleLabel">
<property name="text">
<string>Specify the properties of the plugin library and the collection class.</string>
</property>
</widget>
</item>
<item>
<spacer name="subTitleSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="collectionClassLabel">
<property name="text">
<string>Collection class:</string>
</property>
<property name="buddy">
<cstring>collectionClassEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="collectionClassEdit">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="collectionHeaderLabel">
<property name="text">
<string>Collection header file:</string>
</property>
<property name="buddy">
<cstring>collectionHeaderEdit</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="collectionHeaderEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="collectionSourceLabel">
<property name="text">
<string>Collection source file:</string>
</property>
<property name="buddy">
<cstring>collectionSourceEdit</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="collectionSourceEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="pluginNameLabel">
<property name="text">
<string>Plugin name:</string>
</property>
<property name="buddy">
<cstring>pluginNameEdit</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="pluginNameEdit"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="resourceFileLabel">
<property name="text">
<string>Resource file:</string>
</property>
<property name="buddy">
<cstring>resourceFileEdit</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="resourceFileEdit">
<property name="text">
<string>icons.qrc</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -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 <utils/layoutbuilder.h>
#include <utils/utilsicons.h>
#include <utils/wizard.h>
#include <QTimer>
#include <QStackedLayout>
#include <QIcon>
#include <QLabel>
#include <QStackedLayout>
#include <QTimer>
#include <QToolButton>
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 <new class> 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<PluginOptions::WidgetOptions> CustomWidgetWidgetsWizardPage::widgetOptions() const

View File

@@ -10,6 +10,7 @@
#include <QWizardPage>
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<PluginOptions::WidgetOptions> widgetOptions() const;
@@ -51,11 +52,12 @@ private Q_SLOTS:
private:
void updatePluginTab();
Ui::CustomWidgetWidgetsWizardPage *m_ui;
QList<ClassDefinition *> m_uiClassDefs;
QStackedLayout *m_tabStackLayout;
FileNamingParameters m_fileNamingParameters;
bool m_complete;
QToolButton *m_deleteButton;
ClassList *m_classList;
};
}

View File

@@ -1,105 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmakeProjectManager::Internal::CustomWidgetWidgetsWizardPage</class>
<widget class="QWizardPage" name="QmakeProjectManager::Internal::CustomWidgetWidgetsWizardPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>668</width>
<height>475</height>
</rect>
</property>
<property name="windowTitle">
<string>Custom Qt Widget Wizard</string>
</property>
<property name="title">
<string>Custom Widget List</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1" rowspan="2">
<widget class="QWidget" name="tabStackWidget" native="true">
<property name="minimumSize">
<size>
<width>400</width>
<height>200</height>
</size>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QmakeProjectManager::Internal::ClassList" name="classList">
<property name="minimumSize">
<size>
<width>0</width>
<height>400</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="subTitleLabel">
<property name="text">
<string>Specify the list of custom widgets and their properties.</string>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="titleSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Widget &amp;Classes:</string>
</property>
<property name="buddy">
<cstring>classList</cstring>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="addButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="deleteButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QmakeProjectManager::Internal::ClassList</class>
<extends>QListWidget</extends>
<header location="global">qmakeprojectmanager/customwidgetwizard/classlist.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>classList</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -33,11 +33,13 @@
#include <memory>
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<void *> QmakeProjectImporter::examineDirectory(const FilePath &importPath,

View File

@@ -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",

View File

@@ -144,7 +144,6 @@ void CurveEditorView::variantPropertiesChanged([[maybe_unused]] const QList<Vari
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();
if (QmlTimelineKeyframeGroup::isValidQmlTimelineKeyframeGroup(framesNode))
@@ -166,7 +165,7 @@ void CurveEditorView::bindingPropertiesChanged([[maybe_unused]] const QList<Bind
void CurveEditorView::propertiesRemoved([[maybe_unused]] const QList<AbstractProperty> &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);
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();

View File

@@ -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<QColor>();
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<QColor>();
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);

View File

@@ -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<AbstractProperty>& proper
if ("width" == property.name() || "height" == property.name()) {
const QmlItemNode qmlItemNode = m_selectedNode;
if (qmlItemNode.isValid() && qmlItemNode.isInLayout())
if (qmlItemNode.isInLayout())
resetPuppet();
}

View File

@@ -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:

View File

@@ -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);

View File

@@ -142,15 +142,12 @@ void TimelineActions::copyKeyframes(const QList<ModelNode> &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)

View File

@@ -769,7 +769,7 @@ void TimelineGraphicsScene::deleteKeyframes(const QList<ModelNode> &frames)
ModelNode frame = keyframe;
ModelNode parent = frame.parentProperty().parentModelNode();
keyframe.destroy();
if (parent.isValid() && parent.defaultNodeListProperty().isEmpty())
if (parent.defaultNodeListProperty().isEmpty())
parent.destroy();
}
}

View File

@@ -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 *)

View File

@@ -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<QColor>();
if (overrideColor.isValid()) {
brushColorSelected = overrideColor;
brushColor = brushColorSelected.darker(120);
}
QColor overrideColor = target.auxiliaryDataWithDefault(timelineOverrideColorProperty).value<QColor>();
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);

View File

@@ -208,9 +208,9 @@ void TimelineSettingsModel::addState(const ModelNode &state)
QList<QStandardItem *> 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");

View File

@@ -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<VariantProperty> &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();

View File

@@ -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 &parallel : transition.directSubModelNodes()) {
auto item = TransitionEditorSectionItem::create(parallel, this);
m_layout->addItem(item);
}
for (const ModelNode &parallel : transition.directSubModelNodes()) {
auto item = TransitionEditorSectionItem::create(parallel, this);
m_layout->addItem(item);
}
m_placeholder2->setParentItem(this);

View File

@@ -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);

View File

@@ -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

View File

@@ -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({});
}

View File

@@ -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());
}
}

View File

@@ -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<ModelNode> 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)

View File

@@ -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<ModelNode> directSubNodes = transitions.directSubNodes();
if (!directSubNodes.isEmpty())
transition = directSubNodes.constFirst();
}
if (NodeAbstractProperty transitions = root.nodeAbstractProperty("transitions")) {
const QList<ModelNode> 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 {

View File

@@ -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);
}

View File

@@ -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:

View File

@@ -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()] {

View File

@@ -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"
}
]
}