Merge remote-tracking branch 'origin/4.14'

Conflicts:
	src/plugins/mesonprojectmanager/project/mesonprojectparser.h

Change-Id: Id38d20ce20981dcdc322fe5d1d7647f4bec89d8a
This commit is contained in:
Eike Ziller
2020-11-13 16:03:26 +01:00
125 changed files with 1246 additions and 847 deletions

View File

@@ -391,6 +391,7 @@ jobs:
COMMAND python COMMAND python
-u -u
scripts/build.py scripts/build.py
--build-type Release
--src . --src .
--build build --build build
--qt-path "${{ steps.qt.outputs.qt_dir }}" --qt-path "${{ steps.qt.outputs.qt_dir }}"

View File

@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.10)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(FeatureSummary) include(FeatureSummary)
include(QtCreatorIDEBranding) include(QtCreatorIDEBranding RESULT_VARIABLE IDE_BRANDING_FILE)
include(QtCreatorTranslations) include(QtCreatorTranslations)
include(QtCreatorDocumentation) include(QtCreatorDocumentation)
include(QtCreatorAPI) include(QtCreatorAPI)

View File

@@ -69,7 +69,7 @@ set(Qt5_VERSION ${Qt6_VERSION})
foreach(tool qmake lrelease moc rcc qhelpgenerator) foreach(tool qmake lrelease moc rcc qhelpgenerator)
if (TARGET Qt6::${tool} AND NOT TARGET Qt5::${tool}) if (TARGET Qt6::${tool} AND NOT TARGET Qt5::${tool})
add_executable(Qt5::${tool} IMPORTED GLOBAL) add_executable(Qt5::${tool} IMPORTED GLOBAL)
get_target_property(imported_location Qt6::${tool} IMPORTED_LOCATION_RELEASE) get_target_property(imported_location Qt6::${tool} IMPORTED_LOCATION)
set_target_properties(Qt5::${tool} PROPERTIES IMPORTED_LOCATION "${imported_location}") set_target_properties(Qt5::${tool} PROPERTIES IMPORTED_LOCATION "${imported_location}")
endif() endif()
endforeach() endforeach()

View File

@@ -114,5 +114,8 @@ else()
${YAML_SOURCE_DIR}/src/tag.h ${YAML_SOURCE_DIR}/src/tag.h
${YAML_SOURCE_DIR}/src/token.h ${YAML_SOURCE_DIR}/src/token.h
) )
if(MSVC)
target_compile_options(yaml-cpp PUBLIC /wd4251 /wd4275)
endif()
unset(YAML_SOURCE_DIR) unset(YAML_SOURCE_DIR)
endif() endif()

View File

@@ -133,7 +133,7 @@ function(add_qtc_library name)
endif() endif()
add_library(${name} ${library_type} ${_arg_SOURCES}) add_library(${name} ${library_type} ${_arg_SOURCES})
add_library(${IDE_CASED_ID}::${name} ALIAS ${name}) add_library(QtCreator::${name} ALIAS ${name})
set_public_headers(${name} "${_arg_SOURCES}") set_public_headers(${name} "${_arg_SOURCES}")
# TODO remove, see above # TODO remove, see above
@@ -339,9 +339,9 @@ function(add_qtc_plugin target_name)
set(_arg_DEPENDENCY_STRING "\"Dependencies\" : [\n") set(_arg_DEPENDENCY_STRING "\"Dependencies\" : [\n")
foreach(i IN LISTS _DEP_PLUGINS) foreach(i IN LISTS _DEP_PLUGINS)
if (i MATCHES "^${IDE_CASED_ID}::") if (i MATCHES "^QtCreator::")
set(_v ${IDE_VERSION}) set(_v ${IDE_VERSION})
string(REPLACE "${IDE_CASED_ID}::" "" i ${i}) string(REPLACE "QtCreator::" "" i ${i})
else() else()
get_property(_v TARGET "${i}" PROPERTY _arg_VERSION) get_property(_v TARGET "${i}" PROPERTY _arg_VERSION)
endif() endif()
@@ -353,9 +353,9 @@ function(add_qtc_plugin target_name)
_arg_DEPENDENCY_STRING "${_arg_DEPENDENCY_STRING}" _arg_DEPENDENCY_STRING "${_arg_DEPENDENCY_STRING}"
) )
foreach(i IN LISTS ${_arg_RECOMMENDS}) foreach(i IN LISTS ${_arg_RECOMMENDS})
if (i MATCHES "^${IDE_CASED_ID}::") if (i MATCHES "^QtCreator::")
set(_v ${IDE_VERSION}) set(_v ${IDE_VERSION})
string(REPLACE "${IDE_CASED_ID}::" "" i ${i}) string(REPLACE "QtCreator::" "" i ${i})
else() else()
get_property(_v TARGET "${i}" PROPERTY _arg_VERSION) get_property(_v TARGET "${i}" PROPERTY _arg_VERSION)
endif() endif()
@@ -393,7 +393,7 @@ function(add_qtc_plugin target_name)
endif() endif()
add_library(${target_name} SHARED ${_arg_SOURCES}) add_library(${target_name} SHARED ${_arg_SOURCES})
add_library(${IDE_CASED_ID}::${target_name} ALIAS ${target_name}) add_library(QtCreator::${target_name} ALIAS ${target_name})
set_public_headers(${target_name} "${_arg_SOURCES}") set_public_headers(${target_name} "${_arg_SOURCES}")
### Generate EXPORT_SYMBOL ### Generate EXPORT_SYMBOL
@@ -598,7 +598,10 @@ function(add_qtc_executable name)
if (_prop_OUTPUT_NAME) if (_prop_OUTPUT_NAME)
set(_BUNDLE_NAME "${_prop_OUTPUT_NAME}") set(_BUNDLE_NAME "${_prop_OUTPUT_NAME}")
endif() endif()
set(_EXECUTABLE_PATH "${_DESTINATION}/${_BUNDLE_NAME}.app/Contents/MacOS") set(_BUNDLE_CONTENTS_PATH "${_DESTINATION}/${_BUNDLE_NAME}.app/Contents")
set(_EXECUTABLE_PATH "${_BUNDLE_CONTENTS_PATH}/MacOS")
set(_EXECUTABLE_FILE_PATH "${_EXECUTABLE_PATH}/${_BUNDLE_NAME}")
set(_BUNDLE_INFO_PLIST "${_BUNDLE_CONTENTS_PATH}/Info.plist")
endif() endif()
endif() endif()
@@ -647,11 +650,70 @@ function(add_qtc_executable name)
set(COMPONENT_OPTION "COMPONENT" "${_arg_COMPONENT}") set(COMPONENT_OPTION "COMPONENT" "${_arg_COMPONENT}")
endif() endif()
# work around the issue that CMake simply copies the bundle directory
# when installing app bundles, which copies things that it should not
# like static libraries, executables with SKIP_INSTALL, clang resources
# and dSYM directories
if (APPLE AND _EXECUTABLE_FILE_PATH AND _BUNDLE_INFO_PLIST)
install(
PROGRAMS "${_output_binary_dir}/${_EXECUTABLE_FILE_PATH}"
DESTINATION "${_EXECUTABLE_PATH}"
${COMPONENT_OPTION}
OPTIONAL
)
install(
FILES "${_output_binary_dir}/${_BUNDLE_INFO_PLIST}"
DESTINATION "${_BUNDLE_CONTENTS_PATH}"
${COMPONENT_OPTION}
OPTIONAL
)
# Remove build-rpaths. That is BUILD_RPATH and the ones added because we
# don't use SKIP_BUILD_RPATH
set(_rpaths_to_remove ${build_rpath})
get_target_property(_linked_libs ${name} LINK_LIBRARIES)
foreach(_lib ${_linked_libs})
get_target_property(_target_type ${_lib} TYPE)
if (_target_type STREQUAL "SHARED_LIBRARY")
get_target_property(_location ${_lib} LIBRARY_OUTPUT_DIRECTORY)
if (_location)
get_filename_component(_abs_location ${_location} ABSOLUTE)
list(APPEND _rpaths_to_remove "${_abs_location}")
else()
get_target_property(_location ${_lib} LOCATION)
get_target_property(_is_framework ${_lib} FRAMEWORK)
if (_is_framework)
set(_location ${_location}/../..)
endif()
get_filename_component(_abs_location ${_location} ABSOLUTE)
list(APPEND _rpaths_to_remove "${_abs_location}")
endif()
endif()
endforeach()
list(REMOVE_DUPLICATES _rpaths_to_remove)
set(_code)
foreach(_rpath ${_rpaths_to_remove})
set(_code "${_code}
execute_process(COMMAND \"${CMAKE_INSTALL_NAME_TOOL}\"
-delete_rpath \"${_rpath}\"
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_EXECUTABLE_FILE_PATH}\")"
)
endforeach()
foreach(_rpath ${install_rpath})
set(_code "${_code}
execute_process(COMMAND \"${CMAKE_INSTALL_NAME_TOOL}\"
-add_rpath \"${_rpath}\"
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_EXECUTABLE_FILE_PATH}\")"
)
endforeach()
install(CODE "${_code}")
else()
install(TARGETS ${name} install(TARGETS ${name}
DESTINATION "${_DESTINATION}" DESTINATION "${_DESTINATION}"
${COMPONENT_OPTION} ${COMPONENT_OPTION}
OPTIONAL OPTIONAL
) )
endif()
update_cached_list(__QTC_INSTALLED_EXECUTABLES update_cached_list(__QTC_INSTALLED_EXECUTABLES
"${_DESTINATION}/${name}${CMAKE_EXECUTABLE_SUFFIX}") "${_DESTINATION}/${name}${CMAKE_EXECUTABLE_SUFFIX}")

77
dist/changes-4.13.3.md vendored Normal file
View File

@@ -0,0 +1,77 @@
Qt Creator 4.13.3
=================
Qt Creator version 4.13.3 contains bug fixes.
The most important changes are listed in this document. For a complete list of
changes, see the Git log for the Qt Creator sources that you can check out from
the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline origin/v4.13.2..v4.13.3
General
-------
* Updated prebuilt binaries to Qt 5.15.2 which fixes drag & drop on macOS
Editing
-------
### QML
* Fixed reformatting of required properties (QTCREATORBUG-24376)
* Fixed importing without specific version for Qt 6 (QTCREATORBUG-24533)
Projects
--------
* Fixed auto-scrolling of compile output window (QTCREATORBUG-24728)
* Fixed GitHub Actions for Qt Creator plugin wizard (QTCREATORBUG-24412)
* Fixed crash with `Manage Sessions` (QTCREATORBUG-24797)
Qt Quick Designer
-----------------
* Fixed crash when opening malformed `.ui.qml` file (QTCREATORBUG-24587)
Debugging
---------
### CDB
* Fixed pretty printing of `std::vector` and `std::string` in release mode
Analyzer
--------
### QML Profiler
* Fixed crash with `Analyze Current Range` (QTCREATORBUG-24730)
Platforms
---------
### Android
* Fixed modified state of manifest editor when changing app icons
(QTCREATORBUG-24700)
Credits for these changes go to:
--------------------------------
Alexandru Croitor
Christian Kandeler
Christian Stenger
David Schulz
Dominik Holland
Eike Ziller
Fawzi Mohamed
Friedemann Kleint
Ivan Komissarov
Johanna Vanhatapio
Leena Miettinen
Lukasz Ornatek
Robert Löhning
Tim Jenssen
Ville Voutilainen
Xiaofeng Wang

View File

@@ -52,6 +52,8 @@ Editing
* Fixed that `Complete switch statement` indents unrelated code (QTCREATORBUG-12445) * Fixed that `Complete switch statement` indents unrelated code (QTCREATORBUG-12445)
* Fixed `Complete switch statement` with templates (QTCREATORBUG-24752) * Fixed `Complete switch statement` with templates (QTCREATORBUG-24752)
* Fixed `Complete switch statement` for enum classes (QTCREATORBUG-20475) * Fixed `Complete switch statement` for enum classes (QTCREATORBUG-20475)
* Fixed creating and moving template member function definitions (QTCREATORBUG-24801,
QTCREATORBUG-24848)
* Fixed that `Apply function signature change` removed return values from `std::function` * Fixed that `Apply function signature change` removed return values from `std::function`
arguments (QTCREATORBUG-13698) arguments (QTCREATORBUG-13698)
* Fixed handling of multiple inheritance in `Insert Virtual Functions` (QTCREATORBUG-12223) * Fixed handling of multiple inheritance in `Insert Virtual Functions` (QTCREATORBUG-12223)
@@ -81,6 +83,8 @@ Projects
* Renamed `CurrentProject:*` variables to `CurrentDocument:Project:*` (QTCREATORBUG-12724, * Renamed `CurrentProject:*` variables to `CurrentDocument:Project:*` (QTCREATORBUG-12724,
QTCREATORBUG-24606) QTCREATORBUG-24606)
* Added `ActiveProject:*` variables (QTCREATORBUG-24878)
* Changed `Qt Creator Plugin` wizard to CMake build system (QTCREATORBUG-24073)
* Fixed issue when environment changes after appending or prepending path (QTCREATORBUG-24105) * Fixed issue when environment changes after appending or prepending path (QTCREATORBUG-24105)
* Fixed `Embedding of the UI Class` option for widget applications (QTCREATORBUG-24422) * Fixed `Embedding of the UI Class` option for widget applications (QTCREATORBUG-24422)
* Fixed shell used for console applications (QTCREATORBUG-24659) * Fixed shell used for console applications (QTCREATORBUG-24659)
@@ -107,11 +111,16 @@ Debugging
--------- ---------
* Fixed disabling and enabling breakpoints (QTCREATORBUG-24669) * Fixed disabling and enabling breakpoints (QTCREATORBUG-24669)
* Fixed setting source mappings with variables (QTCREATORBUG-24816)
### GDB ### GDB
* Fixed loading of symbol files with `Load Core File` (QTCREATORBUG-24541) * Fixed loading of symbol files with `Load Core File` (QTCREATORBUG-24541)
### CDB
* Fixed debugging when `PYTHONPATH` is set (QTCREATORBUG-24859)
Analyzer Analyzer
-------- --------
@@ -156,8 +165,13 @@ Platforms
* Added missing Android variables to completion in `.pro` and `.pri` files * Added missing Android variables to completion in `.pro` and `.pri` files
* Fixed passing command line arguments to application (QTCREATORBUG-23712) * Fixed passing command line arguments to application (QTCREATORBUG-23712)
### MCU
* Improved creation of kits (QTCREATORBUG-24354)
Credits for these changes go to: Credits for these changes go to:
-------------------------------- --------------------------------
Aleksei German
Alessandro Portale Alessandro Portale
Alexander Mishin Alexander Mishin
Alexis Jeandet Alexis Jeandet
@@ -166,6 +180,7 @@ André Pönitz
Antonio Di Monaco Antonio Di Monaco
Asit Dhal Asit Dhal
Assam Boudjelthia Assam Boudjelthia
Christiaan Janssen
Christian Kandeler Christian Kandeler
Christian Stenger Christian Stenger
Cristian Adam Cristian Adam
@@ -176,14 +191,19 @@ Fabio Falsini
Fawzi Mohamed Fawzi Mohamed
Federico Guerinoni Federico Guerinoni
Henning Gruendl Henning Gruendl
Jaroslaw Kobus
Jeremy Ephron Jeremy Ephron
Jochen Seemann
Johanna Vanhatapio
Kai Köhne Kai Köhne
Knud Dollereder Knud Dollereder
Lars Knoll Lars Knoll
Leander Schulten Leander Schulten
Leena Miettinen Leena Miettinen
Lukas Holecek
Lukasz Ornatek Lukasz Ornatek
Mahmoud Badri Mahmoud Badri
Marco Bubke
Martin Kampas Martin Kampas
Michael Weghorn Michael Weghorn
Miikka Heikkinen Miikka Heikkinen
@@ -194,6 +214,7 @@ Robert Löhning
Tasuku Suzuki Tasuku Suzuki
Thiago Macieira Thiago Macieira
Thomas Hartmann Thomas Hartmann
Tim Jenssen
Tobias Hunger Tobias Hunger
Vikas Pachdha Vikas Pachdha
Volodymyr Zibarov Volodymyr Zibarov

View File

@@ -51,7 +51,7 @@
You can use the model component to load static mesh data from You can use the model component to load static mesh data from
storage or one of the built-in primitive types: cube, cone, storage or one of the built-in primitive types: cube, cone,
cylinder, rectangle, or sphere. You can attach materials to cylinder, plane (rectangle), or sphere. You can attach materials to
meshes and sub-meshes. meshes and sub-meshes.
\li \l {Using Materials and Shaders} \li \l {Using Materials and Shaders}
@@ -85,9 +85,9 @@
scene and set their properties. scene and set their properties.
\li \l {Using Scene Camera} \li \l {Using Scene Camera}
To project a 3D scene to a 2D viewport, it is necessary to view To project a 3D scene to a 2D viewport, such as
the scene from a camera. You can select the camera type and set \uicontrol {Form Editor}, it is necessary to view the scene from a
its properties. camera. You can select the camera type and set its properties.
\li \l {Setting Scene Environment} \li \l {Setting Scene Environment}
You can use the SceneEnvironment type to specify how the scene is You can use the SceneEnvironment type to specify how the scene is

View File

@@ -54,7 +54,8 @@ def get_arguments():
parser.add_argument('--build', help='path that should be used for building', required=True) parser.add_argument('--build', help='path that should be used for building', required=True)
parser.add_argument('--qt-path', help='Path to Qt', required=True) parser.add_argument('--qt-path', help='Path to Qt', required=True)
parser.add_argument('--debug', help='Enable debug builds', action='store_true', default=False) parser.add_argument('--build-type', help='Build type to pass to CMake (defaults to RelWithDebInfo)',
default='RelWithDebInfo')
# clang codemodel # clang codemodel
parser.add_argument('--llvm-path', help='Path to LLVM installation for Clang code model', parser.add_argument('--llvm-path', help='Path to LLVM installation for Clang code model',
@@ -113,13 +114,12 @@ def build_qtcreator(args, paths):
if paths.elfutils: if paths.elfutils:
prefix_paths += [paths.elfutils] prefix_paths += [paths.elfutils]
prefix_paths = [common.to_posix_path(fp) for fp in prefix_paths] prefix_paths = [common.to_posix_path(fp) for fp in prefix_paths]
build_type = 'Debug' if args.debug else 'Release'
with_docs_str = 'OFF' if args.no_docs else 'ON' with_docs_str = 'OFF' if args.no_docs else 'ON'
build_date_option = 'OFF' if args.no_build_date else 'ON' build_date_option = 'OFF' if args.no_build_date else 'ON'
test_option = 'ON' if args.with_tests else 'OFF' test_option = 'ON' if args.with_tests else 'OFF'
cmake_args = ['cmake', cmake_args = ['cmake',
'-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths), '-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths),
'-DCMAKE_BUILD_TYPE=' + build_type, '-DCMAKE_BUILD_TYPE=' + args.build_type,
'-DSHOW_BUILD_DATE=' + build_date_option, '-DSHOW_BUILD_DATE=' + build_date_option,
'-DWITH_DOCS=' + with_docs_str, '-DWITH_DOCS=' + with_docs_str,
'-DBUILD_DEVELOPER_DOCS=' + with_docs_str, '-DBUILD_DEVELOPER_DOCS=' + with_docs_str,

View File

@@ -57,7 +57,8 @@ def get_arguments():
action='store_true', default=False) action='store_true', default=False)
parser.add_argument('--deploy', help='Installs the "Dependencies" component of the plugin.', parser.add_argument('--deploy', help='Installs the "Dependencies" component of the plugin.',
action='store_true', default=False) action='store_true', default=False)
parser.add_argument('--debug', help='Enable debug builds', action='store_true', default=False) parser.add_argument('--build-type', help='Build type to pass to CMake (defaults to RelWithDebInfo)',
default='RelWithDebInfo')
return parser.parse_args() return parser.parse_args()
def build(args, paths): def build(args, paths):
@@ -67,10 +68,9 @@ def build(args, paths):
os.makedirs(paths.result) os.makedirs(paths.result)
prefix_paths = [os.path.abspath(fp) for fp in args.prefix_paths] + [paths.qt_creator, paths.qt] prefix_paths = [os.path.abspath(fp) for fp in args.prefix_paths] + [paths.qt_creator, paths.qt]
prefix_paths = [common.to_posix_path(fp) for fp in prefix_paths] prefix_paths = [common.to_posix_path(fp) for fp in prefix_paths]
build_type = 'Debug' if args.debug else 'Release'
cmake_args = ['cmake', cmake_args = ['cmake',
'-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths), '-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths),
'-DCMAKE_BUILD_TYPE=' + build_type, '-DCMAKE_BUILD_TYPE=' + args.build_type,
'-DCMAKE_INSTALL_PREFIX=' + common.to_posix_path(paths.install), '-DCMAKE_INSTALL_PREFIX=' + common.to_posix_path(paths.install),
'-G', 'Ninja'] '-G', 'Ninja']

View File

@@ -36,7 +36,8 @@ import re
if __name__ == '__main__': if __name__ == '__main__':
# qt.shiboken: (<module>) <file>:<line>:[<column>:] text # qt.shiboken: (<module>) <file>:<line>:[<column>:] text
pattern = re.compile(r'^qt\.shiboken: \(([^)]+)\) ([^:]+):(\d+):(?:\d+:)? (.*)$') # file might be c:\ on Windows
pattern = re.compile(r'^qt\.shiboken: \(([^)]+)\) (..[^:]+):(\d+):(?:\d+:)? (.*)$')
while True: while True:
line = sys.stdin.readline() line = sys.stdin.readline()
if not line: if not line:

View File

@@ -28,6 +28,10 @@ qtc_copy_to_builddir(copy_share_to_builddir
) )
# create install rule for resource directories # create install rule for resource directories
install(DIRECTORY ${resource_directories} DESTINATION "${IDE_DATA_PATH}") install(
DIRECTORY ${resource_directories}
DESTINATION "${IDE_DATA_PATH}"
USE_SOURCE_PERMISSIONS
)
add_subdirectory(translations) add_subdirectory(translations)

View File

@@ -729,11 +729,22 @@ def qdumpHelper__std__string__QNX(d, value, charType, format):
def qdumpHelper__std__string__MSVC(d, value, charType, format): def qdumpHelper__std__string__MSVC(d, value, charType, format):
try:
(proxy, buffer, size, alloc) = value.split("p16spp") (proxy, buffer, size, alloc) = value.split("p16spp")
_BUF_SIZE = int(16 / charType.size())
d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000) d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000)
except RuntimeError:
proxy = None
(buffer, size, alloc) = value.split("16spp")
d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000)
_BUF_SIZE = int(16 / charType.size())
if _BUF_SIZE <= alloc: if _BUF_SIZE <= alloc:
if proxy is None:
data = value.extractPointer()
else:
(proxy, data) = value.split("pp") (proxy, data) = value.split("pp")
else:
if proxy is None:
data = value.address()
else: else:
data = value.address() + d.ptrSize() data = value.address() + d.ptrSize()
d.putCharArrayHelper(data, size, charType, format) d.putCharArrayHelper(data, size, charType, format)
@@ -1098,8 +1109,18 @@ def qdumpHelper__std__vector__QNX(d, value):
(proxy, start, last, end) = value.split("pppp") (proxy, start, last, end) = value.split("pppp")
size = (last - start) // innerType.size() size = (last - start) // innerType.size()
try:
d.check(0 <= size and size <= 1000 * 1000 * 1000) d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.check(last <= end) d.check(last <= end)
except RuntimeError:
if isBool:
(start, last, end, size) = value.split("pppi")
else:
(start, last, end) = value.split("ppp")
size = (last - start) // innerType.size()
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.check(last <= end)
if size > 0: if size > 0:
d.checkPointer(start) d.checkPointer(start)
d.checkPointer(last) d.checkPointer(last)

View File

@@ -29,136 +29,20 @@
namespace QmlDesigner { namespace QmlDesigner {
CreateSceneCommand::CreateSceneCommand() = default;
CreateSceneCommand::CreateSceneCommand(const QVector<InstanceContainer> &instanceContainer,
const QVector<ReparentContainer> &reparentContainer,
const QVector<IdContainer> &idVector,
const QVector<PropertyValueContainer> &valueChangeVector,
const QVector<PropertyBindingContainer> &bindingChangeVector,
const QVector<PropertyValueContainer> &auxiliaryChangeVector,
const QVector<AddImportContainer> &importVector,
const QVector<MockupTypeContainer> &mockupTypeVector,
const QUrl &fileUrl,
const QHash<QString, QVariantMap> &edit3dToolStates,
const QString &language)
: m_instanceVector(instanceContainer),
m_reparentInstanceVector(reparentContainer),
m_idVector(idVector),
m_valueChangeVector(valueChangeVector),
m_bindingChangeVector(bindingChangeVector),
m_auxiliaryChangeVector(auxiliaryChangeVector),
m_importVector(importVector),
m_mockupTypeVector(mockupTypeVector),
m_fileUrl(fileUrl),
m_edit3dToolStates(edit3dToolStates),
m_language(language)
{
}
QVector<InstanceContainer> CreateSceneCommand::instances() const
{
return m_instanceVector;
}
QVector<ReparentContainer> CreateSceneCommand::reparentInstances() const
{
return m_reparentInstanceVector;
}
QVector<IdContainer> CreateSceneCommand::ids() const
{
return m_idVector;
}
QVector<PropertyValueContainer> CreateSceneCommand::valueChanges() const
{
return m_valueChangeVector;
}
QVector<PropertyBindingContainer> CreateSceneCommand::bindingChanges() const
{
return m_bindingChangeVector;
}
QVector<PropertyValueContainer> CreateSceneCommand::auxiliaryChanges() const
{
return m_auxiliaryChangeVector;
}
QVector<AddImportContainer> CreateSceneCommand::imports() const
{
return m_importVector;
}
QVector<MockupTypeContainer> CreateSceneCommand::mockupTypes() const
{
return m_mockupTypeVector;
}
QUrl CreateSceneCommand::fileUrl() const
{
return m_fileUrl;
}
QHash<QString, QVariantMap> CreateSceneCommand::edit3dToolStates() const
{
return m_edit3dToolStates;
}
QString CreateSceneCommand::language() const
{
return m_language;
}
QDataStream &operator<<(QDataStream &out, const CreateSceneCommand &command)
{
out << command.instances();
out << command.reparentInstances();
out << command.ids();
out << command.valueChanges();
out << command.bindingChanges();
out << command.auxiliaryChanges();
out << command.imports();
out << command.mockupTypes();
out << command.fileUrl();
out << command.edit3dToolStates();
out << command.language();
return out;
}
QDataStream &operator>>(QDataStream &in, CreateSceneCommand &command)
{
in >> command.m_instanceVector;
in >> command.m_reparentInstanceVector;
in >> command.m_idVector;
in >> command.m_valueChangeVector;
in >> command.m_bindingChangeVector;
in >> command.m_auxiliaryChangeVector;
in >> command.m_importVector;
in >> command.m_mockupTypeVector;
in >> command.m_fileUrl;
in >> command.m_edit3dToolStates;
in >> command.m_language;
return in;
}
QDebug operator <<(QDebug debug, const CreateSceneCommand &command) QDebug operator <<(QDebug debug, const CreateSceneCommand &command)
{ {
return debug.nospace() << "CreateSceneCommand(" return debug.nospace() << "CreateSceneCommand("
<< "instances: " << command.instances() << ", " << "instances: " << command.instances << ", "
<< "reparentInstances: " << command.reparentInstances() << ", " << "reparentInstances: " << command.reparentInstances << ", "
<< "ids: " << command.ids() << ", " << "ids: " << command.ids << ", "
<< "valueChanges: " << command.valueChanges() << ", " << "valueChanges: " << command.valueChanges << ", "
<< "bindingChanges: " << command.bindingChanges() << ", " << "bindingChanges: " << command.bindingChanges << ", "
<< "auxiliaryChanges: " << command.auxiliaryChanges() << ", " << "auxiliaryChanges: " << command.auxiliaryChanges << ", "
<< "imports: " << command.imports() << ", " << "imports: " << command.imports << ", "
<< "mockupTypes: " << command.mockupTypes() << ", " << "mockupTypes: " << command.mockupTypes << ", "
<< "fileUrl: " << command.fileUrl() << ", " << "fileUrl: " << command.fileUrl << ", "
<< "edit3dToolStates: " << command.edit3dToolStates() << ", " << "edit3dToolStates: " << command.edit3dToolStates << ", "
<< "language: " << command.language() << ")"; << "language: " << command.language << ")";
} }
} }

View File

@@ -41,12 +41,9 @@ namespace QmlDesigner {
class CreateSceneCommand class CreateSceneCommand
{ {
friend QDataStream &operator>>(QDataStream &in, CreateSceneCommand &command);
public: public:
CreateSceneCommand(); CreateSceneCommand() = default;
explicit CreateSceneCommand( explicit CreateSceneCommand(const QVector<InstanceContainer> &instanceContainer,
const QVector<InstanceContainer> &instanceContainer,
const QVector<ReparentContainer> &reparentContainer, const QVector<ReparentContainer> &reparentContainer,
const QVector<IdContainer> &idVector, const QVector<IdContainer> &idVector,
const QVector<PropertyValueContainer> &valueChangeVector, const QVector<PropertyValueContainer> &valueChangeVector,
@@ -56,38 +53,75 @@ public:
const QVector<MockupTypeContainer> &mockupTypeVector, const QVector<MockupTypeContainer> &mockupTypeVector,
const QUrl &fileUrl, const QUrl &fileUrl,
const QHash<QString, QVariantMap> &edit3dToolStates, const QHash<QString, QVariantMap> &edit3dToolStates,
const QString &language); const QString &language,
qint32 stateInstanceId)
: instances(instanceContainer)
, reparentInstances(reparentContainer)
, ids(idVector)
, valueChanges(valueChangeVector)
, bindingChanges(bindingChangeVector)
, auxiliaryChanges(auxiliaryChangeVector)
, imports(importVector)
, mockupTypes(mockupTypeVector)
, fileUrl(fileUrl)
, edit3dToolStates(edit3dToolStates)
, language(language)
, stateInstanceId{stateInstanceId}
{}
QVector<InstanceContainer> instances() const; friend QDataStream &operator<<(QDataStream &out, const CreateSceneCommand &command)
QVector<ReparentContainer> reparentInstances() const; {
QVector<IdContainer> ids() const; out << command.instances;
QVector<PropertyValueContainer> valueChanges() const; out << command.reparentInstances;
QVector<PropertyBindingContainer> bindingChanges() const; out << command.ids;
QVector<PropertyValueContainer> auxiliaryChanges() const; out << command.valueChanges;
QVector<AddImportContainer> imports() const; out << command.bindingChanges;
QVector<MockupTypeContainer> mockupTypes() const; out << command.auxiliaryChanges;
QUrl fileUrl() const; out << command.imports;
QHash<QString, QVariantMap> edit3dToolStates() const; out << command.mockupTypes;
QString language() const; out << command.fileUrl;
out << command.edit3dToolStates;
out << command.language;
out << command.stateInstanceId;
private: return out;
QVector<InstanceContainer> m_instanceVector; }
QVector<ReparentContainer> m_reparentInstanceVector;
QVector<IdContainer> m_idVector; friend QDataStream &operator>>(QDataStream &in, CreateSceneCommand &command)
QVector<PropertyValueContainer> m_valueChangeVector; {
QVector<PropertyBindingContainer> m_bindingChangeVector; in >> command.instances;
QVector<PropertyValueContainer> m_auxiliaryChangeVector; in >> command.reparentInstances;
QVector<AddImportContainer> m_importVector; in >> command.ids;
QVector<MockupTypeContainer> m_mockupTypeVector; in >> command.valueChanges;
QUrl m_fileUrl; in >> command.bindingChanges;
QHash<QString, QVariantMap> m_edit3dToolStates; in >> command.auxiliaryChanges;
QString m_language; in >> command.imports;
in >> command.mockupTypes;
in >> command.fileUrl;
in >> command.edit3dToolStates;
in >> command.language;
in >> command.stateInstanceId;
return in;
}
public:
QVector<InstanceContainer> instances;
QVector<ReparentContainer> reparentInstances;
QVector<IdContainer> ids;
QVector<PropertyValueContainer> valueChanges;
QVector<PropertyBindingContainer> bindingChanges;
QVector<PropertyValueContainer> auxiliaryChanges;
QVector<AddImportContainer> imports;
QVector<MockupTypeContainer> mockupTypes;
QUrl fileUrl;
QHash<QString, QVariantMap> edit3dToolStates;
QString language;
qint32 stateInstanceId = 0;
}; };
QDataStream &operator<<(QDataStream &out, const CreateSceneCommand &command); QDebug operator<<(QDebug debug, const CreateSceneCommand &command);
QDataStream &operator>>(QDataStream &in, CreateSceneCommand &command);
QDebug operator <<(QDebug debug, const CreateSceneCommand &command); } // namespace QmlDesigner
}
Q_DECLARE_METATYPE(QmlDesigner::CreateSceneCommand) Q_DECLARE_METATYPE(QmlDesigner::CreateSceneCommand)

View File

@@ -128,15 +128,16 @@ static void writeSharedMemory(SharedMemory *sharedMemory, const QImage &image)
{ {
sharedMemory->lock(); sharedMemory->lock();
qint32 headerData[5]; qint32 headerData[6];
headerData[0] = qint32(image.sizeInBytes()); headerData[0] = qint32(image.sizeInBytes());
headerData[1] = image.bytesPerLine(); headerData[1] = image.bytesPerLine();
headerData[2] = image.size().width(); headerData[2] = image.size().width();
headerData[3] = image.size().height(); headerData[3] = image.size().height();
headerData[4] = image.format(); headerData[4] = image.format();
headerData[5] = image.devicePixelRatio() * 100;
std::memcpy(sharedMemory->data(), headerData, 20); std::memcpy(sharedMemory->data(), headerData, 24);
std::memcpy(reinterpret_cast<char*>(sharedMemory->data()) + 20, image.constBits(), image.sizeInBytes()); std::memcpy(reinterpret_cast<char*>(sharedMemory->data()) + 24, image.constBits(), image.sizeInBytes());
sharedMemory->unlock(); sharedMemory->unlock();
} }
@@ -146,12 +147,13 @@ static void writeStream(QDataStream &out, const QImage &image)
out << image.size(); out << image.size();
out << qint32(image.format()); out << qint32(image.format());
out << qint32(image.sizeInBytes()); out << qint32(image.sizeInBytes());
out << qint32(image.devicePixelRatio() * 100);
out.writeRawData(reinterpret_cast<const char*>(image.constBits()), image.sizeInBytes()); out.writeRawData(reinterpret_cast<const char*>(image.constBits()), image.sizeInBytes());
} }
QDataStream &operator<<(QDataStream &out, const ImageContainer &container) QDataStream &operator<<(QDataStream &out, const ImageContainer &container)
{ {
const int extraDataSize = 20; const int extraDataSize = 24;
static const bool dontUseSharedMemory = qEnvironmentVariableIsSet("DESIGNER_DONT_USE_SHARED_MEMORY"); static const bool dontUseSharedMemory = qEnvironmentVariableIsSet("DESIGNER_DONT_USE_SHARED_MEMORY");
out << container.instanceId(); out << container.instanceId();
@@ -183,24 +185,26 @@ static void readSharedMemory(qint32 key, ImageContainer &container)
bool canAttach = sharedMemory.attach(QSharedMemory::ReadOnly); bool canAttach = sharedMemory.attach(QSharedMemory::ReadOnly);
if (canAttach && sharedMemory.size() >= 20) if (canAttach && sharedMemory.size() >= 24)
{ {
sharedMemory.lock(); sharedMemory.lock();
qint32 headerData[5]; qint32 headerData[6];
std::memcpy(headerData, sharedMemory.constData(), 20); std::memcpy(headerData, sharedMemory.constData(), 24);
qint32 byteCount = headerData[0]; qint32 byteCount = headerData[0];
// qint32 bytesPerLine = headerData[1]; // qint32 bytesPerLine = headerData[1];
qint32 imageWidth = headerData[2]; qint32 imageWidth = headerData[2];
qint32 imageHeight = headerData[3]; qint32 imageHeight = headerData[3];
qint32 imageFormat = headerData[4]; qint32 imageFormat = headerData[4];
qreal pixelRatio = headerData[5] / 100.0;
QImage image = QImage(imageWidth, imageHeight, QImage::Format(imageFormat)); QImage image = QImage(imageWidth, imageHeight, QImage::Format(imageFormat));
image.setDevicePixelRatio(pixelRatio);
if (image.isNull()) if (image.isNull())
qDebug() << Q_FUNC_INFO << "Not able to create image:" << imageWidth << imageHeight << imageFormat; qDebug() << Q_FUNC_INFO << "Not able to create image:" << imageWidth << imageHeight << imageFormat;
else else
std::memcpy(image.bits(), reinterpret_cast<const qint32*>(sharedMemory.constData()) + 5, byteCount); std::memcpy(image.bits(), reinterpret_cast<const qint32*>(sharedMemory.constData()) + 6, byteCount);
container.setImage(image); container.setImage(image);
@@ -215,6 +219,7 @@ static void readStream(QDataStream &in, ImageContainer &container)
qint32 bytesPerLine; qint32 bytesPerLine;
QSize imageSize; QSize imageSize;
qint32 imageFormat; qint32 imageFormat;
qint32 pixelRatio;
in >> bytesPerLine; in >> bytesPerLine;
in >> imageSize; in >> imageSize;
@@ -224,6 +229,7 @@ static void readStream(QDataStream &in, ImageContainer &container)
QImage image = QImage(imageSize, QImage::Format(imageFormat)); QImage image = QImage(imageSize, QImage::Format(imageFormat));
in.readRawData(reinterpret_cast<char*>(image.bits()), byteCount); in.readRawData(reinterpret_cast<char*>(image.bits()), byteCount);
image.setDevicePixelRatio(pixelRatio / 100.0);
container.setImage(image); container.setImage(image);
} }

View File

@@ -318,12 +318,13 @@ void NodeInstanceServer::stopRenderTimer()
void NodeInstanceServer::createScene(const CreateSceneCommand &command) void NodeInstanceServer::createScene(const CreateSceneCommand &command)
{ {
setTranslationLanguage(command.language()); setTranslationLanguage(command.language);
initializeView(); initializeView();
Internal::QmlPrivateGate::stopUnifiedTimer(); Internal::QmlPrivateGate::stopUnifiedTimer();
setupScene(command); setupScene(command);
setupState(command.stateInstanceId);
refreshBindings(); refreshBindings();
startRenderTimer(); startRenderTimer();
} }
@@ -399,15 +400,7 @@ void NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &comma
void NodeInstanceServer::changeState(const ChangeStateCommand &command) void NodeInstanceServer::changeState(const ChangeStateCommand &command)
{ {
if (hasInstanceForId(command.stateInstanceId())) { setupState(command.stateInstanceId());
if (activeStateInstance().isValid())
activeStateInstance().deactivateState();
ServerNodeInstance instance = instanceForId(command.stateInstanceId());
instance.activateState();
} else {
if (activeStateInstance().isValid())
activeStateInstance().deactivateState();
}
startRenderTimer(); startRenderTimer();
} }
@@ -569,38 +562,37 @@ void NodeInstanceServer::setupDefaultDummyData()
QList<ServerNodeInstance> NodeInstanceServer::setupInstances(const CreateSceneCommand &command) QList<ServerNodeInstance> NodeInstanceServer::setupInstances(const CreateSceneCommand &command)
{ {
QList<ServerNodeInstance> instanceList = createInstances(command.instances()); QList<ServerNodeInstance> instanceList = createInstances(command.instances);
foreach (const IdContainer &container, command.ids()) { for (const IdContainer &container : std::as_const(command.ids)) {
if (hasInstanceForId(container.instanceId())) if (hasInstanceForId(container.instanceId()))
instanceForId(container.instanceId()).setId(container.id()); instanceForId(container.instanceId()).setId(container.id());
} }
foreach (const PropertyValueContainer &container, command.valueChanges()) { for (const PropertyValueContainer &container : std::as_const(command.valueChanges)) {
if (container.isDynamic()) if (container.isDynamic())
setInstancePropertyVariant(container); setInstancePropertyVariant(container);
} }
foreach (const PropertyValueContainer &container, command.valueChanges()) { for (const PropertyValueContainer &container : std::as_const(command.valueChanges)) {
if (!container.isDynamic()) if (!container.isDynamic())
setInstancePropertyVariant(container); setInstancePropertyVariant(container);
} }
reparentInstances(command.reparentInstances()); reparentInstances(command.reparentInstances);
foreach (const PropertyBindingContainer &container, command.bindingChanges()) { for (const PropertyBindingContainer &container : std::as_const(command.bindingChanges)) {
if (container.isDynamic()) if (container.isDynamic())
setInstancePropertyBinding(container); setInstancePropertyBinding(container);
} }
foreach (const PropertyBindingContainer &container, command.bindingChanges()) { for (const PropertyBindingContainer &container : std::as_const(command.bindingChanges)) {
if (!container.isDynamic()) if (!container.isDynamic())
setInstancePropertyBinding(container); setInstancePropertyBinding(container);
} }
foreach (const PropertyValueContainer &container, command.auxiliaryChanges()) { for (const PropertyValueContainer &container : std::as_const(command.auxiliaryChanges))
setInstanceAuxiliaryData(container); setInstanceAuxiliaryData(container);
}
for (int i = instanceList.size(); --i >= 0; ) for (int i = instanceList.size(); --i >= 0; )
instanceList[i].doComponentComplete(); instanceList[i].doComponentComplete();
@@ -1498,4 +1490,17 @@ void NodeInstanceServer::handleInstanceHidden(const ServerNodeInstance &/*instan
{ {
} }
void NodeInstanceServer::setupState(qint32 stateInstanceId)
{
if (hasInstanceForId(stateInstanceId)) {
if (activeStateInstance().isValid())
activeStateInstance().deactivateState();
ServerNodeInstance instance = instanceForId(stateInstanceId);
instance.activateState();
} else {
if (activeStateInstance().isValid())
activeStateInstance().deactivateState();
}
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -289,6 +289,7 @@ protected:
static QList<QObject*> allSubObjectsForObject(QObject *object); static QList<QObject*> allSubObjectsForObject(QObject *object);
virtual void resizeCanvasSizeToRootItemSize() = 0; virtual void resizeCanvasSizeToRootItemSize() = 0;
void setupState(qint32 stateInstanceId);
private: private:
void setupOnlyWorkingImports(const QStringList &workingImportStatementList); void setupOnlyWorkingImports(const QStringList &workingImportStatementList);

View File

@@ -583,7 +583,8 @@ void Qt5InformationNodeInstanceServer::renderModelNodeImageView()
void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView() void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView()
{ {
// Disable preview in Qt6 until QTBUG-QTBUG-88320 is fixed
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
ServerNodeInstance instance; ServerNodeInstance instance;
if (m_modelNodePreviewImageCommand.renderItemId() >= 0) if (m_modelNodePreviewImageCommand.renderItemId() >= 0)
instance = instanceForId(m_modelNodePreviewImageCommand.renderItemId()); instance = instanceForId(m_modelNodePreviewImageCommand.renderItemId());
@@ -594,6 +595,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView()
doRenderModelNode3DImageView(); doRenderModelNode3DImageView();
else if (instance.isSubclassOf("QQuickItem")) else if (instance.isSubclassOf("QQuickItem"))
doRenderModelNode2DImageView(); doRenderModelNode2DImageView();
#endif
} }
void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
@@ -1316,8 +1318,7 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
Qt5NodeInstanceServer::createScene(command); Qt5NodeInstanceServer::createScene(command);
QList<ServerNodeInstance> instanceList; QList<ServerNodeInstance> instanceList;
const auto instances = command.instances(); for (const InstanceContainer &container : std::as_const(command.instances)) {
for (const InstanceContainer &container : instances) {
if (hasInstanceForId(container.instanceId())) { if (hasInstanceForId(container.instanceId())) {
ServerNodeInstance instance = instanceForId(container.instanceId()); ServerNodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid()) if (instance.isValid())
@@ -1331,7 +1332,7 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList)); nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList));
if (isQuick3DMode()) if (isQuick3DMode())
setup3DEditView(instanceList, command.edit3dToolStates()); setup3DEditView(instanceList, command.edit3dToolStates);
QObject::connect(&m_renderModelNodeImageViewTimer, &QTimer::timeout, QObject::connect(&m_renderModelNodeImageViewTimer, &QTimer::timeout,
this, &Qt5InformationNodeInstanceServer::doRenderModelNodeImageView); this, &Qt5InformationNodeInstanceServer::doRenderModelNodeImageView);
@@ -1675,6 +1676,10 @@ void Qt5InformationNodeInstanceServer::handleInstanceLocked(const ServerNodeInst
} }
} }
} }
#else
Q_UNUSED(instance);
Q_UNUSED(enable);
Q_UNUSED(checkAncestors);
#endif #endif
} }
@@ -1745,6 +1750,10 @@ void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInst
} }
} }
} }
#else
Q_UNUSED(instance);
Q_UNUSED(enable);
Q_UNUSED(checkAncestors);
#endif #endif
} }

View File

@@ -82,12 +82,6 @@ void Qt5NodeInstanceServer::initializeView()
fileSelector->setExtraSelectors(customSelectors); fileSelector->setExtraSelectors(customSelectors);
} }
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
// View needs to be shown for all puppets before any instances are created in case there is a View3D
quickView()->show();
quickView()->lower();
#endif
initializeAuxiliaryViews(); initializeAuxiliaryViews();
} }
@@ -116,11 +110,10 @@ void Qt5NodeInstanceServer::resetAllItems()
void Qt5NodeInstanceServer::setupScene(const CreateSceneCommand &command) void Qt5NodeInstanceServer::setupScene(const CreateSceneCommand &command)
{ {
setupMockupTypes(command.mockupTypes);
setupMockupTypes(command.mockupTypes()); setupFileUrl(command.fileUrl);
setupFileUrl(command.fileUrl()); setupImports(command.imports);
setupImports(command.imports()); setupDummyData(command.fileUrl);
setupDummyData(command.fileUrl());
setupInstances(command); setupInstances(command);
quickView()->resize(rootNodeInstance().boundingRect().size().toSize()); quickView()->resize(rootNodeInstance().boundingRect().size().toSize());

View File

@@ -46,7 +46,7 @@ Qt5PreviewNodeInstanceServer::Qt5PreviewNodeInstanceServer(NodeInstanceClientInt
void Qt5PreviewNodeInstanceServer::createScene(const CreateSceneCommand &command) void Qt5PreviewNodeInstanceServer::createScene(const CreateSceneCommand &command)
{ {
setTranslationLanguage(command.language()); setTranslationLanguage(command.language);
initializeView(); initializeView();
setupScene(command); setupScene(command);
startRenderTimer(); startRenderTimer();

View File

@@ -137,7 +137,7 @@ void Qt5RenderNodeInstanceServer::createScene(const CreateSceneCommand &command)
Qt5NodeInstanceServer::createScene(command); Qt5NodeInstanceServer::createScene(command);
QList<ServerNodeInstance> instanceList; QList<ServerNodeInstance> instanceList;
foreach (const InstanceContainer &container, command.instances()) { for (const InstanceContainer &container : std::as_const(command.instances)) {
if (hasInstanceForId(container.instanceId())) { if (hasInstanceForId(container.instanceId())) {
ServerNodeInstance instance = instanceForId(container.instanceId()); ServerNodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid()) { if (instance.isValid()) {

View File

@@ -187,7 +187,6 @@ void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &object
} }
ObjectNodeInstance::initialize(objectNodeInstance, flags); ObjectNodeInstance::initialize(objectNodeInstance, flags);
quickItem()->update();
} }
QQuickItem *QuickItemNodeInstance::contentItem() const QQuickItem *QuickItemNodeInstance::contentItem() const
@@ -429,12 +428,14 @@ QImage QuickItemNodeInstance::renderImage() const
nodeInstanceServer()->quickView()->afterRendering(); nodeInstanceServer()->quickView()->afterRendering();
} }
renderImage.setDevicePixelRatio(devicePixelRatio);
#else #else
renderImage = nodeInstanceServer()->quickView()->grabWindow(); renderImage = nodeInstanceServer()->quickView()->grabWindow();
renderImage = renderImage.copy(renderBoundingRect.toRect());
/* When grabbing an offscren window the device pixel ratio is 1 */
renderImage.setDevicePixelRatio(1);
#endif #endif
renderImage.setDevicePixelRatio(devicePixelRatio);
return renderImage; return renderImage;
} }
@@ -463,6 +464,7 @@ QImage QuickItemNodeInstance::renderPreviewImage(const QSize &previewImageSize)
} }
#else #else
image = nodeInstanceServer()->quickView()->grabWindow(); image = nodeInstanceServer()->quickView()->grabWindow();
image = image.copy(previewItemBoundingRect.toRect());
#endif #endif
image = image.scaledToWidth(size.width()); image = image.scaledToWidth(size.width());
@@ -542,7 +544,9 @@ void QuickItemNodeInstance::updateDirtyNodesRecursive(QQuickItem *parentItem) co
} }
QmlPrivateGate::disableNativeTextRendering(parentItem); QmlPrivateGate::disableNativeTextRendering(parentItem);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
DesignerSupport::updateDirtyNode(parentItem); DesignerSupport::updateDirtyNode(parentItem);
#endif
} }
void QuickItemNodeInstance::updateAllDirtyNodesRecursive(QQuickItem *parentItem) const void QuickItemNodeInstance::updateAllDirtyNodesRecursive(QQuickItem *parentItem) const

View File

@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.9)
# Remove when sharing with others.
list(APPEND CMAKE_PREFIX_PATH "%{QtCreatorBuild}")
project(%{PluginName})
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 17)
find_package(QtCreator COMPONENTS Core REQUIRED)
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
set(QtX Qt${QT_VERSION_MAJOR})
add_qtc_plugin(%{PluginName}
PLUGIN_DEPENDS
QtCreator::Core
DEPENDS
${QtX}::Widgets
QtCreator::ExtensionSystem
QtCreator::Utils
SOURCES
.github/workflows/build_cmake.yml
.github/workflows/README.md
README.md
%{SrcFileName}
%{HdrFileName}
%{GlobalHdrFileName}
%{ConstantsHdrFileName}
)

View File

@@ -0,0 +1,35 @@
# %{PluginName}
## How to Build
Create a build directory and run
cmake -DCMAKE_PREFIX_PATH=<path_to_qtcreator> -DCMAKE_BUILD_TYPE=RelWithDebInfo <path_to_plugin_source>
cmake --build .
where `<path_to_qtcreator>` is the relative or absolute path to a Qt Creator build directory, or to
a combined binary and development package, and `<path_to_plugin_source>` is the relative or absolute
path to this plugin directory.
## How to Run
Run a compatible Qt Creator with the additional command line argument
-pluginpath <path_to_plugin>
where `<path_to_plugin>` is the path to the resulting plugin library in the build directory
(`<plugin_build>/lib/qtcreator/plugins` on Windows and Linux,
`<plugin_build>/Qt Creator.app/Contents/PlugIns` on macOS).
You might want to add `-temporarycleansettings` (or `-tcs`) to ensure that the opened Qt Creator
instance cannot mess with your user-global Qt Creator settings.
When building and running the plugin from Qt Creator, you can use
-pluginpath "%{buildDir}/lib/qtcreator/plugins" -tcs
on Windows and Linux, or
-pluginpath "%{buildDir}/Qt Creator.app/Contents/PlugIns" -tcs
for the `Command line arguments` field in the run settings.

View File

@@ -1,6 +1,6 @@
# GitHub Actions & Workflows # GitHub Actions & Workflows
The `build_qmake.yml` in this directory adds a [GitHub action][1] and workflow that builds The `build_cmake.yml` in this directory adds a [GitHub action][1] and workflow that builds
your plugin anytime you push commits to GitHub on Windows, Linux and macOS. your plugin anytime you push commits to GitHub on Windows, Linux and macOS.
The build artifacts can be downloaded from GitHub and be installed into an existing Qt Creator The build artifacts can be downloaded from GitHub and be installed into an existing Qt Creator

View File

@@ -3,11 +3,12 @@ name: Build plugin
on: [push] on: [push]
env: env:
PLUGIN_NAME: %{PluginName}
QT_VERSION: %{JS: Util.qtVersion()} QT_VERSION: %{JS: Util.qtVersion()}
QT_CREATOR_VERSION: %{JS: Util.qtCreatorVersion()} QT_CREATOR_VERSION: %{JS: Util.qtCreatorVersion()}
QT_CREATOR_SNAPSHOT: NO QT_CREATOR_SNAPSHOT: NO
PLUGIN_PRO: %{ProFile} CMAKE_VERSION: 3.18.3
PLUGIN_NAME: %{PluginName} NINJA_VERSION: 1.10.1
jobs: jobs:
build: build:
@@ -17,82 +18,114 @@ jobs:
matrix: matrix:
config: config:
- { - {
name: "Windows Latest x64", artifact: "Windows-x64.zip", name: "Windows Latest MSVC", artifact: "Windows-x64",
os: windows-latest, os: windows-latest,
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat" cc: "cl", cxx: "cl",
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat",
} }
- { - {
name: "Windows Latest x86", artifact: "Windows-x86.zip", name: "Ubuntu Latest GCC", artifact: "Linux-x64",
os: windows-latest, os: ubuntu-latest,
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars32.bat" cc: "gcc", cxx: "g++"
} }
- { - {
name: "Linux Latest x64", artifact: "Linux-x64.zip", name: "macOS Latest Clang", artifact: "macOS-x64",
os: ubuntu-latest os: macos-latest,
} cc: "clang", cxx: "clang++"
- {
name: "macOS Latest x64", artifact: "macOS-x64.zip",
os: macos-latest
} }
steps: steps:
- uses: actions/checkout@v1 - uses: actions/checkout@v1
- name: Installing system libs - name: Download Ninja and CMake
shell: cmake -P {0}
run: |
set(cmake_version "$ENV{CMAKE_VERSION}")
set(ninja_version "$ENV{NINJA_VERSION}")
if ("${{ runner.os }}" STREQUAL "Windows")
set(ninja_suffix "win.zip")
set(cmake_suffix "win64-x64.zip")
set(cmake_dir "cmake-${cmake_version}-win64-x64/bin")
elseif ("${{ runner.os }}" STREQUAL "Linux")
set(ninja_suffix "linux.zip")
set(cmake_suffix "Linux-x86_64.tar.gz")
set(cmake_dir "cmake-${cmake_version}-Linux-x86_64/bin")
elseif ("${{ runner.os }}" STREQUAL "macOS")
set(ninja_suffix "mac.zip")
set(cmake_suffix "Darwin-x86_64.tar.gz")
set(cmake_dir "cmake-${cmake_version}-Darwin-x86_64/CMake.app/Contents/bin")
endif()
set(ninja_url "https://github.com/ninja-build/ninja/releases/download/v${ninja_version}/ninja-${ninja_suffix}")
file(DOWNLOAD "${ninja_url}" ./ninja.zip SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ninja.zip)
set(cmake_url "https://github.com/Kitware/CMake/releases/download/v${cmake_version}/cmake-${cmake_version}-${cmake_suffix}")
file(DOWNLOAD "${cmake_url}" ./cmake.zip SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./cmake.zip)
# Add to PATH environment variable
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir)
set(path_separator ":")
if ("${{ runner.os }}" STREQUAL "Windows")
set(path_separator ";")
endif()
file(APPEND "$ENV{GITHUB_PATH}" "$ENV{GITHUB_WORKSPACE}${path_separator}${cmake_dir}")
if (NOT "${{ runner.os }}" STREQUAL "Windows")
execute_process(
COMMAND chmod +x ninja
COMMAND chmod +x ${cmake_dir}/cmake
)
endif()
- name: Install system libs
shell: cmake -P {0} shell: cmake -P {0}
run: | run: |
if ("${{ runner.os }}" STREQUAL "Linux") if ("${{ runner.os }}" STREQUAL "Linux")
execute_process( execute_process(
COMMAND sudo apt install libgl1-mesa-dev COMMAND sudo apt update
) )
elseif ("${{ runner.os }}" STREQUAL "Windows") execute_process(
# get JOM COMMAND sudo apt install libgl1-mesa-dev
file(DOWNLOAD "https://download.qt.io/official_releases/jom/jom.zip" ./jom.zip SHOW_PROGRESS) RESULT_VARIABLE result
file(MAKE_DIRECTORY ./jom) )
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../jom.zip WORKING_DIRECTORY ./jom) if (NOT result EQUAL 0)
message(FATAL_ERROR "Failed to install dependencies")
endif()
endif() endif()
- name: Download Qt - name: Download Qt
id: qt id: qt
shell: cmake -P {0} shell: cmake -P {0}
run: | run: |
set(qt_version $ENV{QT_VERSION}) set(qt_version "$ENV{QT_VERSION}")
string(REPLACE "." "" qt_version_dotless "${qt_version}") string(REPLACE "." "" qt_version_dotless "${qt_version}")
if ("${{ runner.os }}" STREQUAL "Windows") if ("${{ runner.os }}" STREQUAL "Windows")
set(url_os "windows_x86") set(url_os "windows_x86")
if ("${{ matrix.config.environment_script }}" MATCHES "vcvars64.bat") set(qt_package_arch_suffix "win64_msvc2019_64")
set(qt_package_name "qt.qt5.${qt_version_dotless}.win64_msvc2019_64")
set(qt_dir_prefix "${qt_version}/msvc2019_64") set(qt_dir_prefix "${qt_version}/msvc2019_64")
elseif ("${{ matrix.config.environment_script }}" MATCHES "vcvars32.bat") set(qt_package_suffix "-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64")
set(qt_package_name "qt.qt5.${qt_version_dotless}.win32_msvc2019")
set(qt_dir_prefix "${qt_version}/msvc2019")
else()
endif()
elseif ("${{ runner.os }}" STREQUAL "Linux") elseif ("${{ runner.os }}" STREQUAL "Linux")
set(url_os "linux_x64") set(url_os "linux_x64")
set(qt_package_name "qt.qt5.${qt_version_dotless}.gcc_64") set(qt_package_arch_suffix "gcc_64")
set(qt_dir_prefix "${qt_version}/gcc_64") set(qt_dir_prefix "${qt_version}/gcc_64")
set(qt_package_suffix "-Linux-RHEL_7_6-GCC-Linux-RHEL_7_6-X86_64")
elseif ("${{ runner.os }}" STREQUAL "macOS") elseif ("${{ runner.os }}" STREQUAL "macOS")
set(url_os "mac_x64") set(url_os "mac_x64")
set(qt_package_name "qt.qt5.${qt_version_dotless}.clang_64") set(qt_package_arch_suffix "clang_64")
set(qt_dir_prefix "${qt_version}/clang_64") set(qt_dir_prefix "${qt_version}/clang_64")
set(qt_package_suffix "-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64")
endif() endif()
set(qt_base_url "https://download.qt.io/online/qtsdkrepository/${url_os}/desktop/qt5_${qt_version_dotless}") set(qt_base_url "https://download.qt.io/online/qtsdkrepository/${url_os}/desktop/qt5_${qt_version_dotless}")
file(DOWNLOAD "${qt_base_url}/Updates.xml" ./Updates.xml SHOW_PROGRESS) file(DOWNLOAD "${qt_base_url}/Updates.xml" ./Updates.xml SHOW_PROGRESS)
file(READ ./Updates.xml updates_xml) file(READ ./Updates.xml updates_xml)
string(REGEX MATCH "<Name>${qt_package_name}.*<Version>([0-9+-.]+)</Version>.*<DownloadableArchives>qtbase([a-zA-Z0-9_-]+).7z" string(REGEX MATCH "<Name>qt.qt5.*<Version>([0-9+-.]+)</Version>" updates_xml_output "${updates_xml}")
updates_xml_output "${updates_xml}") set(qt_package_version ${CMAKE_MATCH_1})
set(package_version ${CMAKE_MATCH_1})
set(package_suffix ${CMAKE_MATCH_2})
string(REPLACE "-debug-symbols" "" package_suffix "${package_suffix}")
# Workaround for CMake's greedy regex
if ("${{ matrix.config.environment_script }}" MATCHES "vcvars32.bat")
string(REPLACE "X86_64" "X86" package_suffix "${package_suffix}")
endif()
file(MAKE_DIRECTORY qt5) file(MAKE_DIRECTORY qt5)
@@ -100,20 +133,27 @@ jobs:
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt5/${qt_dir_prefix}" qt_dir) file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt5/${qt_dir_prefix}" qt_dir)
message("::set-output name=qt_dir::${qt_dir}") message("::set-output name=qt_dir::${qt_dir}")
foreach(package qtbase qtdeclarative qttools qtsvg) message("Downloading Qt to ${qt_dir}")
file(DOWNLOAD function(downloadAndExtract url archive)
"${qt_base_url}/${qt_package_name}/${package_version}${package}${package_suffix}.7z" ./${package}.7z message("Downloading ${url}")
SHOW_PROGRESS file(DOWNLOAD "${url}" ./${archive} SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../${archive} WORKING_DIRECTORY qt5)
endfunction()
foreach(package qtbase qtdeclarative)
downloadAndExtract(
"${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z"
${package}.7z
) )
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../${package}.7z WORKING_DIRECTORY qt5)
endforeach() endforeach()
file(READ "qt5/${qt_dir_prefix}/mkspecs/qconfig.pri" qtconfig) # uic depends on libicu56.so
string(REPLACE "Enterprise" "OpenSource" qtconfig "${qtconfig}") if ("${{ runner.os }}" STREQUAL "Linux")
string(REPLACE "licheck.exe" "" qtconfig "${qtconfig}") downloadAndExtract(
string(REPLACE "licheck64" "" qtconfig "${qtconfig}") "${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}icu-linux-Rhel7.2-x64.7z"
string(REPLACE "licheck_mac" "" qtconfig "${qtconfig}") icu.7z
file(WRITE "qt5/${qt_dir_prefix}/mkspecs/qconfig.pri" "${qtconfig}") )
endif()
- name: Download Qt Creator - name: Download Qt Creator
id: qt_creator id: qt_creator
@@ -128,29 +168,21 @@ jobs:
endif() endif()
if ("${{ runner.os }}" STREQUAL "Windows") if ("${{ runner.os }}" STREQUAL "Windows")
set(qtc_output_directory "qtcreator/lib/qtcreator/plugins")
set(qtc_binary_name "$ENV{PLUGIN_NAME}4.dll")
if ("${{ matrix.config.environment_script }}" MATCHES "vcvars64.bat")
set(qtc_platform "windows_x64") set(qtc_platform "windows_x64")
elseif ("${{ matrix.config.environment_script }}" MATCHES "vcvars32.bat")
set(qtc_platform "windows_x86")
endif()
elseif ("${{ runner.os }}" STREQUAL "Linux") elseif ("${{ runner.os }}" STREQUAL "Linux")
set(qtc_output_directory "qtcreator/lib/qtcreator/plugins")
set(qtc_binary_name "lib$ENV{PLUGIN_NAME}.so")
set(qtc_platform "linux_x64") set(qtc_platform "linux_x64")
elseif ("${{ runner.os }}" STREQUAL "macOS") elseif ("${{ runner.os }}" STREQUAL "macOS")
set(qtc_output_directory "qtcreator/bin/Qt Creator.app/Contents/PlugIns")
set(qtc_binary_name "lib$ENV{PLUGIN_NAME}.dylib")
set(qtc_platform "mac_x64") set(qtc_platform "mac_x64")
endif() endif()
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qtcreator" qtc_dir)
# Save the path for other steps # Save the path for other steps
message("::set-output name=qtc_binary_name::${qtc_binary_name}") message("::set-output name=qtc_dir::${qtc_dir}")
message("::set-output name=qtc_output_directory::${qtc_output_directory}")
file(MAKE_DIRECTORY qtcreator) file(MAKE_DIRECTORY qtcreator)
message("Downloading Qt Creator from ${qtc_base_url}/${qtc_platform}")
foreach(package qtcreator qtcreator_dev) foreach(package qtcreator qtcreator_dev)
file(DOWNLOAD file(DOWNLOAD
"${qtc_base_url}/${qtc_platform}/${package}.7z" ./${package}.7z SHOW_PROGRESS) "${qtc_base_url}/${qtc_platform}/${package}.7z" ./${package}.7z SHOW_PROGRESS)
@@ -158,18 +190,13 @@ jobs:
${CMAKE_COMMAND} -E tar xvf ../${package}.7z WORKING_DIRECTORY qtcreator) ${CMAKE_COMMAND} -E tar xvf ../${package}.7z WORKING_DIRECTORY qtcreator)
endforeach() endforeach()
if ("${{ runner.os }}" STREQUAL "macOS")
execute_process(
COMMAND ${CMAKE_COMMAND} -E make_directory qtcreator/bin
COMMAND ${CMAKE_COMMAND} -E create_symlink
"$ENV{GITHUB_WORKSPACE}/qtcreator/Qt Creator.app"
"$ENV{GITHUB_WORKSPACE}/qtcreator/bin/Qt Creator.app"
)
endif()
- name: Build - name: Build
shell: cmake -P {0} shell: cmake -P {0}
run: | run: |
set(ENV{CC} ${{ matrix.config.cc }})
set(ENV{CXX} ${{ matrix.config.cxx }})
set(ENV{MACOSX_DEPLOYMENT_TARGET} "10.13")
if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x")
execute_process( execute_process(
COMMAND "${{ matrix.config.environment_script }}" && set COMMAND "${{ matrix.config.environment_script }}" && set
@@ -183,55 +210,32 @@ jobs:
endforeach() endforeach()
endif() endif()
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qtcreator" qtcreator_dir) set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ")
execute_process( execute_process(
COMMAND ${{ steps.qt.outputs.qt_dir }}/bin/qmake COMMAND python
$ENV{PLUGIN_PRO} -u
CONFIG+=release ${{ steps.qt_creator.outputs.qtc_dir }}/scripts/build_plugin.py
IDE_SOURCE_TREE="${qtcreator_dir}" --name "$ENV{PLUGIN_NAME}-$ENV{QT_CREATOR_VERSION}-${{ matrix.config.artifact }}"
IDE_BUILD_TREE="${qtcreator_dir}" --src .
--build build
--qt-path "${{ steps.qt.outputs.qt_dir }}"
--qtc-path "${{ steps.qt_creator.outputs.qtc_dir }}"
--output-path "$ENV{GITHUB_WORKSPACE}"
RESULT_VARIABLE result RESULT_VARIABLE result
) )
if (NOT result EQUAL 0) if (NOT result EQUAL 0)
message(FATAL_ERROR "Bad exit status") string(REGEX MATCH "FAILED:.*$" error_message "${output}")
string(REPLACE "\\n" "%0A" error_message "${error_message}")
message("::error::${error_message}")
message(FATAL_ERROR "Build failed")
endif() endif()
if ("${{ runner.os }}" STREQUAL "Windows") - uses: actions/upload-artifact@v2
set(ENV{PATH} "${{ steps.qt.outputs.qt_dir }}/bin/;$ENV{PATH}")
else()
set(ENV{PATH} "${{ steps.qt.outputs.qt_dir }}/bin/:$ENV{PATH}")
set(ENV{LD_LIBRARY_PATH} "qtcreator/lib/Qt/lib:$ENV{LD_LIBRARY_PATH}")
endif()
include(ProcessorCount)
ProcessorCount(N)
set(make_program make -j ${N})
if ("${{ runner.os }}" STREQUAL "Windows")
set(make_program "jom/jom")
endif()
execute_process(
COMMAND ${make_program}
RESULT_VARIABLE result
)
if (NOT result EQUAL 0)
message(FATAL_ERROR "Bad exit status")
endif()
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/$ENV{PLUGIN_NAME}-$ENV{QT_CREATOR_VERSION}-${{ matrix.config.artifact }}" artifact)
execute_process(COMMAND
${CMAKE_COMMAND} -E tar cvf ${artifact} --format=zip "${{ steps.qt_creator.outputs.qtc_binary_name }}"
WORKING_DIRECTORY "${{ steps.qt_creator.outputs.qtc_output_directory }}"
)
- uses: actions/upload-artifact@v1
id: upload_artifact id: upload_artifact
with: with:
path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z
name: ${{ env.PLUGIN_NAME}}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} name: ${{ env.PLUGIN_NAME}}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z
release: release:
if: contains(github.ref, 'tags/v') if: contains(github.ref, 'tags/v')
@@ -268,19 +272,15 @@ jobs:
matrix: matrix:
config: config:
- { - {
name: "Windows Latest x64", artifact: "Windows-x64.zip", name: "Windows Latest x64", artifact: "Windows-x64.7z",
os: ubuntu-latest os: ubuntu-latest
} }
- { - {
name: "Windows Latest x86", artifact: "Windows-x86.zip", name: "Linux Latest x64", artifact: "Linux-x64.7z",
os: ubuntu-latest os: ubuntu-latest
} }
- { - {
name: "Linux Latest x64", artifact: "Linux-x64.zip", name: "macOS Latest x64", artifact: "macOS-x64.7z",
os: ubuntu-latest
}
- {
name: "macOS Latest x64", artifact: "macOS-x64.zip",
os: macos-latest os: macos-latest
} }
needs: release needs: release
@@ -311,4 +311,4 @@ jobs:
upload_url: ${{ steps.set_upload_url.outputs.upload_url }} upload_url: ${{ steps.set_upload_url.outputs.upload_url }}
asset_path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} asset_path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}
asset_name: ${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} asset_name: ${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}
asset_content_type: application/zip asset_content_type: application/x-7z-compressed

View File

@@ -1,53 +0,0 @@
DEFINES += %{LibraryDefine}
# %{PluginName} files
SOURCES += \\
%{SrcFileName}
HEADERS += \\
%{HdrFileName} \\
%{GlobalHdrFileName} \\
%{ConstantsHdrFileName}
DISTFILES += \\
.github/workflows/build_qmake.yml \\
.github/workflows/README.md
# Qt Creator linking
## Either set the IDE_SOURCE_TREE when running qmake,
## or set the QTC_SOURCE environment variable, to override the default setting
isEmpty(IDE_SOURCE_TREE): IDE_SOURCE_TREE = $$(QTC_SOURCE)
isEmpty(IDE_SOURCE_TREE): IDE_SOURCE_TREE = "%{QtCreatorSources}"
## Either set the IDE_BUILD_TREE when running qmake,
## or set the QTC_BUILD environment variable, to override the default setting
isEmpty(IDE_BUILD_TREE): IDE_BUILD_TREE = $$(QTC_BUILD)
isEmpty(IDE_BUILD_TREE): IDE_BUILD_TREE = "%{QtCreatorBuild}"
## uncomment to build plugin into user config directory
## <localappdata>/plugins/<ideversion>
## where <localappdata> is e.g.
## "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later
## "$XDG_DATA_HOME/data/QtProject/qtcreator" or "~/.local/share/data/QtProject/qtcreator" on Linux
## "~/Library/Application Support/QtProject/Qt Creator" on OS X
%{DestDir}USE_USER_DESTDIR = yes
###### If the plugin can be depended upon by other plugins, this code needs to be outsourced to
###### <dirname>_dependencies.pri, where <dirname> is the name of the directory containing the
###### plugin's sources.
QTC_PLUGIN_NAME = %{PluginName}
QTC_LIB_DEPENDS += \\
# nothing here at this time
QTC_PLUGIN_DEPENDS += \\
coreplugin
QTC_PLUGIN_RECOMMENDS += \\
# optional plugin dependencies. nothing here at this time
###### End _dependencies.pri contents ######
include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri)

View File

@@ -8,13 +8,12 @@
"trDisplayCategory": "Library", "trDisplayCategory": "Library",
"icon": "qtcreatorplugin.png", "icon": "qtcreatorplugin.png",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt", "QtSupport.Wizards.FeatureDesktop" ], "featuresRequired": [ "QtSupport.Wizards.FeatureQt", "QtSupport.Wizards.FeatureDesktop" ],
"enabled": "%{JS: value('Plugins').indexOf('QmakeProjectManager') >= 0}", "enabled": "%{JS: value('Plugins').indexOf('CMakeProjectManager') >= 0}",
"options": "options":
[ [
{ "key": "ProjectFile", "value": "%{ProFile}" }, { "key": "ProjectFile", "value": "%{ProjectDirectory}/CMakeLists.txt" },
{ "key": "PluginNameLower", "value": "%{JS: value('PluginName').toLowerCase()}"}, { "key": "PluginNameLower", "value": "%{JS: value('PluginName').toLowerCase()}"},
{ "key": "ProFile", "value": "%{JS: Util.fileName(value('PluginNameLower'), 'pro')}" },
{ "key": "PluginJsonFile", "value": "%{JS: Util.fileName(value('PluginName'), 'json.in')}" }, { "key": "PluginJsonFile", "value": "%{JS: Util.fileName(value('PluginName'), 'json.in')}" },
{ "key": "LibraryDefine", "value": "%{JS: Cpp.headerGuard(value('PluginName')) + '_LIBRARY'}" }, { "key": "LibraryDefine", "value": "%{JS: Cpp.headerGuard(value('PluginName')) + '_LIBRARY'}" },
{ "key": "LibraryExport", "value": "%{JS: Cpp.headerGuard(value('PluginName')) + '_EXPORT'}" }, { "key": "LibraryExport", "value": "%{JS: Cpp.headerGuard(value('PluginName')) + '_EXPORT'}" },
@@ -115,17 +114,6 @@
"trText": "https://www.%{JS: encodeURIComponent(value('VendorName').toLowerCase())}.com" "trText": "https://www.%{JS: encodeURIComponent(value('VendorName').toLowerCase())}.com"
} }
}, },
{
"name": "QtCreatorSources",
"persistenceKey": "QtCreatorSources",
"trDisplayName": "Qt Creator sources:",
"mandatory": true,
"type": "PathChooser",
"data":
{
"kind": "existingDirectory"
}
},
{ {
"name": "QtCreatorBuild", "name": "QtCreatorBuild",
"persistenceKey": "QtCreatorBuild", "persistenceKey": "QtCreatorBuild",
@@ -136,27 +124,6 @@
{ {
"kind": "existingDirectory" "kind": "existingDirectory"
} }
},
{
"name": "DestDir",
"persistenceKey": "QtCreatorPluginDestDir",
"trDisplayName": "Deploy into:",
"type": "ComboBox",
"data":
{
"index": 0,
"items":
[
{
"trKey": "Qt Creator Build",
"value": "# "
},
{
"trKey": "Local User Settings",
"value": ""
}
]
}
} }
] ]
}, },
@@ -185,13 +152,16 @@
"data": "data":
[ [
{ {
"source": "myplugin.pro", "source": "CMakeLists.txt",
"target": "%{ProFile}",
"openAsProject": true "openAsProject": true
}, },
{ {
"source": "github_workflows_build_qmake.yml", "source": "README.md",
"target": ".github/workflows/build_qmake.yml" "openInEditor": true
},
{
"source": "github_workflows_build_cmake.yml",
"target": ".github/workflows/build_cmake.yml"
}, },
{ {
"source": "github_workflows_README.md", "source": "github_workflows_README.md",
@@ -199,8 +169,7 @@
}, },
{ {
"source": "myplugin.cpp", "source": "myplugin.cpp",
"target": "%{SrcFileName}", "target": "%{SrcFileName}"
"openInEditor": true
}, },
{ {
"source": "myplugin.h", "source": "myplugin.h",

View File

@@ -25,6 +25,7 @@ install(
${PROJECT_SOURCE_DIR}/scripts ${PROJECT_SOURCE_DIR}/scripts
DESTINATION ./ DESTINATION ./
COMPONENT Devel EXCLUDE_FROM_ALL COMPONENT Devel EXCLUDE_FROM_ALL
USE_SOURCE_PERMISSIONS
) )
install(EXPORT QtCreator install(EXPORT QtCreator
@@ -70,7 +71,7 @@ export(EXPORT QtCreator
FILE ${CMAKE_BINARY_DIR}/cmake/QtCreatorTargets.cmake) FILE ${CMAKE_BINARY_DIR}/cmake/QtCreatorTargets.cmake)
file(COPY file(COPY
${PROJECT_SOURCE_DIR}/cmake/QtCreatorIDEBranding.cmake ${IDE_BRANDING_FILE}
${PROJECT_SOURCE_DIR}/cmake/QtCreatorTranslations.cmake ${PROJECT_SOURCE_DIR}/cmake/QtCreatorTranslations.cmake
${PROJECT_SOURCE_DIR}/cmake/QtCreatorDocumentation.cmake ${PROJECT_SOURCE_DIR}/cmake/QtCreatorDocumentation.cmake
${PROJECT_SOURCE_DIR}/cmake/QtCreatorAPI.cmake ${PROJECT_SOURCE_DIR}/cmake/QtCreatorAPI.cmake
@@ -83,7 +84,7 @@ file(COPY
# Devel package install # Devel package install
install( install(
FILES FILES
${PROJECT_SOURCE_DIR}/cmake/QtCreatorIDEBranding.cmake ${IDE_BRANDING_FILE}
${PROJECT_SOURCE_DIR}/cmake/QtCreatorTranslations.cmake ${PROJECT_SOURCE_DIR}/cmake/QtCreatorTranslations.cmake
${PROJECT_SOURCE_DIR}/cmake/QtCreatorDocumentation.cmake ${PROJECT_SOURCE_DIR}/cmake/QtCreatorDocumentation.cmake
${PROJECT_SOURCE_DIR}/cmake/QtCreatorAPI.cmake ${PROJECT_SOURCE_DIR}/cmake/QtCreatorAPI.cmake

View File

@@ -66,10 +66,16 @@ if (APPLE)
"${CMAKE_CURRENT_BINARY_DIR}/qtcreator.icns" "${CMAKE_CURRENT_BINARY_DIR}/qtcreator.icns"
"${CMAKE_CURRENT_BINARY_DIR}/qtcreator-project.icns" "${CMAKE_CURRENT_BINARY_DIR}/qtcreator-project.icns"
) )
set_source_files_properties( qtc_copy_to_builddir(copy_icns
"${CMAKE_CURRENT_BINARY_DIR}/qtcreator.icns" DESTINATION ${IDE_DATA_PATH}
"${CMAKE_CURRENT_BINARY_DIR}/qtcreator-project.icns" FILES
PROPERTIES ${CMAKE_CURRENT_BINARY_DIR}/qtcreator.icns
MACOSX_PACKAGE_LOCATION "Resources" ${CMAKE_CURRENT_BINARY_DIR}/qtcreator-project.icns
)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/qtcreator.icns
${CMAKE_CURRENT_BINARY_DIR}/qtcreator-project.icns
DESTINATION ${IDE_DATA_PATH}
) )
endif() endif()

View File

@@ -341,11 +341,13 @@ static void setHighDpiEnvironmentVariable()
&& !qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR") && !qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR")
&& !qEnvironmentVariableIsSet("QT_SCALE_FACTOR") && !qEnvironmentVariableIsSet("QT_SCALE_FACTOR")
&& !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS")) { && !qEnvironmentVariableIsSet("QT_SCREEN_SCALE_FACTORS")) {
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#if QT_VERSION == QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION == QT_VERSION_CHECK(5, 14, 0)
// work around QTBUG-80934 // work around QTBUG-80934
QGuiApplication::setHighDpiScaleFactorRoundingPolicy( QGuiApplication::setHighDpiScaleFactorRoundingPolicy(
Qt::HighDpiScaleFactorRoundingPolicy::Round); Qt::HighDpiScaleFactorRoundingPolicy::Round);
#endif
#endif #endif
} }
} }
@@ -557,8 +559,8 @@ int main(int argc, char **argv)
CrashHandlerSetup::EnableRestart, libexecPath); CrashHandlerSetup::EnableRestart, libexecPath);
#endif #endif
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
app.setAttribute(Qt::AA_DisableWindowContextHelpButton); app.setAttribute(Qt::AA_DisableWindowContextHelpButton);
#endif #endif
@@ -586,7 +588,7 @@ int main(int argc, char **argv)
app.setProperty("qtc_locale", locale); app.setProperty("qtc_locale", locale);
break; break;
} }
translator.load(QString()); // unload() Q_UNUSED(translator.load(QString())); // unload()
} else if (locale == QLatin1String("C") /* overrideLanguage == "English" */) { } else if (locale == QLatin1String("C") /* overrideLanguage == "English" */) {
// use built-in // use built-in
break; break;

View File

@@ -19,8 +19,7 @@ namespace detail {
struct iterator_value; struct iterator_value;
template <typename V> template <typename V>
class iterator_base : public std::iterator<std::forward_iterator_tag, V, class iterator_base {
std::ptrdiff_t, V*, V> {
private: private:
template <typename> template <typename>
@@ -37,7 +36,11 @@ class iterator_base : public std::iterator<std::forward_iterator_tag, V,
}; };
public: public:
typedef typename iterator_base::value_type value_type; using iterator_category = std::forward_iterator_tag;
using value_type = V;
using difference_type = std::ptrdiff_t;
using pointer = V*;
using reference = V&;
public: public:
iterator_base() : m_iterator(), m_pMemory() {} iterator_base() : m_iterator(), m_pMemory() {}

View File

@@ -52,10 +52,7 @@ struct node_iterator_type<const V> {
}; };
template <typename V> template <typename V>
class node_iterator_base class node_iterator_base {
: public std::iterator<std::forward_iterator_tag, node_iterator_value<V>,
std::ptrdiff_t, node_iterator_value<V>*,
node_iterator_value<V>> {
private: private:
struct enabler {}; struct enabler {};
@@ -70,7 +67,11 @@ class node_iterator_base
public: public:
typedef typename node_iterator_type<V>::seq SeqIter; typedef typename node_iterator_type<V>::seq SeqIter;
typedef typename node_iterator_type<V>::map MapIter; typedef typename node_iterator_type<V>::map MapIter;
typedef node_iterator_value<V> value_type; using iterator_category = std::forward_iterator_tag;
using value_type = node_iterator_value<V>;
using difference_type = std::ptrdiff_t;
using pointer = node_iterator_value<V>*;
using reference = node_iterator_value<V>&;
node_iterator_base() node_iterator_base()
: m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {} : m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}

View File

@@ -26,6 +26,7 @@
#include "easingcontextpane.h" #include "easingcontextpane.h"
#include "ui_easingcontextpane.h" #include "ui_easingcontextpane.h"
#include <qmljs/qmljspropertyreader.h> #include <qmljs/qmljspropertyreader.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <QGraphicsPixmapItem> #include <QGraphicsPixmapItem>
@@ -287,8 +288,10 @@ void QmlEditorWidgets::EasingContextPane::on_durationSpinBox_valueChanged(int ne
emit propertyChanged(QLatin1String("duration"), newValue); emit propertyChanged(QLatin1String("duration"), newValue);
} }
void QmlEditorWidgets::EasingContextPane::on_easingShapeComboBox_currentIndexChanged(const QString &newShape) void QmlEditorWidgets::EasingContextPane::on_easingShapeComboBox_currentIndexChanged(int newIndex)
{ {
QTC_ASSERT(newIndex >= 0, return);
const QString newShape = ui->easingShapeComboBox->itemText(newIndex);
if (newShape==QLatin1String("Linear")) if (newShape==QLatin1String("Linear"))
setLinear(); setLinear();
else if (newShape==QLatin1String("Bounce")) else if (newShape==QLatin1String("Bounce"))
@@ -311,8 +314,10 @@ void QmlEditorWidgets::EasingContextPane::on_easingShapeComboBox_currentIndexCha
} }
} }
void QmlEditorWidgets::EasingContextPane::on_easingExtremesComboBox_currentIndexChanged(const QString &newExtremes) void QmlEditorWidgets::EasingContextPane::on_easingExtremesComboBox_currentIndexChanged(int newIndex)
{ {
QTC_ASSERT(newIndex >= 0, return);
const QString newExtremes = ui->easingExtremesComboBox->itemText(newIndex);
if (m_easingGraph->easingExtremes() != newExtremes) { if (m_easingGraph->easingExtremes() != newExtremes) {
m_easingGraph->setEasingExtremes(newExtremes); m_easingGraph->setEasingExtremes(newExtremes);
m_easingGraph->setAmplitude(ui->amplitudeSpinBox->value()); m_easingGraph->setAmplitude(ui->amplitudeSpinBox->value());

View File

@@ -77,8 +77,8 @@ private slots:
void on_overshootSpinBox_valueChanged(double); void on_overshootSpinBox_valueChanged(double);
void on_periodSpinBox_valueChanged(double); void on_periodSpinBox_valueChanged(double);
void on_amplitudeSpinBox_valueChanged(double); void on_amplitudeSpinBox_valueChanged(double);
void on_easingExtremesComboBox_currentIndexChanged(const QString &); void on_easingExtremesComboBox_currentIndexChanged(int);
void on_easingShapeComboBox_currentIndexChanged(const QString &); void on_easingShapeComboBox_currentIndexChanged(int);
void on_durationSpinBox_valueChanged(int); void on_durationSpinBox_valueChanged(int);
void switchToGraph(); void switchToGraph();

View File

@@ -151,6 +151,11 @@ void Database::applyAndUpdateSessions()
m_statements->sessions.applyAndUpdateSessions(); m_statements->sessions.applyAndUpdateSessions();
} }
SessionChangeSets Database::changeSets() const
{
return m_statements->sessions.changeSets();
}
const Utils::PathString &Database::databaseFilePath() const const Utils::PathString &Database::databaseFilePath() const
{ {
return m_databaseFilePath; return m_databaseFilePath;

View File

@@ -28,6 +28,7 @@
#include "sqlitedatabasebackend.h" #include "sqlitedatabasebackend.h"
#include "sqlitedatabaseinterface.h" #include "sqlitedatabaseinterface.h"
#include "sqliteglobal.h" #include "sqliteglobal.h"
#include "sqlitesessionchangeset.h"
#include "sqlitetable.h" #include "sqlitetable.h"
#include "sqlitetransaction.h" #include "sqlitetransaction.h"
@@ -131,6 +132,8 @@ public:
void setAttachedTables(const Utils::SmallStringVector &tables) override; void setAttachedTables(const Utils::SmallStringVector &tables) override;
void applyAndUpdateSessions() override; void applyAndUpdateSessions() override;
SessionChangeSets changeSets() const;
private: private:
void deferredBegin() override; void deferredBegin() override;
void immediateBegin() override; void immediateBegin() override;

View File

@@ -86,7 +86,7 @@ ValueView convertSqliteValue(sqlite3_value *value)
return ValueView::create(sqlite3_value_double(value)); return ValueView::create(sqlite3_value_double(value));
case SQLITE_TEXT: case SQLITE_TEXT:
return ValueView::create( return ValueView::create(
Utils::SmallStringView{reinterpret_cast<const char *const>(sqlite3_value_text(value)), Utils::SmallStringView{reinterpret_cast<const char *>(sqlite3_value_text(value)),
static_cast<std::size_t>(sqlite3_value_bytes(value))}); static_cast<std::size_t>(sqlite3_value_bytes(value))});
case SQLITE_NULL: case SQLITE_NULL:
return ValueView::create(NullValue{}); return ValueView::create(NullValue{});

View File

@@ -41,9 +41,10 @@ namespace Sqlite {
class Sessions; class Sessions;
namespace SessionChangeSetInternal {
enum class Operation : char { Invalid, Insert, Update, Delete }; enum class Operation : char { Invalid, Insert, Update, Delete };
namespace SessionChangeSetInternal {
class SentinelIterator class SentinelIterator
{}; {};
@@ -54,7 +55,7 @@ public:
ValueView oldValue; ValueView oldValue;
}; };
class ConstTupleIterator class SQLITE_EXPORT ConstTupleIterator
{ {
public: public:
using difference_type = int; using difference_type = int;
@@ -63,7 +64,9 @@ public:
using reference = const ValueView &; using reference = const ValueView &;
using iterator_category = std::forward_iterator_tag; using iterator_category = std::forward_iterator_tag;
ConstTupleIterator(sqlite3_changeset_iter *sessionIterator, int index, Operation operation) ConstTupleIterator(sqlite3_changeset_iter *sessionIterator,
int index,
Sqlite::Operation operation)
: m_sessionIterator{sessionIterator} : m_sessionIterator{sessionIterator}
, m_column{index} , m_column{index}
, m_operation{operation} , m_operation{operation}
@@ -91,10 +94,10 @@ public:
private: private:
sqlite3_changeset_iter *m_sessionIterator = {}; sqlite3_changeset_iter *m_sessionIterator = {};
int m_column = 0; int m_column = 0;
Operation m_operation = Operation::Invalid; Sqlite::Operation m_operation = Sqlite::Operation::Invalid;
}; };
class Tuple class SQLITE_EXPORT Tuple
{ {
public: public:
using difference_type = int; using difference_type = int;
@@ -108,7 +111,7 @@ public:
Utils::SmallStringView table; Utils::SmallStringView table;
sqlite3_changeset_iter *sessionIterator = {}; sqlite3_changeset_iter *sessionIterator = {};
int columnCount = 0; int columnCount = 0;
Operation operation = Operation::Invalid; Sqlite::Operation operation = Sqlite::Operation::Invalid;
ValueViews operator[](int column) const; ValueViews operator[](int column) const;
ConstTupleIterator begin() const { return {sessionIterator, 0, operation}; } ConstTupleIterator begin() const { return {sessionIterator, 0, operation}; }
@@ -117,7 +120,7 @@ public:
enum class State : char { Invalid, Row, Done }; enum class State : char { Invalid, Row, Done };
class ConstIterator class SQLITE_EXPORT ConstIterator
{ {
public: public:
using difference_type = long; using difference_type = long;
@@ -144,13 +147,19 @@ public:
ConstIterator &operator=(ConstIterator &&other) ConstIterator &operator=(ConstIterator &&other)
{ {
auto tmp = std::move(other); auto tmp = std::move(other);
std::swap(tmp, *this); swap(tmp, *this);
return *this; return *this;
} }
~ConstIterator(); ~ConstIterator();
friend void swap(ConstIterator &first, ConstIterator &second)
{
std::swap(first.m_sessionIterator, second.m_sessionIterator);
std::swap(first.m_state, second.m_state);
}
ConstIterator &operator++(); ConstIterator &operator++();
friend bool operator==(const ConstIterator &first, const ConstIterator &second) friend bool operator==(const ConstIterator &first, const ConstIterator &second)

View File

@@ -261,7 +261,7 @@ void runAsyncQFutureInterfaceDispatch(std::true_type, QFutureInterface<ResultTyp
template <typename ResultType, typename Function, typename... Args> template <typename ResultType, typename Function, typename... Args>
void runAsyncQFutureInterfaceDispatch(std::false_type, QFutureInterface<ResultType> futureInterface, Function &&function, Args&&... args) void runAsyncQFutureInterfaceDispatch(std::false_type, QFutureInterface<ResultType> futureInterface, Function &&function, Args&&... args)
{ {
runAsyncReturnVoidDispatch(std::is_void<std::result_of_t<Function(Args...)>>(), runAsyncReturnVoidDispatch(std::is_void<std::invoke_result_t<Function, Args...>>(),
futureInterface, std::forward<Function>(function), std::forward<Args>(args)...); futureInterface, std::forward<Function>(function), std::forward<Args>(args)...);
} }

View File

@@ -39,7 +39,6 @@
#include <QVector> #include <QVector>
#include <QHash> #include <QHash>
#include <QMap> #include <QMap>
#include <QFutureInterface>
#include <QVersionNumber> #include <QVersionNumber>
#include <utils/fileutils.h> #include <utils/fileutils.h>

View File

@@ -31,7 +31,6 @@
#include <qmldebug/qmldebugcommandlinearguments.h> #include <qmldebug/qmldebugcommandlinearguments.h>
#include <qmldebug/qmloutputparser.h> #include <qmldebug/qmloutputparser.h>
#include <QFutureInterface>
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include <QTcpSocket> #include <QTcpSocket>

View File

@@ -234,8 +234,9 @@ void AvdDialog::updateApiLevelComboBox()
m_avdDialog.targetApiComboBox->clear(); m_avdDialog.targetApiComboBox->clear();
for (SystemImage *image : filteredList) { for (SystemImage *image : filteredList) {
QString imageString = "android-" % QString::number(image->apiLevel()); QString imageString = "android-" % QString::number(image->apiLevel());
if (image->sdkStylePath().contains("playstore")) const QStringList imageSplits = image->sdkStylePath().split(';');
imageString += " (Google PlayStore)"; if (imageSplits.size() == 4)
imageString += QStringLiteral(" (%1)").arg(imageSplits.at(2));
m_avdDialog.targetApiComboBox->addItem(imageString, m_avdDialog.targetApiComboBox->addItem(imageString,
QVariant::fromValue<SystemImage *>(image)); QVariant::fromValue<SystemImage *>(image));
m_avdDialog.targetApiComboBox->setItemData(m_avdDialog.targetApiComboBox->count() - 1, m_avdDialog.targetApiComboBox->setItemData(m_avdDialog.targetApiComboBox->count() - 1,

View File

@@ -60,7 +60,6 @@
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QFutureWatcher>
#include <QMenu> #include <QMenu>
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QProcess> #include <QProcess>

View File

@@ -1,5 +1,5 @@
add_qtc_plugin(ClangFormat add_qtc_plugin(ClangFormat
CONDITION TARGET libclang CONDITION TARGET libclang AND LLVM_PACKAGE_VERSION VERSION_GREATER_EQUAL 10.0.0
DEPENDS Utils Qt5::Widgets clangFormat DEPENDS Utils Qt5::Widgets clangFormat
INCLUDES "${CLANG_INCLUDE_DIRS}" INCLUDES "${CLANG_INCLUDE_DIRS}"
PLUGIN_DEPENDS Core TextEditor CppEditor CppTools ProjectExplorer PLUGIN_DEPENDS Core TextEditor CppEditor CppTools ProjectExplorer

View File

@@ -115,7 +115,7 @@ static clang::format::FormatStyle qtcStyle()
style.ExperimentalAutoDetectBinPacking = false; style.ExperimentalAutoDetectBinPacking = false;
style.FixNamespaceComments = true; style.FixNamespaceComments = true;
style.ForEachMacros = {"forever", "foreach", "Q_FOREACH", "BOOST_FOREACH"}; style.ForEachMacros = {"forever", "foreach", "Q_FOREACH", "BOOST_FOREACH"};
style.IncludeStyle.IncludeCategories = {{"^<Q.*", 200}}; style.IncludeStyle.IncludeCategories = {{"^<Q.*", 200, 200}};
style.IncludeStyle.IncludeIsMainRegex = "(Test)?$"; style.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
style.IndentCaseLabels = false; style.IndentCaseLabels = false;
style.IndentWidth = 4; style.IndentWidth = 4;

View File

@@ -27,11 +27,10 @@
#include <coreplugin/find/ifindfilter.h> #include <coreplugin/find/ifindfilter.h>
#include <QFutureWatcher>
#include <QPointer>
#include <QWidget>
#include <QCheckBox> #include <QCheckBox>
#include <QPointer>
#include <QRadioButton> #include <QRadioButton>
#include <QWidget>
namespace Core { class SearchResult; } namespace Core { class SearchResult; }

View File

@@ -76,7 +76,7 @@ public:
int filesAnalyzed() const { return m_filesAnalyzed.size(); } int filesAnalyzed() const { return m_filesAnalyzed.size(); }
int filesNotAnalyzed() const { return m_filesNotAnalyzed.size(); } int filesNotAnalyzed() const { return m_filesNotAnalyzed.size(); }
int totalFilesToAnalyze() const { return m_fileInfos.size(); } int totalFilesToAnalyze() const { return int(m_fileInfos.size()); }
signals: signals:
void buildFailed(); void buildFailed();

View File

@@ -387,7 +387,7 @@ void ShortcutSettingsWidget::setupShortcutBox(ShortcutItem *scitem)
}; };
const auto addButtonToLayout = [this, updateAddButton] { const auto addButtonToLayout = [this, updateAddButton] {
m_shortcutLayout->addWidget(m_addButton, m_shortcutLayout->addWidget(m_addButton,
m_shortcutInputs.size() * 2 - 1, int(m_shortcutInputs.size() * 2 - 1),
m_shortcutLayout->columnCount() - 1); m_shortcutLayout->columnCount() - 1);
updateAddButton(); updateAddButton();
}; };
@@ -397,7 +397,7 @@ void ShortcutSettingsWidget::setupShortcutBox(ShortcutItem *scitem)
for (int i = 0; i < qMax(1, scitem->m_keys.size()); ++i) for (int i = 0; i < qMax(1, scitem->m_keys.size()); ++i)
addShortcutInput(i, scitem->m_keys.value(i)); addShortcutInput(i, scitem->m_keys.value(i));
connect(m_addButton, &QPushButton::clicked, this, [this, addShortcutInput, addButtonToLayout] { connect(m_addButton, &QPushButton::clicked, this, [this, addShortcutInput, addButtonToLayout] {
addShortcutInput(m_shortcutInputs.size(), {}); addShortcutInput(int(m_shortcutInputs.size()), {});
addButtonToLayout(); addButtonToLayout();
}); });
addButtonToLayout(); addButtonToLayout();

View File

@@ -27,7 +27,7 @@
#include <cppcheck/cppcheckoptions.h> #include <cppcheck/cppcheckoptions.h>
#include <QFuture> #include <QFutureInterface>
#include <QPointer> #include <QPointer>
#include <QRegularExpression> #include <QRegularExpression>

View File

@@ -91,7 +91,6 @@
#include <QAction> #include <QAction>
#include <QApplication> #include <QApplication>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QFutureWatcher>
#include <QMenu> #include <QMenu>
#include <QPointer> #include <QPointer>
#include <QTextEdit> #include <QTextEdit>

View File

@@ -4370,20 +4370,25 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_templateClass()
"template<class T>\n" "template<class T>\n"
"class Foo\n" "class Foo\n"
"{\n" "{\n"
" void fun@c();\n" " void fun@c1();\n"
"};\n"; " void func2();\n"
"};\n\n"
"template<class T>\n"
"void Foo<T>::func2() {}\n";
QByteArray expected = QByteArray expected =
"template<class T>\n" "template<class T>\n"
"class Foo\n" "class Foo\n"
"{\n" "{\n"
" void fun@c();\n" " void func1();\n"
"};\n" " void func2();\n"
"\n" "};\n\n"
"template<class T>\n" "template<class T>\n"
"void Foo::func()\n" // Should really be Foo<T>::func() "void Foo<T>::func1()\n"
"{\n" "{\n"
"\n" "\n"
"}\n"; "}\n\n"
"template<class T>\n"
"void Foo<T>::func2() {}\n";
InsertDefFromDecl factory; InsertDefFromDecl factory;
QuickFixOperationTest(singleDocument(original, expected), &factory); QuickFixOperationTest(singleDocument(original, expected), &factory);
@@ -4405,7 +4410,7 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_templateFunction()
"};\n" "};\n"
"\n" "\n"
"template<class T>\n" "template<class T>\n"
"void Foo::func()\n" "void Foo::func<T>()\n"
"{\n" "{\n"
"\n" "\n"
"}\n"; "}\n";

View File

@@ -3070,6 +3070,7 @@ public:
oo.showReturnTypes = true; oo.showReturnTypes = true;
oo.showArgumentNames = true; oo.showArgumentNames = true;
oo.showEnclosingTemplate = true; oo.showEnclosingTemplate = true;
oo.showTemplateParameters = true;
if (defPos == DefPosInsideClass) { if (defPos == DefPosInsideClass) {
const int targetPos = targetFile->position(loc.line(), loc.column()); const int targetPos = targetFile->position(loc.line(), loc.column());

View File

@@ -135,7 +135,6 @@ void classifyFiles(const QSet<QString> &files, QStringList *headers, QStringList
} }
void indexFindErrors(QFutureInterface<void> &indexingFuture, void indexFindErrors(QFutureInterface<void> &indexingFuture,
const QFutureInterface<void> &superFuture,
const ParseParams params) const ParseParams params)
{ {
QStringList sources, headers; QStringList sources, headers;
@@ -149,7 +148,7 @@ void indexFindErrors(QFutureInterface<void> &indexingFuture,
timer.start(); timer.start();
for (int i = 0, end = files.size(); i < end ; ++i) { for (int i = 0, end = files.size(); i < end ; ++i) {
if (indexingFuture.isCanceled() || superFuture.isCanceled()) if (indexingFuture.isCanceled())
break; break;
const QString file = files.at(i); const QString file = files.at(i);
@@ -179,7 +178,6 @@ void indexFindErrors(QFutureInterface<void> &indexingFuture,
} }
void index(QFutureInterface<void> &indexingFuture, void index(QFutureInterface<void> &indexingFuture,
const QFutureInterface<void> &superFuture,
const ParseParams params) const ParseParams params)
{ {
QScopedPointer<CppSourceProcessor> sourceProcessor(CppModelManager::createSourceProcessor()); QScopedPointer<CppSourceProcessor> sourceProcessor(CppModelManager::createSourceProcessor());
@@ -209,7 +207,7 @@ void index(QFutureInterface<void> &indexingFuture,
qCDebug(indexerLog) << "About to index" << files.size() << "files."; qCDebug(indexerLog) << "About to index" << files.size() << "files.";
for (int i = 0; i < files.size(); ++i) { for (int i = 0; i < files.size(); ++i) {
if (indexingFuture.isCanceled() || superFuture.isCanceled()) if (indexingFuture.isCanceled())
break; break;
const QString fileName = files.at(i); const QString fileName = files.at(i);
@@ -243,9 +241,7 @@ void index(QFutureInterface<void> &indexingFuture,
qCDebug(indexerLog) << "Indexing finished."; qCDebug(indexerLog) << "Indexing finished.";
} }
void parse(QFutureInterface<void> &indexingFuture, void parse(QFutureInterface<void> &indexingFuture, const ParseParams params)
const QFutureInterface<void> &superFuture,
const ParseParams params)
{ {
const QSet<QString> &files = params.sourceFiles; const QSet<QString> &files = params.sourceFiles;
if (files.isEmpty()) if (files.isEmpty())
@@ -254,9 +250,9 @@ void parse(QFutureInterface<void> &indexingFuture,
indexingFuture.setProgressRange(0, files.size()); indexingFuture.setProgressRange(0, files.size());
if (FindErrorsIndexing) if (FindErrorsIndexing)
indexFindErrors(indexingFuture, superFuture, params); indexFindErrors(indexingFuture, params);
else else
index(indexingFuture, superFuture, params); index(indexingFuture, params);
indexingFuture.setProgressValue(files.size()); indexingFuture.setProgressValue(files.size());
CppModelManager::instance()->finishedRefreshingSourceFiles(files); CppModelManager::instance()->finishedRefreshingSourceFiles(files);
@@ -349,9 +345,7 @@ BuiltinIndexingSupport::BuiltinIndexingSupport()
BuiltinIndexingSupport::~BuiltinIndexingSupport() = default; BuiltinIndexingSupport::~BuiltinIndexingSupport() = default;
QFuture<void> BuiltinIndexingSupport::refreshSourceFiles( QFuture<void> BuiltinIndexingSupport::refreshSourceFiles(
const QFutureInterface<void> &superFuture, const QSet<QString> &sourceFiles, CppModelManager::ProgressNotificationMode mode)
const QSet<QString> &sourceFiles,
CppModelManager::ProgressNotificationMode mode)
{ {
CppModelManager *mgr = CppModelManager::instance(); CppModelManager *mgr = CppModelManager::instance();
@@ -361,7 +355,7 @@ QFuture<void> BuiltinIndexingSupport::refreshSourceFiles(
params.workingCopy = mgr->workingCopy(); params.workingCopy = mgr->workingCopy();
params.sourceFiles = sourceFiles; params.sourceFiles = sourceFiles;
QFuture<void> result = Utils::runAsync(mgr->sharedThreadPool(), parse, superFuture, params); QFuture<void> result = Utils::runAsync(mgr->sharedThreadPool(), parse, params);
if (m_synchronizer.futures().size() > 10) { if (m_synchronizer.futures().size() > 10) {
QList<QFuture<void> > futures = m_synchronizer.futures(); QList<QFuture<void> > futures = m_synchronizer.futures();

View File

@@ -38,8 +38,7 @@ public:
BuiltinIndexingSupport(); BuiltinIndexingSupport();
~BuiltinIndexingSupport() override; ~BuiltinIndexingSupport() override;
QFuture<void> refreshSourceFiles(const QFutureInterface<void> &superFuture, QFuture<void> refreshSourceFiles(const QSet<QString> &sourceFiles,
const QSet<QString> &sourceFiles,
CppModelManager::ProgressNotificationMode mode) override; CppModelManager::ProgressNotificationMode mode) override;
SymbolSearcher *createSymbolSearcher(const SymbolSearcher::Parameters &parameters, SymbolSearcher *createSymbolSearcher(const SymbolSearcher::Parameters &parameters,
const QSet<QString> &fileNames) override; const QSet<QString> &fileNames) override;

View File

@@ -48,6 +48,7 @@
#include <QtConcurrentMap> #include <QtConcurrentMap>
#include <QCheckBox> #include <QCheckBox>
#include <QDir> #include <QDir>
#include <QFutureWatcher>
#include <functional> #include <functional>

View File

@@ -31,7 +31,6 @@
#include <QObject> #include <QObject>
#include <QPointer> #include <QPointer>
#include <QFuture> #include <QFuture>
#include <QFutureWatcher>
QT_FORWARD_DECLARE_CLASS(QTimer) QT_FORWARD_DECLARE_CLASS(QTimer)

View File

@@ -78,9 +78,9 @@ class CPPTOOLS_EXPORT CppIndexingSupport
public: public:
virtual ~CppIndexingSupport() = 0; virtual ~CppIndexingSupport() = 0;
virtual QFuture<void> refreshSourceFiles(const QFutureInterface<void> &superFuture, virtual QFuture<void> refreshSourceFiles(const QSet<QString> &sourceFiles,
const QSet<QString> &sourceFiles, CppModelManager::ProgressNotificationMode mode)
CppModelManager::ProgressNotificationMode mode) = 0; = 0;
virtual SymbolSearcher *createSymbolSearcher(const SymbolSearcher::Parameters &parameters, virtual SymbolSearcher *createSymbolSearcher(const SymbolSearcher::Parameters &parameters,
const QSet<QString> &fileNames) = 0; const QSet<QString> &fileNames) = 0;
}; };

View File

@@ -929,14 +929,6 @@ static QSet<QString> tooBigFilesRemoved(const QSet<QString> &files, int fileSize
QFuture<void> CppModelManager::updateSourceFiles(const QSet<QString> &sourceFiles, QFuture<void> CppModelManager::updateSourceFiles(const QSet<QString> &sourceFiles,
ProgressNotificationMode mode) ProgressNotificationMode mode)
{
const QFutureInterface<void> dummy;
return updateSourceFiles(dummy, sourceFiles, mode);
}
QFuture<void> CppModelManager::updateSourceFiles(const QFutureInterface<void> &superFuture,
const QSet<QString> &sourceFiles,
ProgressNotificationMode mode)
{ {
if (sourceFiles.isEmpty() || !d->m_indexerEnabled) if (sourceFiles.isEmpty() || !d->m_indexerEnabled)
return QFuture<void>(); return QFuture<void>();
@@ -944,8 +936,8 @@ QFuture<void> CppModelManager::updateSourceFiles(const QFutureInterface<void> &s
const QSet<QString> filteredFiles = tooBigFilesRemoved(sourceFiles, indexerFileSizeLimitInMb()); const QSet<QString> filteredFiles = tooBigFilesRemoved(sourceFiles, indexerFileSizeLimitInMb());
if (d->m_indexingSupporter) if (d->m_indexingSupporter)
d->m_indexingSupporter->refreshSourceFiles(superFuture, filteredFiles, mode); d->m_indexingSupporter->refreshSourceFiles(filteredFiles, mode);
return d->m_internalIndexingSupport->refreshSourceFiles(superFuture, filteredFiles, mode); return d->m_internalIndexingSupport->refreshSourceFiles(filteredFiles, mode);
} }
QList<ProjectInfo> CppModelManager::projectInfos() const QList<ProjectInfo> CppModelManager::projectInfos() const
@@ -1078,12 +1070,11 @@ void CppModelManager::recalculateProjectPartMappings()
d->m_symbolFinder.clearCache(); d->m_symbolFinder.clearCache();
} }
void CppModelManager::watchForCanceledProjectIndexer(const QVector<QFuture<void>> &futures, void CppModelManager::watchForCanceledProjectIndexer(const QFuture<void> &future,
ProjectExplorer::Project *project) ProjectExplorer::Project *project)
{ {
for (const QFuture<void> &future : futures) {
if (future.isCanceled() || future.isFinished()) if (future.isCanceled() || future.isFinished())
continue; return;
auto watcher = new QFutureWatcher<void>(this); auto watcher = new QFutureWatcher<void>(this);
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, project, watcher]() { connect(watcher, &QFutureWatcher<void>::canceled, this, [this, project, watcher]() {
@@ -1096,7 +1087,6 @@ void CppModelManager::watchForCanceledProjectIndexer(const QVector<QFuture<void>
watcher->deleteLater(); watcher->deleteLater();
}); });
watcher->setFuture(future); watcher->setFuture(future);
}
} }
void CppModelManager::updateCppEditorDocuments(bool projectsUpdated) const void CppModelManager::updateCppEditorDocuments(bool projectsUpdated) const
@@ -1128,8 +1118,7 @@ void CppModelManager::updateCppEditorDocuments(bool projectsUpdated) const
} }
} }
QFuture<void> CppModelManager::updateProjectInfo(QFutureInterface<void> &futureInterface, QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectInfo)
const ProjectInfo &newProjectInfo)
{ {
if (!newProjectInfo.isValid()) if (!newProjectInfo.isValid())
return QFuture<void>(); return QFuture<void>();
@@ -1221,12 +1210,12 @@ QFuture<void> CppModelManager::updateProjectInfo(QFutureInterface<void> &futureI
updateCppEditorDocuments(/*projectsUpdated = */ true); updateCppEditorDocuments(/*projectsUpdated = */ true);
// Trigger reindexing // Trigger reindexing
const QFuture<void> indexingFuture = updateSourceFiles(futureInterface, filesToReindex, const QFuture<void> indexingFuture = updateSourceFiles(filesToReindex,
ForcedProgressNotification); ForcedProgressNotification);
if (!filesToReindex.isEmpty()) { if (!filesToReindex.isEmpty()) {
d->m_projectToIndexerCanceled.insert(project, false); d->m_projectToIndexerCanceled.insert(project, false);
} }
watchForCanceledProjectIndexer({futureInterface.future(), indexingFuture}, project); watchForCanceledProjectIndexer(indexingFuture, project);
return indexingFuture; return indexingFuture;
} }

View File

@@ -106,17 +106,13 @@ public:
QFuture<void> updateSourceFiles(const QSet<QString> &sourceFiles, QFuture<void> updateSourceFiles(const QSet<QString> &sourceFiles,
ProgressNotificationMode mode = ReservedProgressNotification); ProgressNotificationMode mode = ReservedProgressNotification);
QFuture<void> updateSourceFiles(const QFutureInterface<void> &superFuture,
const QSet<QString> &sourceFiles,
ProgressNotificationMode mode = ReservedProgressNotification);
void updateCppEditorDocuments(bool projectsUpdated = false) const; void updateCppEditorDocuments(bool projectsUpdated = false) const;
WorkingCopy workingCopy() const; WorkingCopy workingCopy() const;
QByteArray codeModelConfiguration() const; QByteArray codeModelConfiguration() const;
QList<ProjectInfo> projectInfos() const; QList<ProjectInfo> projectInfos() const;
ProjectInfo projectInfo(ProjectExplorer::Project *project) const; ProjectInfo projectInfo(ProjectExplorer::Project *project) const;
QFuture<void> updateProjectInfo(QFutureInterface<void> &futureInterface, QFuture<void> updateProjectInfo(const ProjectInfo &newProjectInfo);
const ProjectInfo &newProjectInfo);
/// \return The project part with the given project file /// \return The project part with the given project file
ProjectPart::Ptr projectPartForId(const QString &projectPartId) const override; ProjectPart::Ptr projectPartForId(const QString &projectPartId) const override;
@@ -274,7 +270,7 @@ private:
void initializeBuiltinModelManagerSupport(); void initializeBuiltinModelManagerSupport();
void delayedGC(); void delayedGC();
void recalculateProjectPartMappings(); void recalculateProjectPartMappings();
void watchForCanceledProjectIndexer(const QVector<QFuture<void> > &futures, void watchForCanceledProjectIndexer(const QFuture<void> &future,
ProjectExplorer::Project *project); ProjectExplorer::Project *project);
void replaceSnapshot(const CPlusPlus::Snapshot &newSnapshot); void replaceSnapshot(const CPlusPlus::Snapshot &newSnapshot);

View File

@@ -190,8 +190,7 @@ void CppToolsPlugin::test_modelmanager_paths_are_clean()
{testDataDir.frameworksDir(false), HeaderPathType::Framework}}; {testDataDir.frameworksDir(false), HeaderPathType::Framework}};
pi.appendProjectPart(part); pi.appendProjectPart(part);
QFutureInterface<void> dummy; mm->updateProjectInfo(pi);
mm->updateProjectInfo(dummy, pi);
ProjectExplorer::HeaderPaths headerPaths = mm->headerPaths(); ProjectExplorer::HeaderPaths headerPaths = mm->headerPaths();
QCOMPARE(headerPaths.size(), 2); QCOMPARE(headerPaths.size(), 2);
@@ -223,8 +222,7 @@ void CppToolsPlugin::test_modelmanager_framework_headers()
part->files << ProjectFile(source, ProjectFile::CXXSource); part->files << ProjectFile(source, ProjectFile::CXXSource);
pi.appendProjectPart(part); pi.appendProjectPart(part);
QFutureInterface<void> dummy; mm->updateProjectInfo(pi).waitForFinished();
mm->updateProjectInfo(dummy, pi).waitForFinished();
QCoreApplication::processEvents(); QCoreApplication::processEvents();
QVERIFY(mm->snapshot().contains(source)); QVERIFY(mm->snapshot().contains(source));
@@ -323,8 +321,7 @@ void CppToolsPlugin::test_modelmanager_refresh_several_times()
part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader)); part->files.append(ProjectFile(testHeader2, ProjectFile::CXXHeader));
part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource)); part->files.append(ProjectFile(testCpp, ProjectFile::CXXSource));
pi.appendProjectPart(part); pi.appendProjectPart(part);
QFutureInterface<void> dummy; mm->updateProjectInfo(pi);
mm->updateProjectInfo(dummy, pi);
CPlusPlus::Snapshot snapshot; CPlusPlus::Snapshot snapshot;
QSet<QString> refreshedFiles; QSet<QString> refreshedFiles;
@@ -387,8 +384,7 @@ void CppToolsPlugin::test_modelmanager_refresh_test_for_changes()
// Reindexing triggers a reparsing thread // Reindexing triggers a reparsing thread
helper.resetRefreshedSourceFiles(); helper.resetRefreshedSourceFiles();
QFutureInterface<void> dummy; QFuture<void> firstFuture = mm->updateProjectInfo(pi);
QFuture<void> firstFuture = mm->updateProjectInfo(dummy, pi);
QVERIFY(firstFuture.isStarted() || firstFuture.isRunning()); QVERIFY(firstFuture.isStarted() || firstFuture.isRunning());
firstFuture.waitForFinished(); firstFuture.waitForFinished();
const QSet<QString> refreshedFiles = helper.waitForRefreshedSourceFiles(); const QSet<QString> refreshedFiles = helper.waitForRefreshedSourceFiles();
@@ -396,7 +392,7 @@ void CppToolsPlugin::test_modelmanager_refresh_test_for_changes()
QVERIFY(refreshedFiles.contains(testCpp)); QVERIFY(refreshedFiles.contains(testCpp));
// No reindexing since nothing has changed // No reindexing since nothing has changed
QFuture<void> subsequentFuture = mm->updateProjectInfo(dummy, pi); QFuture<void> subsequentFuture = mm->updateProjectInfo(pi);
QVERIFY(subsequentFuture.isCanceled() && subsequentFuture.isFinished()); QVERIFY(subsequentFuture.isCanceled() && subsequentFuture.isFinished());
} }

View File

@@ -42,8 +42,7 @@ using namespace ProjectExplorer;
namespace CppTools { namespace CppTools {
namespace Internal { namespace Internal {
ProjectInfoGenerator::ProjectInfoGenerator( ProjectInfoGenerator::ProjectInfoGenerator(const QFutureInterface<ProjectInfo> &futureInterface,
const QFutureInterface<void> &futureInterface,
const ProjectUpdateInfo &projectUpdateInfo) const ProjectUpdateInfo &projectUpdateInfo)
: m_futureInterface(futureInterface) : m_futureInterface(futureInterface)
, m_projectUpdateInfo(projectUpdateInfo) , m_projectUpdateInfo(projectUpdateInfo)

View File

@@ -36,7 +36,7 @@ namespace Internal {
class ProjectInfoGenerator class ProjectInfoGenerator
{ {
public: public:
ProjectInfoGenerator(const QFutureInterface<void> &futureInterface, ProjectInfoGenerator(const QFutureInterface<ProjectInfo> &futureInterface,
const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo); const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo);
ProjectInfo generate(); ProjectInfo generate();
@@ -52,7 +52,7 @@ private:
Utils::LanguageExtensions languageExtensions); Utils::LanguageExtensions languageExtensions);
private: private:
const QFutureInterface<void> m_futureInterface; const QFutureInterface<ProjectInfo> m_futureInterface;
const ProjectExplorer::ProjectUpdateInfo &m_projectUpdateInfo; const ProjectExplorer::ProjectUpdateInfo &m_projectUpdateInfo;
bool m_cToolchainMissing = false; bool m_cToolchainMissing = false;
bool m_cxxToolchainMissing = false; bool m_cxxToolchainMissing = false;

View File

@@ -33,12 +33,16 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <QFutureInterface>
namespace CppTools { namespace CppTools {
CppProjectUpdater::CppProjectUpdater() CppProjectUpdater::CppProjectUpdater()
{ {
connect(&m_generateFutureWatcher, &QFutureWatcher<void>::finished, connect(&m_generateFutureWatcher,
this, &CppProjectUpdater::onProjectInfoGenerated); &QFutureWatcher<ProjectInfo>::finished,
this,
&CppProjectUpdater::onProjectInfoGenerated);
} }
CppProjectUpdater::~CppProjectUpdater() CppProjectUpdater::~CppProjectUpdater()
@@ -50,7 +54,6 @@ void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &project
{ {
// Stop previous update. // Stop previous update.
cancelAndWaitForFinished(); cancelAndWaitForFinished();
m_futureInterface = QFutureInterface<void>();
m_projectUpdateInfo = projectUpdateInfo; m_projectUpdateInfo = projectUpdateInfo;
@@ -60,26 +63,30 @@ void CppProjectUpdater::update(const ProjectExplorer::ProjectUpdateInfo &project
this, &CppProjectUpdater::onToolChainRemoved); this, &CppProjectUpdater::onToolChainRemoved);
// Run the project info generator in a worker thread and continue if that one is finished. // Run the project info generator in a worker thread and continue if that one is finished.
const QFuture<ProjectInfo> future = Utils::runAsync([=]() { m_generateFuture = Utils::runAsync([=](QFutureInterface<ProjectInfo> &futureInterface) {
ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo; ProjectUpdateInfo fullProjectUpdateInfo = projectUpdateInfo;
if (fullProjectUpdateInfo.rppGenerator) if (fullProjectUpdateInfo.rppGenerator)
fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator(); fullProjectUpdateInfo.rawProjectParts = fullProjectUpdateInfo.rppGenerator();
Internal::ProjectInfoGenerator generator(m_futureInterface, fullProjectUpdateInfo); Internal::ProjectInfoGenerator generator(futureInterface, fullProjectUpdateInfo);
return generator.generate(); futureInterface.reportResult(generator.generate());
}); });
m_generateFutureWatcher.setFuture(future); m_generateFutureWatcher.setFuture(m_generateFuture);
} }
void CppProjectUpdater::cancel() void CppProjectUpdater::cancel()
{ {
disconnect(&m_generateFutureWatcher); m_generateFutureWatcher.setFuture({});
m_futureInterface.cancel(); m_generateFuture.cancel();
m_updateFuture.cancel();
} }
void CppProjectUpdater::cancelAndWaitForFinished() void CppProjectUpdater::cancelAndWaitForFinished()
{ {
cancel(); cancel();
m_futureInterface.waitForFinished(); if (m_generateFuture.isRunning())
m_generateFuture.waitForFinished();
if (m_updateFuture.isRunning())
m_updateFuture.waitForFinished();
} }
void CppProjectUpdater::onToolChainRemoved(ProjectExplorer::ToolChain *t) void CppProjectUpdater::onToolChainRemoved(ProjectExplorer::ToolChain *t)
@@ -96,11 +103,11 @@ void CppProjectUpdater::onProjectInfoGenerated()
disconnect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved, disconnect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved,
this, &CppProjectUpdater::onToolChainRemoved); this, &CppProjectUpdater::onToolChainRemoved);
if (m_futureInterface.isCanceled()) if (m_generateFutureWatcher.isCanceled() || m_generateFutureWatcher.future().resultCount() < 1)
return; return;
QFuture<void> future = CppModelManager::instance() m_updateFuture = CppModelManager::instance()->updateProjectInfo(
->updateProjectInfo(m_futureInterface, m_generateFutureWatcher.result()); m_generateFutureWatcher.result());
} }
CppProjectUpdaterFactory::CppProjectUpdaterFactory() CppProjectUpdaterFactory::CppProjectUpdaterFactory()

View File

@@ -29,7 +29,6 @@
#include "cpptools_global.h" #include "cpptools_global.h"
#include "projectinfo.h" #include "projectinfo.h"
#include <QFutureInterface>
#include <QFutureWatcher> #include <QFutureWatcher>
namespace CppTools { namespace CppTools {
@@ -67,7 +66,8 @@ private:
private: private:
ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo; ProjectExplorer::ProjectUpdateInfo m_projectUpdateInfo;
QFutureInterface<void> m_futureInterface; QFuture<ProjectInfo> m_generateFuture;
QFuture<void> m_updateFuture;
QFutureWatcher<ProjectInfo> m_generateFutureWatcher; QFutureWatcher<ProjectInfo> m_generateFutureWatcher;
}; };

View File

@@ -32,6 +32,7 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <cplusplus/ASTPath.h>
#include <cplusplus/LookupContext.h> #include <cplusplus/LookupContext.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -545,6 +546,16 @@ static InsertionLocation nextToSurroundingDefinitions(Symbol *declaration,
return noResult; return noResult;
targetFile->cppDocument()->translationUnit()->getTokenStartPosition(functionDefinition->firstToken(), &line, &column); targetFile->cppDocument()->translationUnit()->getTokenStartPosition(functionDefinition->firstToken(), &line, &column);
const QList<AST *> path = ASTPath(targetFile->cppDocument())(line, column);
for (auto it = path.rbegin(); it != path.rend(); ++it) {
if (const auto templateDecl = (*it)->asTemplateDeclaration()) {
if (templateDecl->declaration == functionDefinition) {
targetFile->cppDocument()->translationUnit()->getTokenStartPosition(
templateDecl->firstToken(), &line, &column);
}
break;
}
}
} }
return InsertionLocation(QString::fromUtf8(definitionFunction->fileName()), prefix, suffix, line, column); return InsertionLocation(QString::fromUtf8(definitionFunction->fileName()), prefix, suffix, line, column);

View File

@@ -93,8 +93,7 @@ ModelManagerTestHelper::Project *ModelManagerTestHelper::createProject(const QSt
QSet<QString> ModelManagerTestHelper::updateProjectInfo(const CppTools::ProjectInfo &projectInfo) QSet<QString> ModelManagerTestHelper::updateProjectInfo(const CppTools::ProjectInfo &projectInfo)
{ {
resetRefreshedSourceFiles(); resetRefreshedSourceFiles();
QFutureInterface<void> dummy; CppModelManager::instance()->updateProjectInfo(projectInfo).waitForFinished();
CppModelManager::instance()->updateProjectInfo(dummy, projectInfo).waitForFinished();
QCoreApplication::processEvents(); QCoreApplication::processEvents();
return waitForRefreshedSourceFiles(); return waitForRefreshedSourceFiles();
} }

View File

@@ -145,7 +145,8 @@ bool SourcePathMappingModel::isNewPlaceHolder(const Mapping &m) const
// Return raw, unfixed mapping // Return raw, unfixed mapping
Mapping SourcePathMappingModel::rawMappingAt(int row) const Mapping SourcePathMappingModel::rawMappingAt(int row) const
{ {
return Mapping(item(row, SourceColumn)->text(), item(row, TargetColumn)->text()); return Mapping(QDir::fromNativeSeparators(item(row, SourceColumn)->text()),
QDir::fromNativeSeparators(item(row, TargetColumn)->text()));
} }
// Return mapping, empty if it is the place holder. // Return mapping, empty if it is the place holder.

View File

@@ -36,7 +36,6 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QFutureWatcher>
#include <QStringList> #include <QStringList>
#include <QUrl> #include <QUrl>

View File

@@ -40,7 +40,6 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <QFuture> #include <QFuture>
#include <QFutureWatcher>
#include <QQueue> #include <QQueue>
namespace MesonProjectManager { namespace MesonProjectManager {

View File

@@ -29,7 +29,6 @@
#include <projectexplorer/projectnodes.h> #include <projectexplorer/projectnodes.h>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QFutureWatcher>
#include <QTimer> #include <QTimer>
namespace Nim { namespace Nim {

View File

@@ -42,6 +42,7 @@
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <QDateTime> #include <QDateTime>
#include <QFutureInterface>
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QProcess> #include <QProcess>
#include <QThreadPool> #include <QThreadPool>

View File

@@ -34,7 +34,6 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <QByteArray> #include <QByteArray>
#include <QFuture>
#include <QHash> #include <QHash>
#include <QList> #include <QList>
@@ -43,6 +42,13 @@
QT_FORWARD_DECLARE_CLASS(QProcess); QT_FORWARD_DECLARE_CLASS(QProcess);
QT_FORWARD_DECLARE_CLASS(QThreadPool); QT_FORWARD_DECLARE_CLASS(QThreadPool);
QT_BEGIN_NAMESPACE
template <typename T>
class QFutureInterface;
template <typename T>
class QFutureWatcher;
QT_END_NAMESPACE
namespace ProjectExplorer { namespace ProjectExplorer {

View File

@@ -382,10 +382,11 @@ FileType FileNode::fileType() const
return m_fileType; return m_fileType;
} }
static QList<FileNode *> scanForFilesRecursively(const Utils::FilePath &directory, static QList<FileNode *> scanForFilesRecursively(QFutureInterface<QList<FileNode*>> &future,
const std::function<FileNode *(const Utils::FilePath &)> factory,
QSet<QString> &visited, QFutureInterface<QList<FileNode*>> *future,
double progressStart, double progressRange, double progressStart, double progressRange,
const Utils::FilePath &directory,
const std::function<FileNode *(const Utils::FilePath &)> factory,
QSet<QString> &visited,
const QList<Core::IVersionControl*> &versionControls) const QList<Core::IVersionControl*> &versionControls)
{ {
QList<FileNode *> result; QList<FileNode *> result;
@@ -403,7 +404,7 @@ static QList<FileNode *> scanForFilesRecursively(const Utils::FilePath &director
const double progressIncrement = progressRange / static_cast<double>(entries.count()); const double progressIncrement = progressRange / static_cast<double>(entries.count());
int lastIntProgress = 0; int lastIntProgress = 0;
for (const QFileInfo &entry : entries) { for (const QFileInfo &entry : entries) {
if (future && future->isCanceled()) if (future.isCanceled())
return result; return result;
const Utils::FilePath entryName = Utils::FilePath::fromString(entry.absoluteFilePath()); const Utils::FilePath entryName = Utils::FilePath::fromString(entry.absoluteFilePath());
@@ -411,33 +412,29 @@ static QList<FileNode *> scanForFilesRecursively(const Utils::FilePath &director
return vc->isVcsFileOrDirectory(entryName); return vc->isVcsFileOrDirectory(entryName);
})) { })) {
if (entry.isDir()) if (entry.isDir())
result.append(scanForFilesRecursively(entryName, factory, visited, future, progress, progressIncrement, versionControls)); result.append(scanForFilesRecursively(future, progress, progressIncrement, entryName, factory, visited, versionControls));
else if (FileNode *node = factory(entryName)) else if (FileNode *node = factory(entryName))
result.append(node); result.append(node);
} }
if (future) {
progress += progressIncrement; progress += progressIncrement;
const int intProgress = std::min(static_cast<int>(progressStart + progress), future->progressMaximum()); const int intProgress = std::min(static_cast<int>(progressStart + progress), future.progressMaximum());
if (lastIntProgress < intProgress) { if (lastIntProgress < intProgress) {
future->setProgressValue(intProgress); future.setProgressValue(intProgress);
lastIntProgress = intProgress; lastIntProgress = intProgress;
} }
} }
} future.setProgressValue(std::min(static_cast<int>(progressStart + progressRange), future.progressMaximum()));
if (future)
future->setProgressValue(std::min(static_cast<int>(progressStart + progressRange), future->progressMaximum()));
return result; return result;
} }
QList<FileNode *> QList<FileNode *>
FileNode::scanForFiles(const Utils::FilePath &directory, FileNode::scanForFiles(QFutureInterface<QList<FileNode *>> &future,
const std::function<FileNode *(const Utils::FilePath &)> factory, const Utils::FilePath &directory,
QFutureInterface<QList<FileNode *>> *future) const std::function<FileNode *(const Utils::FilePath &)> factory)
{ {
QSet<QString> visited; QSet<QString> visited;
if (future) future.setProgressRange(0, 1000000);
future->setProgressRange(0, 1000000); return scanForFilesRecursively(future, 0.0, 1000000.0, directory, factory, visited,
return scanForFilesRecursively(directory, factory, visited, future, 0.0, 1000000.0,
Core::VcsManager::versionControls()); Core::VcsManager::versionControls());
} }

View File

@@ -201,9 +201,9 @@ public:
const FileNode *asFileNode() const final { return this; } const FileNode *asFileNode() const final { return this; }
static QList<FileNode *> static QList<FileNode *>
scanForFiles(const Utils::FilePath &directory, scanForFiles(QFutureInterface<QList<FileNode *>> &future,
const std::function<FileNode *(const Utils::FilePath &fileName)> factory, const Utils::FilePath &directory,
QFutureInterface<QList<FileNode *>> *future = nullptr); const std::function<FileNode *(const Utils::FilePath &fileName)> factory);
bool supportsAction(ProjectAction action, const Node *node) const override; bool supportsAction(ProjectAction action, const Node *node) const override;
QString displayName() const override; QString displayName() const override;

View File

@@ -64,12 +64,11 @@ bool TreeScanner::asyncScanForFiles(const Utils::FilePath &directory)
if (!m_futureWatcher.isFinished()) if (!m_futureWatcher.isFinished())
return false; return false;
auto fi = new FutureInterface(); m_scanFuture = Utils::runAsync([this, directory](FutureInterface &fi) {
m_scanFuture = fi->future(); TreeScanner::scanForFiles(fi, directory, m_filter, m_factory);
});
m_futureWatcher.setFuture(m_scanFuture); m_futureWatcher.setFuture(m_scanFuture);
Utils::runAsync([this, fi, directory]() { TreeScanner::scanForFiles(fi, directory, m_filter, m_factory); });
return true; return true;
} }
@@ -145,14 +144,10 @@ FileType TreeScanner::genericFileType(const Utils::MimeType &mimeType, const Uti
return Node::fileTypeForMimeType(mimeType); return Node::fileTypeForMimeType(mimeType);
} }
void TreeScanner::scanForFiles(FutureInterface *fi, const Utils::FilePath& directory, void TreeScanner::scanForFiles(FutureInterface &fi, const Utils::FilePath& directory,
const FileFilter &filter, const FileTypeFactory &factory) const FileFilter &filter, const FileTypeFactory &factory)
{ {
std::unique_ptr<FutureInterface> fip(fi); Result nodes = FileNode::scanForFiles(fi, directory,
fip->reportStarted();
Result nodes = FileNode::scanForFiles(
directory,
[&filter, &factory](const Utils::FilePath &fn) -> FileNode * { [&filter, &factory](const Utils::FilePath &fn) -> FileNode * {
const Utils::MimeType mimeType = Utils::mimeTypeForFile(fn.toString()); const Utils::MimeType mimeType = Utils::mimeTypeForFile(fn.toString());
@@ -166,13 +161,12 @@ void TreeScanner::scanForFiles(FutureInterface *fi, const Utils::FilePath& direc
type = factory(mimeType, fn); type = factory(mimeType, fn);
return new FileNode(fn, type); return new FileNode(fn, type);
}, fip.get()); });
Utils::sort(nodes, ProjectExplorer::Node::sortByPath); Utils::sort(nodes, ProjectExplorer::Node::sortByPath);
fip->setProgressValue(fip->progressMaximum()); fi.setProgressValue(fi.progressMaximum());
fip->reportResult(nodes); fi.reportResult(nodes);
fip->reportFinished();
} }
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -87,7 +87,7 @@ signals:
void finished(); void finished();
private: private:
static void scanForFiles(FutureInterface *fi, const Utils::FilePath &directory, static void scanForFiles(FutureInterface &fi, const Utils::FilePath &directory,
const FileFilter &filter, const FileTypeFactory &factory); const FileFilter &filter, const FileTypeFactory &factory);
private: private:

View File

@@ -72,6 +72,7 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include <QFuture>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QTimer> #include <QTimer>

View File

@@ -36,7 +36,6 @@
#include <QStringList> #include <QStringList>
#include <QFutureInterface> #include <QFutureInterface>
#include <QFuture>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QMakeGlobals; class QMakeGlobals;

View File

@@ -43,16 +43,16 @@ AnnotationCommentTab::AnnotationCommentTab(QWidget *parent)
ui->titleEdit->setModel(new QStringListModel{QStringList{"Description", ui->titleEdit->setModel(new QStringListModel{QStringList{"Description",
"Display Condition", "Display Condition",
"helper_lines" "helper lines",
"highlight" "highlight",
"project author", "project author",
"project confirmed", "project confirmed",
"project developer", "project developer",
"project distributor", "project distributor",
"project modified", "project modified",
"project type" "project type",
"project version", "project version",
"Screen Description" "Screen Description",
"Section"}}); "Section"}});
connect(ui->titleEdit, &QComboBox::currentTextChanged, connect(ui->titleEdit, &QComboBox::currentTextChanged,

View File

@@ -29,6 +29,10 @@
#include "annotation.h" #include "annotation.h"
#include "qmlmodelnodeproxy.h" #include "qmlmodelnodeproxy.h"
#include <qmldesignerconstants.h>
#include <qmldesignerplugin.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <QObject> #include <QObject>
@@ -175,6 +179,7 @@ void AnnotationEditor::removeFullAnnotation()
void AnnotationEditor::acceptedClicked() void AnnotationEditor::acceptedClicked()
{ {
if (m_dialog) { if (m_dialog) {
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_ANNOTATION_ADDED);
QString customId = m_dialog->customId(); QString customId = m_dialog->customId();
Annotation annotation = m_dialog->annotation(); Annotation annotation = m_dialog->annotation();

View File

@@ -343,7 +343,7 @@ public:
parentNode = selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode(); parentNode = selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode();
if (!ModelNode::isThisOrAncestorLocked(parentNode)) { if (!ModelNode::isThisOrAncestorLocked(parentNode)) {
ActionTemplate *selectionAction = new ActionTemplate(QString(), &ModelNodeOperations::select); ActionTemplate *selectionAction = new ActionTemplate("SELECTION", {}, &ModelNodeOperations::select);
selectionAction->setParent(menu()); selectionAction->setParent(menu());
selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select parent: %1")).arg( selectionAction->setText(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select parent: %1")).arg(
captionForModelNode(parentNode))); captionForModelNode(parentNode)));
@@ -363,7 +363,7 @@ public:
&& !ModelNode::isThisOrAncestorLocked(node)) { && !ModelNode::isThisOrAncestorLocked(node)) {
selectionContext().setTargetNode(node); selectionContext().setTargetNode(node);
QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node)); QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select: %1")).arg(captionForModelNode(node));
ActionTemplate *selectionAction = new ActionTemplate(what, &ModelNodeOperations::select); ActionTemplate *selectionAction = new ActionTemplate("SELECT", what, &ModelNodeOperations::select);
SelectionContext nodeSelectionContext = selectionContext(); SelectionContext nodeSelectionContext = selectionContext();
nodeSelectionContext.setTargetNode(node); nodeSelectionContext.setTargetNode(node);
@@ -546,7 +546,7 @@ public:
for (const QmlFlowItemNode &node : QmlFlowViewNode(selectionContext().rootNode()).flowItems()) { for (const QmlFlowItemNode &node : QmlFlowViewNode(selectionContext().rootNode()).flowItems()) {
if (node != selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode()) { if (node != selectionContext().currentSingleSelectedNode().parentProperty().parentModelNode()) {
QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect: %1")).arg(captionForModelNode(node)); QString what = QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect: %1")).arg(captionForModelNode(node));
ActionTemplate *connectionAction = new ActionTemplate(what, &ModelNodeOperations::addTransition); ActionTemplate *connectionAction = new ActionTemplate("CONNECT", what, &ModelNodeOperations::addTransition);
SelectionContext nodeSelectionContext = selectionContext(); SelectionContext nodeSelectionContext = selectionContext();
nodeSelectionContext.setTargetNode(node); nodeSelectionContext.setTargetNode(node);

View File

@@ -29,6 +29,7 @@
#include "abstractaction.h" #include "abstractaction.h"
#include "abstractactiongroup.h" #include "abstractactiongroup.h"
#include "qmlitemnode.h" #include "qmlitemnode.h"
#include <qmldesignerplugin.h>
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
@@ -103,17 +104,19 @@ class ActionTemplate : public DefaultAction
{ {
public: public:
ActionTemplate(const QString &description, SelectionContextOperation action) ActionTemplate(const QByteArray &id, const QString &description, SelectionContextOperation action)
: DefaultAction(description), m_action(action) : DefaultAction(description), m_action(action), m_id(id)
{ } { }
void actionTriggered(bool b) override void actionTriggered(bool b) override
{ {
QmlDesignerPlugin::emitUsageStatisticsContextAction(QString::fromUtf8(m_id));
m_selectionContext.setToggled(b); m_selectionContext.setToggled(b);
m_action(m_selectionContext); m_action(m_selectionContext);
} }
SelectionContextOperation m_action; SelectionContextOperation m_action;
QByteArray m_id;
}; };
class ActionGroup : public AbstractActionGroup class ActionGroup : public AbstractActionGroup
@@ -202,7 +205,7 @@ public:
SelectionContextOperation selectionAction, SelectionContextOperation selectionAction,
SelectionContextPredicate enabled = &SelectionContextFunctors::always, SelectionContextPredicate enabled = &SelectionContextFunctors::always,
SelectionContextPredicate visibility = &SelectionContextFunctors::always) : SelectionContextPredicate visibility = &SelectionContextFunctors::always) :
AbstractAction(new ActionTemplate(description, selectionAction)), AbstractAction(new ActionTemplate(id, description, selectionAction)),
m_id(id), m_id(id),
m_category(category), m_category(category),
m_priority(priority), m_priority(priority),

View File

@@ -491,7 +491,7 @@ void DesignDocument::paste()
if (rootNode.type() == "empty") if (rootNode.type() == "empty")
return; return;
if (rootNode.id() == "designer__Selection") { // pasting multiple objects if (rootNode.id() == "__multi__selection__") { // pasting multiple objects
currentModel()->attachView(&view); currentModel()->attachView(&view);
ModelNode targetNode; ModelNode targetNode;
@@ -545,7 +545,7 @@ void DesignDocument::paste()
}); });
} else { // pasting single object } else { // pasting single object
rewriterView()->executeInTransaction("DesignDocument::paste1", [this, &view, selectedNodes, rootNode]() { rewriterView()->executeInTransaction("DesignDocument::paste1", [this, &view, rootNode]() {
currentModel()->attachView(&view); currentModel()->attachView(&view);
ModelNode pastedNode(view.insertModel(rootNode)); ModelNode pastedNode(view.insertModel(rootNode));
ModelNode targetNode; ModelNode targetNode;

View File

@@ -141,23 +141,23 @@ void DesignDocumentView::fromText(const QString &text)
inputModel->setFileUrl(model()->fileUrl()); inputModel->setFileUrl(model()->fileUrl());
QPlainTextEdit textEdit; QPlainTextEdit textEdit;
QString imports; QString imports;
foreach (const Import &import, model()->imports()) const auto modelImports = model()->imports();
imports += QStringLiteral("import ") + import.toString(true) + QLatin1Char(';') + QLatin1Char('\n'); for (const Import &import : modelImports)
imports += "import " + import.toString(true) + QLatin1Char(';') + QLatin1Char('\n');
textEdit.setPlainText(imports + text); textEdit.setPlainText(imports + text);
NotIndentingTextEditModifier modifier(&textEdit); NotIndentingTextEditModifier modifier(&textEdit);
QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, nullptr)); RewriterView rewriterView;
rewriterView->setCheckSemanticErrors(false); rewriterView.setCheckSemanticErrors(false);
rewriterView->setTextModifier(&modifier); rewriterView.setTextModifier(&modifier);
inputModel->setRewriterView(rewriterView.data()); inputModel->setRewriterView(&rewriterView);
rewriterView->restoreAuxiliaryData(); rewriterView.restoreAuxiliaryData();
if (rewriterView->errors().isEmpty() && rewriterView->rootModelNode().isValid()) { if (rewriterView.errors().isEmpty() && rewriterView.rootModelNode().isValid()) {
ModelMerger merger(this);
try { try {
merger.replaceModel(rewriterView->rootModelNode()); replaceModel(rewriterView.rootModelNode());
} catch(Exception &/*e*/) { } catch(Exception &/*e*/) {
/* e.showException(); Do not show any error if the clipboard contains invalid QML */ /* e.showException(); Do not show any error if the clipboard contains invalid QML */
} }
@@ -237,13 +237,13 @@ void DesignDocumentView::copyModelNodes(const QList<ModelNode> &nodesToCopy)
Q_ASSERT(view.rootModelNode().type() != "empty"); Q_ASSERT(view.rootModelNode().type() != "empty");
view.toClipboard(); view.toClipboard();
} else { //multi items selected } else { // multi items selected
foreach (ModelNode node, view.rootModelNode().directSubModelNodes()) { foreach (ModelNode node, view.rootModelNode().directSubModelNodes()) {
node.destroy(); node.destroy();
} }
view.changeRootNodeType("QtQuick.Rectangle", 2, 0); view.changeRootNodeType("QtQuick.Rectangle", 2, 0);
view.rootModelNode().setIdWithRefactoring("designer__Selection"); view.rootModelNode().setIdWithRefactoring("__multi__selection__");
foreach (const ModelNode &selectedNode, selectedNodes) { foreach (const ModelNode &selectedNode, selectedNodes) {
ModelNode newNode(view.insertModel(selectedNode)); ModelNode newNode(view.insertModel(selectedNode));

View File

@@ -572,6 +572,7 @@ void ItemLibraryWidget::addResources()
for (const AddResourceHandler &handler : handlers) { for (const AddResourceHandler &handler : handlers) {
QStringList fileNames = partitionedFileNames.values(category); QStringList fileNames = partitionedFileNames.values(category);
if (handler.category == category) { if (handler.category == category) {
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_RESOURCE_IMPORTED + category);
if (!handler.operation(fileNames, document->fileName().parentDir().toString())) if (!handler.operation(fileNames, document->fileName().parentDir().toString()))
Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), tr("Could not add %1 to project.").arg(fileNames.join(" "))); Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), tr("Could not add %1 to project.").arg(fileNames.join(" ")));
break; break;

View File

@@ -793,6 +793,11 @@ void NavigatorTreeModel::handleItemLibraryImageDrop(const QMimeData *mimeData, i
} }
} }
TypeName propertyType(const NodeAbstractProperty &property)
{
return property.parentModelNode().metaInfo().propertyTypeName(property.name());
}
void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProperty, void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProperty,
const QList<ModelNode> &modelNodes, const QList<ModelNode> &modelNodes,
int targetIndex, int targetIndex,
@@ -801,7 +806,7 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper
QTC_ASSERT(m_view, return); QTC_ASSERT(m_view, return);
auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex](){ auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex](){
const TypeName propertyQmlType = parentProperty.parentModelNode().metaInfo().propertyTypeName(parentProperty.name()); const TypeName propertyQmlType = propertyType(parentProperty);
int idx = targetIndex; int idx = targetIndex;
for (const ModelNode &modelNode : modelNodes) { for (const ModelNode &modelNode : modelNodes) {
if (modelNode.isValid() if (modelNode.isValid()

View File

@@ -40,6 +40,8 @@
#include <variantproperty.h> #include <variantproperty.h>
#include <nodelistproperty.h> #include <nodelistproperty.h>
#include <qmldesignerconstants.h>
#include <qmldesignerplugin.h>
#include <qmlitemnode.h> #include <qmlitemnode.h>
#include <qmlstate.h> #include <qmlstate.h>
#include <annotationeditor/annotationeditor.h> #include <annotationeditor/annotationeditor.h>
@@ -182,6 +184,8 @@ void StatesEditorView::addState()
if (!QmlVisualNode::isValidQmlVisualNode(rootModelNode())) if (!QmlVisualNode::isValidQmlVisualNode(rootModelNode()))
return; return;
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_STATE_ADDED);
QStringList modelStateNames = rootStateGroup().names(); QStringList modelStateNames = rootStateGroup().names();
QString newStateName; QString newStateName;
@@ -192,17 +196,12 @@ void StatesEditorView::addState()
break; break;
} }
try { executeInTransaction("addState", [this, newStateName]() {
rootModelNode().validId(); rootModelNode().validId();
if ((rootStateGroup().allStates().count() < 1) && //QtQuick import might be missing
(!model()->hasImport(Import::createLibraryImport("QtQuick", "1.0"), true, true))) {
model()->changeImports({Import::createLibraryImport("QtQuick", "1.0")}, {});
}
ModelNode newState = rootStateGroup().addState(newStateName); ModelNode newState = rootStateGroup().addState(newStateName);
setCurrentState(newState); setCurrentState(newState);
} catch (const RewritingException &e) { });
e.showException();
}
} }
void StatesEditorView::resetModel() void StatesEditorView::resetModel()
@@ -236,9 +235,12 @@ void StatesEditorView::duplicateCurrentState()
QStringList stateNames = rootStateGroup().names(); QStringList stateNames = rootStateGroup().names();
while (stateNames.contains(newName + QString::number(i))) while (stateNames.contains(newName + QString::number(i)))
i++; i++;
const QString newStateName = newName + QString::number(i);
QmlModelState newState = state.duplicate(newName + QString::number(i)); executeInTransaction("addState", [this, newStateName, state]() {
QmlModelState newState = state.duplicate(newStateName);
setCurrentState(newState); setCurrentState(newState);
});
} }
void StatesEditorView::checkForStatesAvailability() void StatesEditorView::checkForStatesAvailability()

View File

@@ -44,6 +44,7 @@
#include <rewritertransaction.h> #include <rewritertransaction.h>
#include <variantproperty.h> #include <variantproperty.h>
#include <viewmanager.h> #include <viewmanager.h>
#include <qmldesignerconstants.h>
#include <qmldesignericons.h> #include <qmldesignericons.h>
#include <qmldesignerplugin.h> #include <qmldesignerplugin.h>
#include <qmlitemnode.h> #include <qmlitemnode.h>
@@ -304,6 +305,8 @@ const QmlTimeline TimelineView::addNewTimeline()
QTC_ASSERT(isAttached(), return QmlTimeline()); QTC_ASSERT(isAttached(), return QmlTimeline());
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_TIMELINE_ADDED);
try { try {
ensureQtQuickTimelineImport(); ensureQtQuickTimelineImport();
} catch (const Exception &e) { } catch (const Exception &e) {

View File

@@ -40,6 +40,7 @@
#include <rewritertransaction.h> #include <rewritertransaction.h>
#include <variantproperty.h> #include <variantproperty.h>
#include <viewmanager.h> #include <viewmanager.h>
#include <qmldesignerconstants.h>
#include <qmldesignericons.h> #include <qmldesignericons.h>
#include <qmldesignerplugin.h> #include <qmldesignerplugin.h>
#include <qmlitemnode.h> #include <qmlitemnode.h>
@@ -203,6 +204,8 @@ ModelNode TransitionEditorView::addNewTransition()
states = QmlVisualNode(root).states().allStates(); states = QmlVisualNode(root).states().allStates();
} }
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_TRANSITION_ADDED);
if (states.isEmpty()) { if (states.isEmpty()) {
Core::AsynchronousMessageBox::warning(tr("No States Defined"), Core::AsynchronousMessageBox::warning(tr("No States Defined"),
tr("There are no states defined in this component.")); tr("There are no states defined in this component."));

View File

@@ -44,6 +44,7 @@ ImageCache::ImageCache(ImageCacheStorageInterface &storage,
while (isRunning()) { while (isRunning()) {
if (auto [hasEntry, entry] = getEntry(); hasEntry) { if (auto [hasEntry, entry] = getEntry(); hasEntry) {
request(entry.name, request(entry.name,
entry.state,
entry.requestType, entry.requestType,
std::move(entry.captureCallback), std::move(entry.captureCallback),
std::move(entry.abortCallback), std::move(entry.abortCallback),
@@ -60,13 +61,11 @@ ImageCache::ImageCache(ImageCacheStorageInterface &storage,
ImageCache::~ImageCache() ImageCache::~ImageCache()
{ {
clean(); clean();
stopThread(); wait();
m_condition.notify_all();
if (m_backgroundThread.joinable())
m_backgroundThread.join();
} }
void ImageCache::request(Utils::SmallStringView name, void ImageCache::request(Utils::SmallStringView name,
Utils::SmallStringView state,
ImageCache::RequestType requestType, ImageCache::RequestType requestType,
ImageCache::CaptureCallback captureCallback, ImageCache::CaptureCallback captureCallback,
ImageCache::AbortCallback abortCallback, ImageCache::AbortCallback abortCallback,
@@ -74,9 +73,11 @@ void ImageCache::request(Utils::SmallStringView name,
ImageCacheGeneratorInterface &generator, ImageCacheGeneratorInterface &generator,
TimeStampProviderInterface &timeStampProvider) TimeStampProviderInterface &timeStampProvider)
{ {
const auto id = state.empty() ? Utils::PathString{name} : Utils::PathString{name, "+", state};
const auto timeStamp = timeStampProvider.timeStamp(name); const auto timeStamp = timeStampProvider.timeStamp(name);
const auto entry = requestType == RequestType::Image ? storage.fetchImage(name, timeStamp) const auto entry = requestType == RequestType::Image ? storage.fetchImage(id, timeStamp)
: storage.fetchIcon(name, timeStamp); : storage.fetchIcon(id, timeStamp);
if (entry.hasEntry) { if (entry.hasEntry) {
if (entry.image.isNull()) if (entry.image.isNull())
@@ -84,23 +85,45 @@ void ImageCache::request(Utils::SmallStringView name,
else else
captureCallback(entry.image); captureCallback(entry.image);
} else { } else {
generator.generateImage(name, timeStamp, std::move(captureCallback), std::move(abortCallback)); generator.generateImage(name,
state,
timeStamp,
std::move(captureCallback),
std::move(abortCallback));
} }
} }
void ImageCache::wait()
{
stopThread();
m_condition.notify_all();
if (m_backgroundThread.joinable())
m_backgroundThread.join();
}
void ImageCache::requestImage(Utils::PathString name, void ImageCache::requestImage(Utils::PathString name,
ImageCache::CaptureCallback captureCallback, ImageCache::CaptureCallback captureCallback,
AbortCallback abortCallback) AbortCallback abortCallback,
Utils::SmallString state)
{ {
addEntry(std::move(name), std::move(captureCallback), std::move(abortCallback), RequestType::Image); addEntry(std::move(name),
std::move(state),
std::move(captureCallback),
std::move(abortCallback),
RequestType::Image);
m_condition.notify_all(); m_condition.notify_all();
} }
void ImageCache::requestIcon(Utils::PathString name, void ImageCache::requestIcon(Utils::PathString name,
ImageCache::CaptureCallback captureCallback, ImageCache::CaptureCallback captureCallback,
ImageCache::AbortCallback abortCallback) ImageCache::AbortCallback abortCallback,
Utils::SmallString state)
{ {
addEntry(std::move(name), std::move(captureCallback), std::move(abortCallback), RequestType::Icon); addEntry(std::move(name),
std::move(state),
std::move(captureCallback),
std::move(abortCallback),
RequestType::Icon);
m_condition.notify_all(); m_condition.notify_all();
} }
@@ -110,6 +133,13 @@ void ImageCache::clean()
m_generator.clean(); m_generator.clean();
} }
void ImageCache::waitForFinished()
{
wait();
m_generator.waitForFinished();
}
std::tuple<bool, ImageCache::Entry> ImageCache::getEntry() std::tuple<bool, ImageCache::Entry> ImageCache::getEntry()
{ {
std::unique_lock lock{m_mutex}; std::unique_lock lock{m_mutex};
@@ -124,6 +154,7 @@ std::tuple<bool, ImageCache::Entry> ImageCache::getEntry()
} }
void ImageCache::addEntry(Utils::PathString &&name, void ImageCache::addEntry(Utils::PathString &&name,
Utils::SmallString &&state,
ImageCache::CaptureCallback &&captureCallback, ImageCache::CaptureCallback &&captureCallback,
AbortCallback &&abortCallback, AbortCallback &&abortCallback,
RequestType requestType) RequestType requestType)
@@ -131,6 +162,7 @@ void ImageCache::addEntry(Utils::PathString &&name,
std::unique_lock lock{m_mutex}; std::unique_lock lock{m_mutex};
m_entries.emplace_back(std::move(name), m_entries.emplace_back(std::move(name),
std::move(state),
std::move(captureCallback), std::move(captureCallback),
std::move(abortCallback), std::move(abortCallback),
requestType); requestType);
@@ -160,7 +192,7 @@ void ImageCache::stopThread()
bool ImageCache::isRunning() bool ImageCache::isRunning()
{ {
std::unique_lock lock{m_mutex}; std::unique_lock lock{m_mutex};
return !m_finishing; return !m_finishing || m_entries.size();
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -67,6 +67,7 @@ ImageCacheCollector::ImageCacheCollector(ImageCacheConnectionManager &connection
ImageCacheCollector::~ImageCacheCollector() = default; ImageCacheCollector::~ImageCacheCollector() = default;
void ImageCacheCollector::start(Utils::SmallStringView name, void ImageCacheCollector::start(Utils::SmallStringView name,
Utils::SmallStringView state,
CaptureCallback captureCallback, CaptureCallback captureCallback,
AbortCallback abortCallback) AbortCallback abortCallback)
{ {
@@ -91,6 +92,11 @@ void ImageCacheCollector::start(Utils::SmallStringView name,
return; return;
} }
ModelNode stateNode = rewriterView.modelNodeForId(QString{state});
if (stateNode.isValid())
rewriterView.setCurrentStateNode(stateNode);
m_connectionManager.setCallback(std::move(captureCallback)); m_connectionManager.setCallback(std::move(captureCallback));
nodeInstanceView.setTarget(m_target.get()); nodeInstanceView.setTarget(m_target.get());

View File

@@ -53,6 +53,7 @@ public:
~ImageCacheCollector(); ~ImageCacheCollector();
void start(Utils::SmallStringView filePath, void start(Utils::SmallStringView filePath,
Utils::SmallStringView state,
CaptureCallback captureCallback, CaptureCallback captureCallback,
AbortCallback abortCallback) override; AbortCallback abortCallback) override;

View File

@@ -38,6 +38,7 @@ public:
using AbortCallback = std::function<void()>; using AbortCallback = std::function<void()>;
virtual void start(Utils::SmallStringView filePath, virtual void start(Utils::SmallStringView filePath,
Utils::SmallStringView state,
CaptureCallback captureCallback, CaptureCallback captureCallback,
AbortCallback abortCallback) AbortCallback abortCallback)
= 0; = 0;

View File

@@ -44,21 +44,23 @@ ImageCacheGenerator::ImageCacheGenerator(ImageCacheCollectorInterface &collector
ImageCacheGenerator::~ImageCacheGenerator() ImageCacheGenerator::~ImageCacheGenerator()
{ {
clean(); clean();
stopThread(); waitForFinished();
m_condition.notify_all();
if (m_backgroundThread)
m_backgroundThread->wait();
} }
void ImageCacheGenerator::generateImage(Utils::SmallStringView name, void ImageCacheGenerator::generateImage(
Utils::SmallStringView name,
Utils::SmallStringView state,
Sqlite::TimeStamp timeStamp, Sqlite::TimeStamp timeStamp,
ImageCacheGeneratorInterface::CaptureCallback &&captureCallback, ImageCacheGeneratorInterface::CaptureCallback &&captureCallback,
AbortCallback &&abortCallback) AbortCallback &&abortCallback)
{ {
{ {
std::lock_guard lock{m_mutex}; std::lock_guard lock{m_mutex};
m_tasks.emplace_back(name, timeStamp, std::move(captureCallback), std::move(abortCallback)); m_tasks.emplace_back(name,
state,
timeStamp,
std::move(captureCallback),
std::move(abortCallback));
} }
m_condition.notify_all(); m_condition.notify_all();
@@ -72,6 +74,15 @@ void ImageCacheGenerator::clean()
m_tasks.clear(); m_tasks.clear();
} }
void ImageCacheGenerator::waitForFinished()
{
stopThread();
m_condition.notify_all();
if (m_backgroundThread)
m_backgroundThread->wait();
}
void ImageCacheGenerator::startGeneration() void ImageCacheGenerator::startGeneration()
{ {
while (isRunning()) { while (isRunning()) {
@@ -82,7 +93,7 @@ void ImageCacheGenerator::startGeneration()
{ {
std::lock_guard lock{m_mutex}; std::lock_guard lock{m_mutex};
if (m_finishing) { if (m_finishing && m_tasks.empty()) {
m_storage.walCheckpointFull(); m_storage.walCheckpointFull();
return; return;
} }
@@ -94,6 +105,7 @@ void ImageCacheGenerator::startGeneration()
m_collector.start( m_collector.start(
task.filePath, task.filePath,
task.state,
[this, task](QImage &&image) { [this, task](QImage &&image) {
if (image.isNull()) if (image.isNull())
task.abortCallback(); task.abortCallback();
@@ -129,7 +141,7 @@ void ImageCacheGenerator::stopThread()
bool ImageCacheGenerator::isRunning() bool ImageCacheGenerator::isRunning()
{ {
std::unique_lock lock{m_mutex}; std::unique_lock lock{m_mutex};
return !m_finishing; return !m_finishing || m_tasks.size();
} }
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -51,26 +51,32 @@ public:
~ImageCacheGenerator(); ~ImageCacheGenerator();
void generateImage(Utils::SmallStringView filePath, void generateImage(Utils::SmallStringView filePath,
Utils::SmallStringView state,
Sqlite::TimeStamp timeStamp, Sqlite::TimeStamp timeStamp,
CaptureCallback &&captureCallback, CaptureCallback &&captureCallback,
AbortCallback &&abortCallback) override; AbortCallback &&abortCallback) override;
void clean() override; void clean() override;
void waitForFinished() override;
private: private:
struct Task struct Task
{ {
Task() = default; Task() = default;
Task(Utils::SmallStringView filePath, Task(Utils::SmallStringView filePath,
Utils::SmallStringView state,
Sqlite::TimeStamp timeStamp, Sqlite::TimeStamp timeStamp,
CaptureCallback &&captureCallback, CaptureCallback &&captureCallback,
AbortCallback &&abortCallback) AbortCallback &&abortCallback)
: filePath(filePath) : filePath(filePath)
, state(std::move(state))
, captureCallback(std::move(captureCallback)) , captureCallback(std::move(captureCallback))
, abortCallback(std::move(abortCallback)) , abortCallback(std::move(abortCallback))
, timeStamp(timeStamp) , timeStamp(timeStamp)
{} {}
Utils::PathString filePath; Utils::PathString filePath;
Utils::SmallString state;
CaptureCallback captureCallback; CaptureCallback captureCallback;
AbortCallback abortCallback; AbortCallback abortCallback;
Sqlite::TimeStamp timeStamp; Sqlite::TimeStamp timeStamp;

View File

@@ -39,12 +39,14 @@ public:
using AbortCallback = std::function<void()>; using AbortCallback = std::function<void()>;
virtual void generateImage(Utils::SmallStringView name, virtual void generateImage(Utils::SmallStringView name,
Utils::SmallStringView state,
Sqlite::TimeStamp timeStamp, Sqlite::TimeStamp timeStamp,
CaptureCallback &&captureCallback, CaptureCallback &&captureCallback,
AbortCallback &&abortCallback) AbortCallback &&abortCallback)
= 0; = 0;
virtual void clean() = 0; virtual void clean() = 0;
virtual void waitForFinished() = 0;
protected: protected:
~ImageCacheGeneratorInterface() = default; ~ImageCacheGeneratorInterface() = default;

View File

@@ -54,12 +54,15 @@ public:
void requestImage(Utils::PathString name, void requestImage(Utils::PathString name,
CaptureCallback captureCallback, CaptureCallback captureCallback,
AbortCallback abortCallback); AbortCallback abortCallback,
Utils::SmallString state = {});
void requestIcon(Utils::PathString name, void requestIcon(Utils::PathString name,
CaptureCallback captureCallback, CaptureCallback captureCallback,
AbortCallback abortCallback); AbortCallback abortCallback,
Utils::SmallString state = {});
void clean(); void clean();
void waitForFinished();
private: private:
enum class RequestType { Image, Icon }; enum class RequestType { Image, Icon };
@@ -67,16 +70,19 @@ private:
{ {
Entry() = default; Entry() = default;
Entry(Utils::PathString name, Entry(Utils::PathString name,
Utils::SmallString state,
CaptureCallback &&captureCallback, CaptureCallback &&captureCallback,
AbortCallback &&abortCallback, AbortCallback &&abortCallback,
RequestType requestType) RequestType requestType)
: name{std::move(name)} : name{std::move(name)}
, state{std::move(state)}
, captureCallback{std::move(captureCallback)} , captureCallback{std::move(captureCallback)}
, abortCallback{std::move(abortCallback)} , abortCallback{std::move(abortCallback)}
, requestType{requestType} , requestType{requestType}
{} {}
Utils::PathString name; Utils::PathString name;
Utils::SmallString state;
CaptureCallback captureCallback; CaptureCallback captureCallback;
AbortCallback abortCallback; AbortCallback abortCallback;
RequestType requestType = RequestType::Image; RequestType requestType = RequestType::Image;
@@ -84,6 +90,7 @@ private:
std::tuple<bool, Entry> getEntry(); std::tuple<bool, Entry> getEntry();
void addEntry(Utils::PathString &&name, void addEntry(Utils::PathString &&name,
Utils::SmallString &&state,
CaptureCallback &&captureCallback, CaptureCallback &&captureCallback,
AbortCallback &&abortCallback, AbortCallback &&abortCallback,
RequestType requestType); RequestType requestType);
@@ -92,6 +99,7 @@ private:
void stopThread(); void stopThread();
bool isRunning(); bool isRunning();
static void request(Utils::SmallStringView name, static void request(Utils::SmallStringView name,
Utils::SmallStringView state,
ImageCache::RequestType requestType, ImageCache::RequestType requestType,
ImageCache::CaptureCallback captureCallback, ImageCache::CaptureCallback captureCallback,
ImageCache::AbortCallback abortCallback, ImageCache::AbortCallback abortCallback,
@@ -99,6 +107,9 @@ private:
ImageCacheGeneratorInterface &generator, ImageCacheGeneratorInterface &generator,
TimeStampProviderInterface &timeStampProvider); TimeStampProviderInterface &timeStampProvider);
private:
void wait();
private: private:
std::vector<Entry> m_entries; std::vector<Entry> m_entries;
mutable std::mutex m_mutex; mutable std::mutex m_mutex;

View File

@@ -75,7 +75,7 @@ public:
}; };
public: public:
RewriterView(DifferenceHandling differenceHandling, QObject *parent); RewriterView(DifferenceHandling differenceHandling = RewriterView::Amend, QObject *parent = nullptr);
~RewriterView() override; ~RewriterView() override;
void modelAttached(Model *model) override; void modelAttached(Model *model) override;

Some files were not shown because too many files have changed in this diff Show More