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
-u
scripts/build.py
--build-type Release
--src .
--build build
--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")
include(FeatureSummary)
include(QtCreatorIDEBranding)
include(QtCreatorIDEBranding RESULT_VARIABLE IDE_BRANDING_FILE)
include(QtCreatorTranslations)
include(QtCreatorDocumentation)
include(QtCreatorAPI)

View File

@@ -69,7 +69,7 @@ set(Qt5_VERSION ${Qt6_VERSION})
foreach(tool qmake lrelease moc rcc qhelpgenerator)
if (TARGET Qt6::${tool} AND NOT TARGET Qt5::${tool})
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}")
endif()
endforeach()

View File

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

View File

@@ -133,7 +133,7 @@ function(add_qtc_library name)
endif()
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}")
# TODO remove, see above
@@ -339,9 +339,9 @@ function(add_qtc_plugin target_name)
set(_arg_DEPENDENCY_STRING "\"Dependencies\" : [\n")
foreach(i IN LISTS _DEP_PLUGINS)
if (i MATCHES "^${IDE_CASED_ID}::")
if (i MATCHES "^QtCreator::")
set(_v ${IDE_VERSION})
string(REPLACE "${IDE_CASED_ID}::" "" i ${i})
string(REPLACE "QtCreator::" "" i ${i})
else()
get_property(_v TARGET "${i}" PROPERTY _arg_VERSION)
endif()
@@ -353,9 +353,9 @@ function(add_qtc_plugin target_name)
_arg_DEPENDENCY_STRING "${_arg_DEPENDENCY_STRING}"
)
foreach(i IN LISTS ${_arg_RECOMMENDS})
if (i MATCHES "^${IDE_CASED_ID}::")
if (i MATCHES "^QtCreator::")
set(_v ${IDE_VERSION})
string(REPLACE "${IDE_CASED_ID}::" "" i ${i})
string(REPLACE "QtCreator::" "" i ${i})
else()
get_property(_v TARGET "${i}" PROPERTY _arg_VERSION)
endif()
@@ -393,7 +393,7 @@ function(add_qtc_plugin target_name)
endif()
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}")
### Generate EXPORT_SYMBOL
@@ -598,7 +598,10 @@ function(add_qtc_executable name)
if (_prop_OUTPUT_NAME)
set(_BUNDLE_NAME "${_prop_OUTPUT_NAME}")
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()
@@ -647,11 +650,70 @@ function(add_qtc_executable name)
set(COMPONENT_OPTION "COMPONENT" "${_arg_COMPONENT}")
endif()
install(TARGETS ${name}
DESTINATION "${_DESTINATION}"
${COMPONENT_OPTION}
OPTIONAL
)
# 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}
DESTINATION "${_DESTINATION}"
${COMPONENT_OPTION}
OPTIONAL
)
endif()
update_cached_list(__QTC_INSTALLED_EXECUTABLES
"${_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 `Complete switch statement` with templates (QTCREATORBUG-24752)
* 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`
arguments (QTCREATORBUG-13698)
* Fixed handling of multiple inheritance in `Insert Virtual Functions` (QTCREATORBUG-12223)
@@ -81,6 +83,8 @@ Projects
* Renamed `CurrentProject:*` variables to `CurrentDocument:Project:*` (QTCREATORBUG-12724,
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 `Embedding of the UI Class` option for widget applications (QTCREATORBUG-24422)
* Fixed shell used for console applications (QTCREATORBUG-24659)
@@ -107,11 +111,16 @@ Debugging
---------
* Fixed disabling and enabling breakpoints (QTCREATORBUG-24669)
* Fixed setting source mappings with variables (QTCREATORBUG-24816)
### GDB
* Fixed loading of symbol files with `Load Core File` (QTCREATORBUG-24541)
### CDB
* Fixed debugging when `PYTHONPATH` is set (QTCREATORBUG-24859)
Analyzer
--------
@@ -156,8 +165,13 @@ Platforms
* Added missing Android variables to completion in `.pro` and `.pri` files
* Fixed passing command line arguments to application (QTCREATORBUG-23712)
### MCU
* Improved creation of kits (QTCREATORBUG-24354)
Credits for these changes go to:
--------------------------------
Aleksei German
Alessandro Portale
Alexander Mishin
Alexis Jeandet
@@ -166,6 +180,7 @@ André Pönitz
Antonio Di Monaco
Asit Dhal
Assam Boudjelthia
Christiaan Janssen
Christian Kandeler
Christian Stenger
Cristian Adam
@@ -176,14 +191,19 @@ Fabio Falsini
Fawzi Mohamed
Federico Guerinoni
Henning Gruendl
Jaroslaw Kobus
Jeremy Ephron
Jochen Seemann
Johanna Vanhatapio
Kai Köhne
Knud Dollereder
Lars Knoll
Leander Schulten
Leena Miettinen
Lukas Holecek
Lukasz Ornatek
Mahmoud Badri
Marco Bubke
Martin Kampas
Michael Weghorn
Miikka Heikkinen
@@ -194,6 +214,7 @@ Robert Löhning
Tasuku Suzuki
Thiago Macieira
Thomas Hartmann
Tim Jenssen
Tobias Hunger
Vikas Pachdha
Volodymyr Zibarov

View File

@@ -51,7 +51,7 @@
You can use the model component to load static mesh data from
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.
\li \l {Using Materials and Shaders}
@@ -85,9 +85,9 @@
scene and set their properties.
\li \l {Using Scene Camera}
To project a 3D scene to a 2D viewport, it is necessary to view
the scene from a camera. You can select the camera type and set
its properties.
To project a 3D scene to a 2D viewport, such as
\uicontrol {Form Editor}, it is necessary to view the scene from a
camera. You can select the camera type and set its properties.
\li \l {Setting Scene Environment}
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('--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
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:
prefix_paths += [paths.elfutils]
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'
build_date_option = 'OFF' if args.no_build_date else 'ON'
test_option = 'ON' if args.with_tests else 'OFF'
cmake_args = ['cmake',
'-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths),
'-DCMAKE_BUILD_TYPE=' + build_type,
'-DCMAKE_BUILD_TYPE=' + args.build_type,
'-DSHOW_BUILD_DATE=' + build_date_option,
'-DWITH_DOCS=' + with_docs_str,
'-DBUILD_DEVELOPER_DOCS=' + with_docs_str,

View File

@@ -57,7 +57,8 @@ def get_arguments():
action='store_true', default=False)
parser.add_argument('--deploy', help='Installs the "Dependencies" component of the plugin.',
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()
def build(args, paths):
@@ -67,10 +68,9 @@ def build(args, paths):
os.makedirs(paths.result)
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]
build_type = 'Debug' if args.debug else 'Release'
cmake_args = ['cmake',
'-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),
'-G', 'Ninja']

View File

@@ -36,7 +36,8 @@ import re
if __name__ == '__main__':
# 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:
line = sys.stdin.readline()
if not line:

View File

@@ -28,6 +28,10 @@ qtc_copy_to_builddir(copy_share_to_builddir
)
# 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)

View File

@@ -729,13 +729,24 @@ def qdumpHelper__std__string__QNX(d, value, charType, format):
def qdumpHelper__std__string__MSVC(d, value, charType, format):
(proxy, buffer, size, alloc) = value.split("p16spp")
try:
(proxy, buffer, size, alloc) = value.split("p16spp")
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())
d.check(0 <= size and size <= alloc and alloc <= 100 * 1000 * 1000)
if _BUF_SIZE <= alloc:
(proxy, data) = value.split("pp")
if proxy is None:
data = value.extractPointer()
else:
(proxy, data) = value.split("pp")
else:
data = value.address() + d.ptrSize()
if proxy is None:
data = value.address()
else:
data = value.address() + d.ptrSize()
d.putCharArrayHelper(data, size, charType, format)
@@ -1098,8 +1109,18 @@ def qdumpHelper__std__vector__QNX(d, value):
(proxy, start, last, end) = value.split("pppp")
size = (last - start) // innerType.size()
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.check(last <= end)
try:
d.check(0 <= size and size <= 1000 * 1000 * 1000)
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:
d.checkPointer(start)
d.checkPointer(last)

View File

@@ -29,136 +29,20 @@
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)
{
return debug.nospace() << "CreateSceneCommand("
<< "instances: " << command.instances() << ", "
<< "reparentInstances: " << command.reparentInstances() << ", "
<< "ids: " << command.ids() << ", "
<< "valueChanges: " << command.valueChanges() << ", "
<< "bindingChanges: " << command.bindingChanges() << ", "
<< "auxiliaryChanges: " << command.auxiliaryChanges() << ", "
<< "imports: " << command.imports() << ", "
<< "mockupTypes: " << command.mockupTypes() << ", "
<< "fileUrl: " << command.fileUrl() << ", "
<< "edit3dToolStates: " << command.edit3dToolStates() << ", "
<< "language: " << command.language() << ")";
<< "instances: " << command.instances << ", "
<< "reparentInstances: " << command.reparentInstances << ", "
<< "ids: " << command.ids << ", "
<< "valueChanges: " << command.valueChanges << ", "
<< "bindingChanges: " << command.bindingChanges << ", "
<< "auxiliaryChanges: " << command.auxiliaryChanges << ", "
<< "imports: " << command.imports << ", "
<< "mockupTypes: " << command.mockupTypes << ", "
<< "fileUrl: " << command.fileUrl << ", "
<< "edit3dToolStates: " << command.edit3dToolStates << ", "
<< "language: " << command.language << ")";
}
}

View File

@@ -41,53 +41,87 @@ namespace QmlDesigner {
class CreateSceneCommand
{
friend QDataStream &operator>>(QDataStream &in, CreateSceneCommand &command);
public:
CreateSceneCommand() = default;
explicit 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,
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}
{}
friend 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;
out << command.stateInstanceId;
return out;
}
friend QDataStream &operator>>(QDataStream &in, CreateSceneCommand &command)
{
in >> command.instances;
in >> command.reparentInstances;
in >> command.ids;
in >> command.valueChanges;
in >> command.bindingChanges;
in >> command.auxiliaryChanges;
in >> command.imports;
in >> command.mockupTypes;
in >> command.fileUrl;
in >> command.edit3dToolStates;
in >> command.language;
in >> command.stateInstanceId;
return in;
}
public:
CreateSceneCommand();
explicit 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);
QVector<InstanceContainer> instances() const;
QVector<ReparentContainer> reparentInstances() const;
QVector<IdContainer> ids() const;
QVector<PropertyValueContainer> valueChanges() const;
QVector<PropertyBindingContainer> bindingChanges() const;
QVector<PropertyValueContainer> auxiliaryChanges() const;
QVector<AddImportContainer> imports() const;
QVector<MockupTypeContainer> mockupTypes() const;
QUrl fileUrl() const;
QHash<QString, QVariantMap> edit3dToolStates() const;
QString language() const;
private:
QVector<InstanceContainer> m_instanceVector;
QVector<ReparentContainer> m_reparentInstanceVector;
QVector<IdContainer> m_idVector;
QVector<PropertyValueContainer> m_valueChangeVector;
QVector<PropertyBindingContainer> m_bindingChangeVector;
QVector<PropertyValueContainer> m_auxiliaryChangeVector;
QVector<AddImportContainer> m_importVector;
QVector<MockupTypeContainer> m_mockupTypeVector;
QUrl m_fileUrl;
QHash<QString, QVariantMap> m_edit3dToolStates;
QString m_language;
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);
QDataStream &operator>>(QDataStream &in, CreateSceneCommand &command);
QDebug operator<<(QDebug debug, const CreateSceneCommand &command);
QDebug operator <<(QDebug debug, const CreateSceneCommand &command);
}
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::CreateSceneCommand)

View File

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

View File

@@ -318,12 +318,13 @@ void NodeInstanceServer::stopRenderTimer()
void NodeInstanceServer::createScene(const CreateSceneCommand &command)
{
setTranslationLanguage(command.language());
setTranslationLanguage(command.language);
initializeView();
Internal::QmlPrivateGate::stopUnifiedTimer();
setupScene(command);
setupState(command.stateInstanceId);
refreshBindings();
startRenderTimer();
}
@@ -399,15 +400,7 @@ void NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &comma
void NodeInstanceServer::changeState(const ChangeStateCommand &command)
{
if (hasInstanceForId(command.stateInstanceId())) {
if (activeStateInstance().isValid())
activeStateInstance().deactivateState();
ServerNodeInstance instance = instanceForId(command.stateInstanceId());
instance.activateState();
} else {
if (activeStateInstance().isValid())
activeStateInstance().deactivateState();
}
setupState(command.stateInstanceId());
startRenderTimer();
}
@@ -569,38 +562,37 @@ void NodeInstanceServer::setupDefaultDummyData()
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()))
instanceForId(container.instanceId()).setId(container.id());
}
foreach (const PropertyValueContainer &container, command.valueChanges()) {
for (const PropertyValueContainer &container : std::as_const(command.valueChanges)) {
if (container.isDynamic())
setInstancePropertyVariant(container);
}
foreach (const PropertyValueContainer &container, command.valueChanges()) {
for (const PropertyValueContainer &container : std::as_const(command.valueChanges)) {
if (!container.isDynamic())
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())
setInstancePropertyBinding(container);
}
foreach (const PropertyBindingContainer &container, command.bindingChanges()) {
for (const PropertyBindingContainer &container : std::as_const(command.bindingChanges)) {
if (!container.isDynamic())
setInstancePropertyBinding(container);
}
foreach (const PropertyValueContainer &container, command.auxiliaryChanges()) {
for (const PropertyValueContainer &container : std::as_const(command.auxiliaryChanges))
setInstanceAuxiliaryData(container);
}
for (int i = instanceList.size(); --i >= 0; )
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

View File

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

View File

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

View File

@@ -82,12 +82,6 @@ void Qt5NodeInstanceServer::initializeView()
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();
}
@@ -116,11 +110,10 @@ void Qt5NodeInstanceServer::resetAllItems()
void Qt5NodeInstanceServer::setupScene(const CreateSceneCommand &command)
{
setupMockupTypes(command.mockupTypes());
setupFileUrl(command.fileUrl());
setupImports(command.imports());
setupDummyData(command.fileUrl());
setupMockupTypes(command.mockupTypes);
setupFileUrl(command.fileUrl);
setupImports(command.imports);
setupDummyData(command.fileUrl);
setupInstances(command);
quickView()->resize(rootNodeInstance().boundingRect().size().toSize());

View File

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

View File

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

View File

@@ -187,7 +187,6 @@ void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &object
}
ObjectNodeInstance::initialize(objectNodeInstance, flags);
quickItem()->update();
}
QQuickItem *QuickItemNodeInstance::contentItem() const
@@ -429,12 +428,14 @@ QImage QuickItemNodeInstance::renderImage() const
nodeInstanceServer()->quickView()->afterRendering();
}
renderImage.setDevicePixelRatio(devicePixelRatio);
#else
renderImage = nodeInstanceServer()->quickView()->grabWindow();
renderImage = renderImage.copy(renderBoundingRect.toRect());
/* When grabbing an offscren window the device pixel ratio is 1 */
renderImage.setDevicePixelRatio(1);
#endif
renderImage.setDevicePixelRatio(devicePixelRatio);
return renderImage;
}
@@ -463,6 +464,7 @@ QImage QuickItemNodeInstance::renderPreviewImage(const QSize &previewImageSize)
}
#else
image = nodeInstanceServer()->quickView()->grabWindow();
image = image.copy(previewItemBoundingRect.toRect());
#endif
image = image.scaledToWidth(size.width());
@@ -542,7 +544,9 @@ void QuickItemNodeInstance::updateDirtyNodesRecursive(QQuickItem *parentItem) co
}
QmlPrivateGate::disableNativeTextRendering(parentItem);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
DesignerSupport::updateDirtyNode(parentItem);
#endif
}
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
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.
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]
env:
PLUGIN_NAME: %{PluginName}
QT_VERSION: %{JS: Util.qtVersion()}
QT_CREATOR_VERSION: %{JS: Util.qtCreatorVersion()}
QT_CREATOR_SNAPSHOT: NO
PLUGIN_PRO: %{ProFile}
PLUGIN_NAME: %{PluginName}
CMAKE_VERSION: 3.18.3
NINJA_VERSION: 1.10.1
jobs:
build:
@@ -17,82 +18,114 @@ jobs:
matrix:
config:
- {
name: "Windows Latest x64", artifact: "Windows-x64.zip",
name: "Windows Latest MSVC", artifact: "Windows-x64",
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",
os: windows-latest,
environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars32.bat"
name: "Ubuntu Latest GCC", artifact: "Linux-x64",
os: ubuntu-latest,
cc: "gcc", cxx: "g++"
}
- {
name: "Linux Latest x64", artifact: "Linux-x64.zip",
os: ubuntu-latest
}
- {
name: "macOS Latest x64", artifact: "macOS-x64.zip",
os: macos-latest
name: "macOS Latest Clang", artifact: "macOS-x64",
os: macos-latest,
cc: "clang", cxx: "clang++"
}
steps:
- 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}
run: |
if ("${{ runner.os }}" STREQUAL "Linux")
execute_process(
COMMAND sudo apt install libgl1-mesa-dev
COMMAND sudo apt update
)
elseif ("${{ runner.os }}" STREQUAL "Windows")
# get JOM
file(DOWNLOAD "https://download.qt.io/official_releases/jom/jom.zip" ./jom.zip SHOW_PROGRESS)
file(MAKE_DIRECTORY ./jom)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../jom.zip WORKING_DIRECTORY ./jom)
execute_process(
COMMAND sudo apt install libgl1-mesa-dev
RESULT_VARIABLE result
)
if (NOT result EQUAL 0)
message(FATAL_ERROR "Failed to install dependencies")
endif()
endif()
- name: Download Qt
id: qt
shell: cmake -P {0}
run: |
set(qt_version $ENV{QT_VERSION})
set(qt_version "$ENV{QT_VERSION}")
string(REPLACE "." "" qt_version_dotless "${qt_version}")
if ("${{ runner.os }}" STREQUAL "Windows")
set(url_os "windows_x86")
if ("${{ matrix.config.environment_script }}" MATCHES "vcvars64.bat")
set(qt_package_name "qt.qt5.${qt_version_dotless}.win64_msvc2019_64")
set(qt_dir_prefix "${qt_version}/msvc2019_64")
elseif ("${{ matrix.config.environment_script }}" MATCHES "vcvars32.bat")
set(qt_package_name "qt.qt5.${qt_version_dotless}.win32_msvc2019")
set(qt_dir_prefix "${qt_version}/msvc2019")
else()
endif()
set(qt_package_arch_suffix "win64_msvc2019_64")
set(qt_dir_prefix "${qt_version}/msvc2019_64")
set(qt_package_suffix "-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64")
elseif ("${{ runner.os }}" STREQUAL "Linux")
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_package_suffix "-Linux-RHEL_7_6-GCC-Linux-RHEL_7_6-X86_64")
elseif ("${{ runner.os }}" STREQUAL "macOS")
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_package_suffix "-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64")
endif()
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(READ ./Updates.xml updates_xml)
string(REGEX MATCH "<Name>${qt_package_name}.*<Version>([0-9+-.]+)</Version>.*<DownloadableArchives>qtbase([a-zA-Z0-9_-]+).7z"
updates_xml_output "${updates_xml}")
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()
string(REGEX MATCH "<Name>qt.qt5.*<Version>([0-9+-.]+)</Version>" updates_xml_output "${updates_xml}")
set(qt_package_version ${CMAKE_MATCH_1})
file(MAKE_DIRECTORY qt5)
@@ -100,20 +133,27 @@ jobs:
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt5/${qt_dir_prefix}" qt_dir)
message("::set-output name=qt_dir::${qt_dir}")
foreach(package qtbase qtdeclarative qttools qtsvg)
file(DOWNLOAD
"${qt_base_url}/${qt_package_name}/${package_version}${package}${package_suffix}.7z" ./${package}.7z
SHOW_PROGRESS
message("Downloading Qt to ${qt_dir}")
function(downloadAndExtract url archive)
message("Downloading ${url}")
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()
file(READ "qt5/${qt_dir_prefix}/mkspecs/qconfig.pri" qtconfig)
string(REPLACE "Enterprise" "OpenSource" qtconfig "${qtconfig}")
string(REPLACE "licheck.exe" "" qtconfig "${qtconfig}")
string(REPLACE "licheck64" "" qtconfig "${qtconfig}")
string(REPLACE "licheck_mac" "" qtconfig "${qtconfig}")
file(WRITE "qt5/${qt_dir_prefix}/mkspecs/qconfig.pri" "${qtconfig}")
# uic depends on libicu56.so
if ("${{ runner.os }}" STREQUAL "Linux")
downloadAndExtract(
"${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}icu-linux-Rhel7.2-x64.7z"
icu.7z
)
endif()
- name: Download Qt Creator
id: qt_creator
@@ -128,29 +168,21 @@ jobs:
endif()
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")
elseif ("${{ matrix.config.environment_script }}" MATCHES "vcvars32.bat")
set(qtc_platform "windows_x86")
endif()
set(qtc_platform "windows_x64")
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")
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")
endif()
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qtcreator" qtc_dir)
# Save the path for other steps
message("::set-output name=qtc_binary_name::${qtc_binary_name}")
message("::set-output name=qtc_output_directory::${qtc_output_directory}")
message("::set-output name=qtc_dir::${qtc_dir}")
file(MAKE_DIRECTORY qtcreator)
message("Downloading Qt Creator from ${qtc_base_url}/${qtc_platform}")
foreach(package qtcreator qtcreator_dev)
file(DOWNLOAD
"${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)
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
shell: cmake -P {0}
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")
execute_process(
COMMAND "${{ matrix.config.environment_script }}" && set
@@ -183,55 +210,32 @@ jobs:
endforeach()
endif()
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qtcreator" qtcreator_dir)
set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ")
execute_process(
COMMAND ${{ steps.qt.outputs.qt_dir }}/bin/qmake
$ENV{PLUGIN_PRO}
CONFIG+=release
IDE_SOURCE_TREE="${qtcreator_dir}"
IDE_BUILD_TREE="${qtcreator_dir}"
COMMAND python
-u
${{ steps.qt_creator.outputs.qtc_dir }}/scripts/build_plugin.py
--name "$ENV{PLUGIN_NAME}-$ENV{QT_CREATOR_VERSION}-${{ matrix.config.artifact }}"
--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
)
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()
if ("${{ runner.os }}" STREQUAL "Windows")
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
- uses: actions/upload-artifact@v2
id: upload_artifact
with:
path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}
name: ${{ 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 }}.7z
release:
if: contains(github.ref, 'tags/v')
@@ -268,19 +272,15 @@ jobs:
matrix:
config:
- {
name: "Windows Latest x64", artifact: "Windows-x64.zip",
name: "Windows Latest x64", artifact: "Windows-x64.7z",
os: ubuntu-latest
}
- {
name: "Windows Latest x86", artifact: "Windows-x86.zip",
name: "Linux Latest x64", artifact: "Linux-x64.7z",
os: ubuntu-latest
}
- {
name: "Linux Latest x64", artifact: "Linux-x64.zip",
os: ubuntu-latest
}
- {
name: "macOS Latest x64", artifact: "macOS-x64.zip",
name: "macOS Latest x64", artifact: "macOS-x64.7z",
os: macos-latest
}
needs: release
@@ -311,4 +311,4 @@ jobs:
upload_url: ${{ steps.set_upload_url.outputs.upload_url }}
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_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",
"icon": "qtcreatorplugin.png",
"featuresRequired": [ "QtSupport.Wizards.FeatureQt", "QtSupport.Wizards.FeatureDesktop" ],
"enabled": "%{JS: value('Plugins').indexOf('QmakeProjectManager') >= 0}",
"enabled": "%{JS: value('Plugins').indexOf('CMakeProjectManager') >= 0}",
"options":
[
{ "key": "ProjectFile", "value": "%{ProFile}" },
{ "key": "ProjectFile", "value": "%{ProjectDirectory}/CMakeLists.txt" },
{ "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": "LibraryDefine", "value": "%{JS: Cpp.headerGuard(value('PluginName')) + '_LIBRARY'}" },
{ "key": "LibraryExport", "value": "%{JS: Cpp.headerGuard(value('PluginName')) + '_EXPORT'}" },
@@ -115,17 +114,6 @@
"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",
"persistenceKey": "QtCreatorBuild",
@@ -136,27 +124,6 @@
{
"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":
[
{
"source": "myplugin.pro",
"target": "%{ProFile}",
"source": "CMakeLists.txt",
"openAsProject": true
},
{
"source": "github_workflows_build_qmake.yml",
"target": ".github/workflows/build_qmake.yml"
"source": "README.md",
"openInEditor": true
},
{
"source": "github_workflows_build_cmake.yml",
"target": ".github/workflows/build_cmake.yml"
},
{
"source": "github_workflows_README.md",
@@ -199,8 +169,7 @@
},
{
"source": "myplugin.cpp",
"target": "%{SrcFileName}",
"openInEditor": true
"target": "%{SrcFileName}"
},
{
"source": "myplugin.h",

View File

@@ -25,6 +25,7 @@ install(
${PROJECT_SOURCE_DIR}/scripts
DESTINATION ./
COMPONENT Devel EXCLUDE_FROM_ALL
USE_SOURCE_PERMISSIONS
)
install(EXPORT QtCreator
@@ -70,7 +71,7 @@ export(EXPORT QtCreator
FILE ${CMAKE_BINARY_DIR}/cmake/QtCreatorTargets.cmake)
file(COPY
${PROJECT_SOURCE_DIR}/cmake/QtCreatorIDEBranding.cmake
${IDE_BRANDING_FILE}
${PROJECT_SOURCE_DIR}/cmake/QtCreatorTranslations.cmake
${PROJECT_SOURCE_DIR}/cmake/QtCreatorDocumentation.cmake
${PROJECT_SOURCE_DIR}/cmake/QtCreatorAPI.cmake
@@ -83,7 +84,7 @@ file(COPY
# Devel package install
install(
FILES
${PROJECT_SOURCE_DIR}/cmake/QtCreatorIDEBranding.cmake
${IDE_BRANDING_FILE}
${PROJECT_SOURCE_DIR}/cmake/QtCreatorTranslations.cmake
${PROJECT_SOURCE_DIR}/cmake/QtCreatorDocumentation.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-project.icns"
)
set_source_files_properties(
"${CMAKE_CURRENT_BINARY_DIR}/qtcreator.icns"
"${CMAKE_CURRENT_BINARY_DIR}/qtcreator-project.icns"
PROPERTIES
MACOSX_PACKAGE_LOCATION "Resources"
qtc_copy_to_builddir(copy_icns
DESTINATION ${IDE_DATA_PATH}
FILES
${CMAKE_CURRENT_BINARY_DIR}/qtcreator.icns
${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()

View File

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

View File

@@ -19,8 +19,7 @@ namespace detail {
struct iterator_value;
template <typename V>
class iterator_base : public std::iterator<std::forward_iterator_tag, V,
std::ptrdiff_t, V*, V> {
class iterator_base {
private:
template <typename>
@@ -37,7 +36,11 @@ class iterator_base : public std::iterator<std::forward_iterator_tag, V,
};
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:
iterator_base() : m_iterator(), m_pMemory() {}

View File

@@ -52,10 +52,7 @@ struct node_iterator_type<const V> {
};
template <typename V>
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>> {
class node_iterator_base {
private:
struct enabler {};
@@ -70,7 +67,11 @@ class node_iterator_base
public:
typedef typename node_iterator_type<V>::seq SeqIter;
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()
: m_type(iterator_type::NoneType), m_seqIt(), m_mapIt(), m_mapEnd() {}

View File

@@ -26,6 +26,7 @@
#include "easingcontextpane.h"
#include "ui_easingcontextpane.h"
#include <qmljs/qmljspropertyreader.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <QGraphicsPixmapItem>
@@ -287,8 +288,10 @@ void QmlEditorWidgets::EasingContextPane::on_durationSpinBox_valueChanged(int ne
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"))
setLinear();
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) {
m_easingGraph->setEasingExtremes(newExtremes);
m_easingGraph->setAmplitude(ui->amplitudeSpinBox->value());

View File

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

View File

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

View File

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

View File

@@ -86,7 +86,7 @@ ValueView convertSqliteValue(sqlite3_value *value)
return ValueView::create(sqlite3_value_double(value));
case SQLITE_TEXT:
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))});
case SQLITE_NULL:
return ValueView::create(NullValue{});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
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
INCLUDES "${CLANG_INCLUDE_DIRS}"
PLUGIN_DEPENDS Core TextEditor CppEditor CppTools ProjectExplorer

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -78,9 +78,9 @@ class CPPTOOLS_EXPORT CppIndexingSupport
public:
virtual ~CppIndexingSupport() = 0;
virtual QFuture<void> refreshSourceFiles(const QFutureInterface<void> &superFuture,
const QSet<QString> &sourceFiles,
CppModelManager::ProgressNotificationMode mode) = 0;
virtual QFuture<void> refreshSourceFiles(const QSet<QString> &sourceFiles,
CppModelManager::ProgressNotificationMode mode)
= 0;
virtual SymbolSearcher *createSymbolSearcher(const SymbolSearcher::Parameters &parameters,
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,
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)
return QFuture<void>();
@@ -944,8 +936,8 @@ QFuture<void> CppModelManager::updateSourceFiles(const QFutureInterface<void> &s
const QSet<QString> filteredFiles = tooBigFilesRemoved(sourceFiles, indexerFileSizeLimitInMb());
if (d->m_indexingSupporter)
d->m_indexingSupporter->refreshSourceFiles(superFuture, filteredFiles, mode);
return d->m_internalIndexingSupport->refreshSourceFiles(superFuture, filteredFiles, mode);
d->m_indexingSupporter->refreshSourceFiles(filteredFiles, mode);
return d->m_internalIndexingSupport->refreshSourceFiles(filteredFiles, mode);
}
QList<ProjectInfo> CppModelManager::projectInfos() const
@@ -1078,25 +1070,23 @@ void CppModelManager::recalculateProjectPartMappings()
d->m_symbolFinder.clearCache();
}
void CppModelManager::watchForCanceledProjectIndexer(const QVector<QFuture<void>> &futures,
void CppModelManager::watchForCanceledProjectIndexer(const QFuture<void> &future,
ProjectExplorer::Project *project)
{
for (const QFuture<void> &future : futures) {
if (future.isCanceled() || future.isFinished())
continue;
if (future.isCanceled() || future.isFinished())
return;
auto watcher = new QFutureWatcher<void>(this);
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, project, watcher]() {
if (d->m_projectToIndexerCanceled.contains(project)) // Project not yet removed
d->m_projectToIndexerCanceled.insert(project, true);
watcher->deleteLater();
});
connect(watcher, &QFutureWatcher<void>::finished, this, [this, project, watcher]() {
d->m_projectToIndexerCanceled.remove(project);
watcher->deleteLater();
});
watcher->setFuture(future);
}
auto watcher = new QFutureWatcher<void>(this);
connect(watcher, &QFutureWatcher<void>::canceled, this, [this, project, watcher]() {
if (d->m_projectToIndexerCanceled.contains(project)) // Project not yet removed
d->m_projectToIndexerCanceled.insert(project, true);
watcher->deleteLater();
});
connect(watcher, &QFutureWatcher<void>::finished, this, [this, project, watcher]() {
d->m_projectToIndexerCanceled.remove(project);
watcher->deleteLater();
});
watcher->setFuture(future);
}
void CppModelManager::updateCppEditorDocuments(bool projectsUpdated) const
@@ -1128,8 +1118,7 @@ void CppModelManager::updateCppEditorDocuments(bool projectsUpdated) const
}
}
QFuture<void> CppModelManager::updateProjectInfo(QFutureInterface<void> &futureInterface,
const ProjectInfo &newProjectInfo)
QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectInfo)
{
if (!newProjectInfo.isValid())
return QFuture<void>();
@@ -1221,12 +1210,12 @@ QFuture<void> CppModelManager::updateProjectInfo(QFutureInterface<void> &futureI
updateCppEditorDocuments(/*projectsUpdated = */ true);
// Trigger reindexing
const QFuture<void> indexingFuture = updateSourceFiles(futureInterface, filesToReindex,
const QFuture<void> indexingFuture = updateSourceFiles(filesToReindex,
ForcedProgressNotification);
if (!filesToReindex.isEmpty()) {
d->m_projectToIndexerCanceled.insert(project, false);
}
watchForCanceledProjectIndexer({futureInterface.future(), indexingFuture}, project);
watchForCanceledProjectIndexer(indexingFuture, project);
return indexingFuture;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -32,6 +32,7 @@
#include <coreplugin/icore.h>
#include <cplusplus/ASTPath.h>
#include <cplusplus/LookupContext.h>
#include <utils/qtcassert.h>
@@ -545,6 +546,16 @@ static InsertionLocation nextToSurroundingDefinitions(Symbol *declaration,
return noResult;
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);

View File

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

View File

@@ -145,7 +145,8 @@ bool SourcePathMappingModel::isNewPlaceHolder(const Mapping &m) const
// Return raw, unfixed mapping
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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -87,7 +87,7 @@ signals:
void finished();
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);
private:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -141,23 +141,23 @@ void DesignDocumentView::fromText(const QString &text)
inputModel->setFileUrl(model()->fileUrl());
QPlainTextEdit textEdit;
QString imports;
foreach (const Import &import, model()->imports())
imports += QStringLiteral("import ") + import.toString(true) + QLatin1Char(';') + QLatin1Char('\n');
const auto modelImports = model()->imports();
for (const Import &import : modelImports)
imports += "import " + import.toString(true) + QLatin1Char(';') + QLatin1Char('\n');
textEdit.setPlainText(imports + text);
NotIndentingTextEditModifier modifier(&textEdit);
QScopedPointer<RewriterView> rewriterView(new RewriterView(RewriterView::Amend, nullptr));
rewriterView->setCheckSemanticErrors(false);
rewriterView->setTextModifier(&modifier);
inputModel->setRewriterView(rewriterView.data());
RewriterView rewriterView;
rewriterView.setCheckSemanticErrors(false);
rewriterView.setTextModifier(&modifier);
inputModel->setRewriterView(&rewriterView);
rewriterView->restoreAuxiliaryData();
rewriterView.restoreAuxiliaryData();
if (rewriterView->errors().isEmpty() && rewriterView->rootModelNode().isValid()) {
ModelMerger merger(this);
if (rewriterView.errors().isEmpty() && rewriterView.rootModelNode().isValid()) {
try {
merger.replaceModel(rewriterView->rootModelNode());
replaceModel(rewriterView.rootModelNode());
} catch(Exception &/*e*/) {
/* 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");
view.toClipboard();
} else { //multi items selected
} else { // multi items selected
foreach (ModelNode node, view.rootModelNode().directSubModelNodes()) {
node.destroy();
}
view.changeRootNodeType("QtQuick.Rectangle", 2, 0);
view.rootModelNode().setIdWithRefactoring("designer__Selection");
view.rootModelNode().setIdWithRefactoring("__multi__selection__");
foreach (const ModelNode &selectedNode, selectedNodes) {
ModelNode newNode(view.insertModel(selectedNode));

View File

@@ -572,6 +572,7 @@ void ItemLibraryWidget::addResources()
for (const AddResourceHandler &handler : handlers) {
QStringList fileNames = partitionedFileNames.values(category);
if (handler.category == category) {
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_RESOURCE_IMPORTED + category);
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(" ")));
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,
const QList<ModelNode> &modelNodes,
int targetIndex,
@@ -801,7 +806,7 @@ void NavigatorTreeModel::moveNodesInteractive(NodeAbstractProperty &parentProper
QTC_ASSERT(m_view, return);
auto doMoveNodesInteractive = [&parentProperty, modelNodes, targetIndex](){
const TypeName propertyQmlType = parentProperty.parentModelNode().metaInfo().propertyTypeName(parentProperty.name());
const TypeName propertyQmlType = propertyType(parentProperty);
int idx = targetIndex;
for (const ModelNode &modelNode : modelNodes) {
if (modelNode.isValid()

View File

@@ -40,6 +40,8 @@
#include <variantproperty.h>
#include <nodelistproperty.h>
#include <qmldesignerconstants.h>
#include <qmldesignerplugin.h>
#include <qmlitemnode.h>
#include <qmlstate.h>
#include <annotationeditor/annotationeditor.h>
@@ -182,6 +184,8 @@ void StatesEditorView::addState()
if (!QmlVisualNode::isValidQmlVisualNode(rootModelNode()))
return;
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_STATE_ADDED);
QStringList modelStateNames = rootStateGroup().names();
QString newStateName;
@@ -192,17 +196,12 @@ void StatesEditorView::addState()
break;
}
try {
executeInTransaction("addState", [this, newStateName]() {
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);
setCurrentState(newState);
} catch (const RewritingException &e) {
e.showException();
}
});
}
void StatesEditorView::resetModel()
@@ -236,9 +235,12 @@ void StatesEditorView::duplicateCurrentState()
QStringList stateNames = rootStateGroup().names();
while (stateNames.contains(newName + QString::number(i)))
i++;
const QString newStateName = newName + QString::number(i);
QmlModelState newState = state.duplicate(newName + QString::number(i));
setCurrentState(newState);
executeInTransaction("addState", [this, newStateName, state]() {
QmlModelState newState = state.duplicate(newStateName);
setCurrentState(newState);
});
}
void StatesEditorView::checkForStatesAvailability()
@@ -303,7 +305,7 @@ void StatesEditorView::renameState(int internalNodeId, const QString &newName)
setCurrentState(oldState);
}
} catch (const RewritingException &e) {
} catch (const RewritingException &e) {
e.showException();
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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