forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/11.0'
Change-Id: I8be5a00000a6699346ed1c44c0711d1f017462a7
This commit is contained in:
@@ -70,4 +70,9 @@ macro.see = "\\sa"
|
||||
macro.function = "\\fn"
|
||||
|
||||
navigation.landingpage = "$IDE_DISPLAY_NAME Manual"
|
||||
|
||||
# Auto-generate navigation linking based on "All Topics":
|
||||
navigation.toctitles = "All Topics"
|
||||
navigation.toctitles.inclusive = false
|
||||
|
||||
buildversion = "$IDE_DISPLAY_NAME Manual $QTC_VERSION"
|
||||
|
||||
@@ -2003,10 +2003,20 @@ bool Check::visit(TypeOfExpression *ast)
|
||||
/// ### Maybe put this into the context as a helper function.
|
||||
const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
|
||||
{
|
||||
|
||||
if (!_importsOk)
|
||||
return nullptr;
|
||||
|
||||
if (!id)
|
||||
return nullptr; // ### error?
|
||||
|
||||
if (id->name.isEmpty()) // possible after error recovery
|
||||
return nullptr;
|
||||
|
||||
QString propertyName = id->name.toString();
|
||||
|
||||
if (propertyName == "id" && !id->next)
|
||||
return nullptr; // ### should probably be a special value
|
||||
|
||||
QList<const ObjectValue *> scopeObjects = _scopeChain.qmlScopeObjects();
|
||||
if (scopeObjects.isEmpty())
|
||||
return nullptr;
|
||||
@@ -2021,24 +2031,9 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
|
||||
return isAttachedProperty;
|
||||
};
|
||||
|
||||
|
||||
if (! id)
|
||||
return nullptr; // ### error?
|
||||
|
||||
if (id->name.isEmpty()) // possible after error recovery
|
||||
return nullptr;
|
||||
|
||||
QString propertyName = id->name.toString();
|
||||
|
||||
if (propertyName == "id" && !id->next)
|
||||
return nullptr; // ### should probably be a special value
|
||||
|
||||
// attached properties
|
||||
bool isAttachedProperty = getAttachedTypes(propertyName);
|
||||
|
||||
if (scopeObjects.isEmpty())
|
||||
return nullptr;
|
||||
|
||||
// global lookup for first part of id
|
||||
const Value *value = nullptr;
|
||||
for (int i = scopeObjects.size() - 1; i >= 0; --i) {
|
||||
@@ -2053,6 +2048,13 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
|
||||
return nullptr;
|
||||
|
||||
if (!value) {
|
||||
// We omit M16 messages if the type using ImmediateProperties
|
||||
// Ideally, we should obtain them through metaobject information
|
||||
const bool omitMessage = !m_typeStack.isEmpty()
|
||||
&& ((m_typeStack.last() == "PropertyChanges")
|
||||
|| m_typeStack.last() == "Binding")
|
||||
&& !m_idStack.isEmpty() && m_idStack.last().contains(propertyName);
|
||||
if (!omitMessage)
|
||||
addMessage(ErrInvalidPropertyName, id->identifierToken, propertyName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
"is not reachable in the running tree. "
|
||||
"It is possible that no barrier was added to the tree, "
|
||||
"or the storage is not reachable from where it is referenced. "
|
||||
"The WaitForBarrier task will finish with error. ");
|
||||
"The WaitForBarrier task finishes with an error. ");
|
||||
return SetupResult::StopWithError;
|
||||
}
|
||||
Barrier *activeSharedBarrier = activeBarrier->barrier();
|
||||
|
||||
@@ -138,6 +138,369 @@ private:
|
||||
Returns the const pointer to the associated \c Task instance.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class Tasking::GroupItem
|
||||
\inheaderfile solutions/tasking/tasktree.h
|
||||
\inmodule TaskingSolution
|
||||
\brief GroupItem represents the basic element that may be a part of any
|
||||
\l {Tasking::Group} {Group}.
|
||||
|
||||
GroupItem is a basic element that may be a part of any \l {Tasking::Group} {Group}.
|
||||
It encapsulates the functionality provided by any GroupItem's subclass.
|
||||
It is a value type and it is safe to copy the GroupItem instance,
|
||||
even when it is originally created via the subclass' constructor.
|
||||
|
||||
There are four main kinds of GroupItem:
|
||||
\table
|
||||
\header
|
||||
\li GroupItem Kind
|
||||
\li Brief Description
|
||||
\row
|
||||
\li \l CustomTask
|
||||
\li Defines asynchronous task type and task's start, done, and error handlers.
|
||||
Aliased with a unique task name, such as, \c ConcurrentCallTask<ResultType>
|
||||
or \l NetworkQueryTask. Asynchronous tasks are the main reason for using a task tree.
|
||||
\row
|
||||
\li \l Group
|
||||
\li A container for other group items. Since the group is of the GroupItem type,
|
||||
it's possible to nest it inside another group. The group is seen by its parent
|
||||
as a single asynchronous task.
|
||||
\row
|
||||
\li \l Storage
|
||||
\li Enables the child tasks of a group to exchange data.
|
||||
When Storage is placed inside a group, the task tree instantiates
|
||||
the storage object just before the group is entered,
|
||||
and destroys it just after the group is finished.
|
||||
\row
|
||||
\li Other group control items
|
||||
\li The items returned by \l {Tasking::parallelLimit()} {parallelLimit()} or
|
||||
\l {Tasking::workflowPolicy()} {workflowPolicy()} influence the group's behavior.
|
||||
The items returned by \l {Tasking::onGroupSetup()} {onGroupSetup()},
|
||||
\l {Tasking::onGroupDone()} {onGroupDone()} or
|
||||
\l {Tasking::onGroupError()} {onGroupError()} define custom handlers called when
|
||||
the group starts or ends execution.
|
||||
\endtable
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class Tasking::Group
|
||||
\inheaderfile solutions/tasking/tasktree.h
|
||||
\inmodule TaskingSolution
|
||||
\brief Group represents the basic element for composing declarative recipes describing
|
||||
how to execute and handle a nested tree of asynchronous tasks.
|
||||
|
||||
Group is a container for other group items. It encloses child tasks into one unit,
|
||||
which is seen by the group's parent as a single, asynchronous task.
|
||||
Since Group is of the GroupItem type, it may also be a child of Group.
|
||||
|
||||
Insert child tasks into the group by using aliased custom task names, such as,
|
||||
\c ConcurrentCallTask<ResultType> or \c NetworkQueryTask:
|
||||
|
||||
\code
|
||||
const Group group {
|
||||
NetworkQueryTask(...),
|
||||
ConcurrentCallTask<int>(...)
|
||||
};
|
||||
\endcode
|
||||
|
||||
The group's behavior may be customized by inserting the items returned by
|
||||
\l {Tasking::parallelLimit()} {parallelLimit()} or
|
||||
\l {Tasking::workflowPolicy()} {workflowPolicy()} functions:
|
||||
|
||||
\code
|
||||
const Group group {
|
||||
parallel,
|
||||
continueOnError,
|
||||
NetworkQueryTask(...),
|
||||
NetworkQueryTask(...)
|
||||
};
|
||||
\endcode
|
||||
|
||||
The group may contain nested groups:
|
||||
|
||||
\code
|
||||
const Group group {
|
||||
finishAllAndDone,
|
||||
NetworkQueryTask(...),
|
||||
Group {
|
||||
NetworkQueryTask(...),
|
||||
Group {
|
||||
parallel,
|
||||
NetworkQueryTask(...),
|
||||
NetworkQueryTask(...),
|
||||
}
|
||||
ConcurrentCallTask<QString>(...)
|
||||
}
|
||||
};
|
||||
\endcode
|
||||
|
||||
The group may dynamically instantiate a custom storage structure, which may be used for
|
||||
inter-task data exchange:
|
||||
|
||||
\code
|
||||
struct MyCustomStruct { QByteArray data; };
|
||||
|
||||
TreeStorage<MyCustomStruct> storage;
|
||||
|
||||
const auto onFirstSetup = [](NetworkQuery &task) { ... };
|
||||
const auto onFirstDone = [storage](const NetworkQuery &task) {
|
||||
// storage-> gives a pointer to MyCustomStruct instance,
|
||||
// created dynamically by the running task tree.
|
||||
storage->data = task.reply()->readAll();
|
||||
};
|
||||
const auto onSecondSetup = [storage](ConcurrentCall<QImage> &task) {
|
||||
// storage-> gives a pointer to MyCustomStruct. Since the group is sequential,
|
||||
// the stored MyCustomStruct was already updated inside the onFirstDone handler.
|
||||
const QByteArray storedData = storage->data;
|
||||
};
|
||||
|
||||
const Group group {
|
||||
// When the group is entered by a running task tree, it creates MyCustomStruct
|
||||
// instance dynamically. It is later accessible from all handlers via
|
||||
// the *storage or storage-> operators.
|
||||
sequential,
|
||||
Storage(storage),
|
||||
NetworkQueryTask(onFirstSetup, onFirstDone),
|
||||
ConcurrentCallTask<QImage>(onSecondSetup)
|
||||
};
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn Group::Group(const QList<GroupItem> &children)
|
||||
|
||||
Constructs a group with a given list of \a children.
|
||||
|
||||
This constructor is useful when the child items of the group are not known at compile time,
|
||||
but later, at runtime:
|
||||
|
||||
\code
|
||||
const QStringList sourceList = ...;
|
||||
|
||||
QList<GroupItem> groupItems { parallel };
|
||||
|
||||
for (const QString &source : sourceList) {
|
||||
const NetworkQueryTask task(...); // use source for setup handler
|
||||
groupItems << task;
|
||||
}
|
||||
|
||||
const Group group(groupItems);
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn Group::Group(std::initializer_list<GroupItem> children)
|
||||
|
||||
Constructs a group from std::initializer_list given by \a children.
|
||||
|
||||
This constructor is useful when all child items of the group are known at compile time:
|
||||
|
||||
\code
|
||||
const Group group {
|
||||
finishAllAndDone,
|
||||
NetworkQueryTask(...),
|
||||
Group {
|
||||
NetworkQueryTask(...),
|
||||
Group {
|
||||
parallel,
|
||||
NetworkQueryTask(...),
|
||||
NetworkQueryTask(...),
|
||||
}
|
||||
ConcurrentCallTask<QString>(...)
|
||||
}
|
||||
};
|
||||
\endcode
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn GroupItem Group::withTimeout(std::chrono::milliseconds timeout, const GroupEndHandler &handler) const
|
||||
|
||||
Attaches \c TimeoutTask to a copy of \c this group, elapsing after \a timeout in milliseconds,
|
||||
with an optionally provided timeout \a handler, and returns the coupled item.
|
||||
|
||||
When the group finishes before \a timeout passes,
|
||||
the returned item finishes immediately with the group's result.
|
||||
Otherwise, the \a handler is invoked (if provided), the group is stopped,
|
||||
and the returned item finishes with an error.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class Tasking::CustomTask
|
||||
\inheaderfile solutions/tasking/tasktree.h
|
||||
\inmodule TaskingSolution
|
||||
\brief A class template used for declaring task items and defining their setup,
|
||||
done, and error handlers.
|
||||
|
||||
The CustomTask class template is used inside TaskTree for describing custom task items.
|
||||
|
||||
Custom task names are aliased with unique names inside the \l Tasking namespace
|
||||
via the TASKING_DECLARE_TASK or TASKING_DECLARE_TEMPLATE_TASK macros.
|
||||
For example, \c ConcurrentCallTask<T> is an alias to the CustomTask that is defined
|
||||
to work with \c ConcurrentCall<T> as an associated task class.
|
||||
The following table contains all the built-in tasks and their associated task classes:
|
||||
|
||||
\table
|
||||
\header
|
||||
\li Aliased Task Name (Tasking Namespace)
|
||||
\li Associated Task Class
|
||||
\li Brief Description
|
||||
\row
|
||||
\li ConcurrentCallTask<ReturnType>
|
||||
\li ConcurrentCall<ReturnType>
|
||||
\li Starts an asynchronous task. Runs in a separate thread.
|
||||
\row
|
||||
\li NetworkQueryTask
|
||||
\li NetworkQuery
|
||||
\li Sends a network query.
|
||||
\row
|
||||
\li TaskTreeTask
|
||||
\li TaskTree
|
||||
\li Starts a nested task tree.
|
||||
\row
|
||||
\li TimeoutTask
|
||||
\li \c std::chrono::milliseconds
|
||||
\li Starts a timer.
|
||||
\row
|
||||
\li WaitForBarrierTask
|
||||
\li MultiBarrier<Limit>
|
||||
\li Starts an asynchronous task waiting for the barrier to pass.
|
||||
\endtable
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typealias CustomTask::Task
|
||||
|
||||
Type alias for \c Adapter::Type.
|
||||
|
||||
This is the associated task's type.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typealias CustomTask::EndHandler
|
||||
|
||||
Type alias for \c std::function<void(const Task &)>.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Adapter> template <typename SetupHandler> CustomTask<Adapter>::CustomTask<Adapter>(SetupHandler &&setup, const EndHandler &done, const EndHandler &error)
|
||||
|
||||
Constructs the CustomTask instance and attaches the \a setup, \a done, and \a error
|
||||
handlers to the task. When the running task tree is about to start the task,
|
||||
it instantiates the associated \l Task object, invokes \a setup handler with a \e reference
|
||||
to the created task, and starts it. When the running task finishes with success or an error,
|
||||
the task tree invokes \a done or \a error handler, respectively,
|
||||
with a \e {const reference} to the created task.
|
||||
|
||||
The passed \a setup handler is either of the \c std::function<SetupResult(Task &)> or
|
||||
\c std::function<void(Task &)> type. For example:
|
||||
|
||||
\code
|
||||
static void parseAndLog(const QString &input);
|
||||
|
||||
...
|
||||
|
||||
const QString input = ...;
|
||||
|
||||
const auto onFirstSetup = [input](ConcurrentCall<void> &task) {
|
||||
if (input == "Skip")
|
||||
return SetupResult::StopWithDone; // This task won't start, the next one will
|
||||
if (input == "Error")
|
||||
return SetupResult::StopWithError; // This task and the next one won't start
|
||||
task.setConcurrentCallData(parseAndLog, input);
|
||||
// This task will start, and the next one will start after this one finished with success
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
|
||||
const auto onSecondSetup = [input](ConcurrentCall<void> &task) {
|
||||
task.setConcurrentCallData(parseAndLog, input);
|
||||
};
|
||||
|
||||
const Group group {
|
||||
ConcurrentCallTask<void>(onFirstSetup),
|
||||
ConcurrentCallTask<void>(onSecondSetup)
|
||||
};
|
||||
\endcode
|
||||
|
||||
When the passed \a setup handler is of the \c std::function<SetupResult(Task &)> type,
|
||||
the return value of the handler instructs the running tree on how to proceed after
|
||||
the handler's invocation is finished. The default return value of SetupResult::Continue
|
||||
instructs the tree to continue running, i.e. to execute the associated \c Task.
|
||||
The return value of SetupResult::StopWithDone or SetupResult::StopWithError instructs
|
||||
the tree to skip the task's execution and finish immediately with success or an error,
|
||||
respectively.
|
||||
When the return type is either SetupResult::StopWithDone or SetupResult::StopWithError,
|
||||
the task's \a done or \a error handler (even if provided) are not called afterwards.
|
||||
|
||||
The \a setup handler may be of a shortened form of std::function<void(Task &)>,
|
||||
i.e. the return value is void. In this case it's assumed that the return value is
|
||||
SetupResult::Continue by default.
|
||||
|
||||
When the running task finishes, one of \a done or \a error handlers is called,
|
||||
depending on whether it finished with success or an error, respectively.
|
||||
Both handlers are of std::function<void(const Task &)> type.
|
||||
|
||||
\sa onSetup(), onDone(), onError()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Adapter> template <typename SetupHandler> CustomTask<Adapter> &CustomTask<Adapter>::onSetup(SetupHandler &&handler)
|
||||
|
||||
Attaches the setup \a handler to \c this task.
|
||||
The \a handler is invoked when the task is about to be started.
|
||||
|
||||
This function enables defining the task's details with a
|
||||
\l {https://en.wikipedia.org/wiki/Fluent_interface}{fluent interface} style:
|
||||
|
||||
\code
|
||||
const auto onQuerySetup = [](NetworkQuery &task) { ... };
|
||||
const auto onQueryError = [](const NetworkQuery &task) { ... };
|
||||
|
||||
const Group group {
|
||||
NetworkQueryTask(onQuerySetup, {}, onQueryError),
|
||||
NetworkQueryTask().onSetup(onQuerySetup).onError(onQueryError), // fluent interface style
|
||||
NetworkQueryTask(onQuerySetup, {}, onQueryError).withTimeout(500ms)
|
||||
}
|
||||
\endcode
|
||||
|
||||
\sa CustomTask(), onDone(), onError()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Adapter> CustomTask<Adapter> &CustomTask<Adapter>::onDone(const EndHandler &handler)
|
||||
|
||||
Attaches the done \a handler to \c this task.
|
||||
The handler is invoked when the task finishes with success.
|
||||
|
||||
This function enables defining the task's details with a fluent interface style.
|
||||
|
||||
\sa CustomTask(), onSetup(), onError()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Adapter> CustomTask<Adapter> &CustomTask<Adapter>::onError(const EndHandler &handler)
|
||||
|
||||
Attaches the error \a handler to \c this task.
|
||||
The handler is invoked when the task finishes with an error.
|
||||
|
||||
This function enables defining the task's details with a fluent interface style.
|
||||
|
||||
\sa CustomTask(), onSetup(), onDone()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <typename Adapter> GroupItem CustomTask<Adapter>::withTimeout(std::chrono::milliseconds timeout, const GroupItem::GroupEndHandler &handler) const
|
||||
|
||||
Attaches \c TimeoutTask to a copy of \c this task, elapsing after \a timeout in milliseconds,
|
||||
with an optionally provided timeout \a handler, and returns the coupled item.
|
||||
|
||||
When the task finishes before \a timeout passes,
|
||||
the returned item finishes immediately with the task's result.
|
||||
Otherwise, the \a handler is invoked (if provided), the task is stopped,
|
||||
and the returned item finishes with an error.
|
||||
|
||||
\sa onSetup()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro TASKING_DECLARE_TASK(CustomTaskName, TaskAdapterClass)
|
||||
\relates Tasking
|
||||
@@ -158,13 +521,6 @@ private:
|
||||
For more information on implementing the custom task adapters, refer to \l {Task Adapters}.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class Tasking::GroupItem
|
||||
\inheaderfile solutions/tasking/tasktree.h
|
||||
\inmodule TaskingSolution
|
||||
\brief The GroupItem class represents the basic element for composing nested tree structures.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum Tasking::WorkflowPolicy
|
||||
|
||||
|
||||
@@ -321,14 +321,14 @@ public:
|
||||
using EndHandler = std::function<void(const Task &)>;
|
||||
static Adapter *createAdapter() { return new Adapter; }
|
||||
CustomTask() : GroupItem({&createAdapter}) {}
|
||||
template <typename SetupFunction>
|
||||
CustomTask(SetupFunction &&function, const EndHandler &done = {}, const EndHandler &error = {})
|
||||
: GroupItem({&createAdapter, wrapSetup(std::forward<SetupFunction>(function)),
|
||||
template <typename SetupHandler>
|
||||
CustomTask(SetupHandler &&setup, const EndHandler &done = {}, const EndHandler &error = {})
|
||||
: GroupItem({&createAdapter, wrapSetup(std::forward<SetupHandler>(setup)),
|
||||
wrapEnd(done), wrapEnd(error)}) {}
|
||||
|
||||
template <typename SetupFunction>
|
||||
CustomTask &onSetup(SetupFunction &&function) {
|
||||
setTaskSetupHandler(wrapSetup(std::forward<SetupFunction>(function)));
|
||||
template <typename SetupHandler>
|
||||
CustomTask &onSetup(SetupHandler &&handler) {
|
||||
setTaskSetupHandler(wrapSetup(std::forward<SetupHandler>(handler)));
|
||||
return *this;
|
||||
}
|
||||
CustomTask &onDone(const EndHandler &handler) {
|
||||
@@ -346,20 +346,20 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename SetupFunction>
|
||||
static GroupItem::TaskSetupHandler wrapSetup(SetupFunction &&function) {
|
||||
template<typename SetupHandler>
|
||||
static GroupItem::TaskSetupHandler wrapSetup(SetupHandler &&handler) {
|
||||
static constexpr bool isDynamic = std::is_same_v<SetupResult,
|
||||
std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
|
||||
std::invoke_result_t<std::decay_t<SetupHandler>, typename Adapter::Type &>>;
|
||||
constexpr bool isVoid = std::is_same_v<void,
|
||||
std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
|
||||
std::invoke_result_t<std::decay_t<SetupHandler>, typename Adapter::Type &>>;
|
||||
static_assert(isDynamic || isVoid,
|
||||
"Task setup handler needs to take (Task &) as an argument and has to return "
|
||||
"void or SetupResult. The passed handler doesn't fulfill these requirements.");
|
||||
return [=](TaskInterface &taskInterface) {
|
||||
Adapter &adapter = static_cast<Adapter &>(taskInterface);
|
||||
if constexpr (isDynamic)
|
||||
return std::invoke(function, *adapter.task());
|
||||
std::invoke(function, *adapter.task());
|
||||
return std::invoke(handler, *adapter.task());
|
||||
std::invoke(handler, *adapter.task());
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -66,22 +66,22 @@ BoostTestSettings::BoostTestSettings(Id settingsId)
|
||||
seed.setEnabler(&randomize);
|
||||
|
||||
randomize.setSettingsKey("Randomize");
|
||||
randomize.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
||||
randomize.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
randomize.setLabelText(Tr::tr("Randomize"));
|
||||
randomize.setToolTip(Tr::tr("Randomize execution order."));
|
||||
|
||||
systemErrors.setSettingsKey("SystemErrors");
|
||||
systemErrors.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
||||
systemErrors.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
systemErrors.setLabelText(Tr::tr("Catch system errors"));
|
||||
systemErrors.setToolTip(Tr::tr("Catch or ignore system errors."));
|
||||
|
||||
fpExceptions.setSettingsKey("FPExceptions");
|
||||
fpExceptions.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
||||
fpExceptions.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
fpExceptions.setLabelText(Tr::tr("Floating point exceptions"));
|
||||
fpExceptions.setToolTip(Tr::tr("Enable floating point exception traps."));
|
||||
|
||||
memLeaks.setSettingsKey("MemoryLeaks");
|
||||
memLeaks.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBox);
|
||||
memLeaks.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
memLeaks.setDefaultValue(true);
|
||||
memLeaks.setLabelText(Tr::tr("Detect memory leaks"));
|
||||
memLeaks.setToolTip(Tr::tr("Enable memory leak detection."));
|
||||
|
||||
@@ -44,6 +44,7 @@ CTestSettings::CTestSettings(Id settingsId)
|
||||
|
||||
outputOnFail.setSettingsKey("OutputOnFail");
|
||||
outputOnFail.setLabelText(Tr::tr("Output on failure"));
|
||||
outputOnFail.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
outputOnFail.setDefaultValue(true);
|
||||
|
||||
outputMode.setSettingsKey("OutputMode");
|
||||
@@ -70,9 +71,11 @@ CTestSettings::CTestSettings(Id settingsId)
|
||||
|
||||
scheduleRandom.setSettingsKey("ScheduleRandom");
|
||||
scheduleRandom.setLabelText(Tr::tr("Schedule random"));
|
||||
scheduleRandom.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
|
||||
stopOnFailure.setSettingsKey("StopOnFail");
|
||||
stopOnFailure.setLabelText(Tr::tr("Stop on failure"));
|
||||
stopOnFailure.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
|
||||
parallel.setSettingsKey("Parallel");
|
||||
parallel.setToolTip(Tr::tr("Run tests in parallel mode using given number of jobs."));
|
||||
|
||||
@@ -26,6 +26,7 @@ GTestSettings::GTestSettings(Id settingsId)
|
||||
setLayouter([this] {
|
||||
return Row { Form {
|
||||
runDisabled, br,
|
||||
throwOnFailure, br,
|
||||
breakOnFailure, br,
|
||||
repeat, iterations, br,
|
||||
shuffle, seed, br,
|
||||
@@ -49,24 +50,29 @@ GTestSettings::GTestSettings(Id settingsId)
|
||||
|
||||
runDisabled.setSettingsKey("RunDisabled");
|
||||
runDisabled.setLabelText(Tr::tr("Run disabled tests"));
|
||||
runDisabled.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
runDisabled.setToolTip(Tr::tr("Executes disabled tests when performing a test run."));
|
||||
|
||||
shuffle.setSettingsKey("Shuffle");
|
||||
shuffle.setLabelText(Tr::tr("Shuffle tests"));
|
||||
shuffle.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
shuffle.setToolTip(Tr::tr("Shuffles tests automatically on every iteration by the given seed."));
|
||||
|
||||
repeat.setSettingsKey("Repeat");
|
||||
repeat.setLabelText(Tr::tr("Repeat tests"));
|
||||
repeat.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
repeat.setToolTip(Tr::tr("Repeats a test run (you might be required to increase the timeout to "
|
||||
"avoid canceling the tests)."));
|
||||
|
||||
throwOnFailure.setSettingsKey("ThrowOnFailure");
|
||||
throwOnFailure.setLabelText(Tr::tr("Throw on failure"));
|
||||
throwOnFailure.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
throwOnFailure.setToolTip(Tr::tr("Turns assertion failures into C++ exceptions."));
|
||||
|
||||
breakOnFailure.setSettingsKey("BreakOnFailure");
|
||||
breakOnFailure.setDefaultValue(true);
|
||||
breakOnFailure.setLabelText(Tr::tr("Break on failure while debugging"));
|
||||
breakOnFailure.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
|
||||
breakOnFailure.setToolTip(Tr::tr("Turns failures into debugger breakpoints."));
|
||||
|
||||
groupMode.setSettingsKey("GroupMode");
|
||||
|
||||
@@ -296,9 +296,8 @@ void TestResultModel::addTestResult(const TestResult &testResult, bool autoExpan
|
||||
if (parentItem) {
|
||||
parentItem->appendChild(newItem);
|
||||
if (autoExpand) {
|
||||
parentItem->expand();
|
||||
newItem->expand();
|
||||
newItem->forAllChildren([](TreeItem *it) { it->expand(); });
|
||||
QMetaObject::invokeMethod(this, [parentItem]{ parentItem->expand(); },
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
updateParent(newItem);
|
||||
} else {
|
||||
|
||||
@@ -142,7 +142,7 @@ TestResultsPane::TestResultsPane(QObject *parent) :
|
||||
onCopyItemTriggered(getTestResult(m_treeView->currentIndex()));
|
||||
});
|
||||
connect(m_model, &TestResultModel::requestExpansion, this, [this](const QModelIndex &idx) {
|
||||
m_treeView->expand(m_filterModel->mapFromSource(idx));
|
||||
m_treeView->expandRecursively(m_filterModel->mapFromSource(idx));
|
||||
});
|
||||
connect(TestRunner::instance(), &TestRunner::testRunStarted,
|
||||
this, &TestResultsPane::onTestRunStarted);
|
||||
|
||||
@@ -152,14 +152,17 @@ CppEditor::CppCodeStyleSettings ClangFormatFile::toCppCodeStyleSettings(
|
||||
// to be false
|
||||
settings.indentAccessSpecifiers = (style.AccessModifierOffset != -1 * int(style.IndentWidth));
|
||||
|
||||
settings.indentNamespaceBody = style.NamespaceIndentation
|
||||
== FormatStyle::NamespaceIndentationKind::NI_All;
|
||||
if (style.NamespaceIndentation == FormatStyle::NamespaceIndentationKind::NI_All) {
|
||||
settings.indentNamespaceBody = true;
|
||||
settings.indentNamespaceBraces = settings.indentNamespaceBody;
|
||||
}
|
||||
|
||||
settings.indentClassBraces = style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths;
|
||||
if (style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) {
|
||||
settings.indentClassBraces = true;
|
||||
settings.indentEnumBraces = settings.indentClassBraces;
|
||||
settings.indentBlockBraces = settings.indentClassBraces;
|
||||
settings.indentFunctionBraces = settings.indentClassBraces;
|
||||
}
|
||||
|
||||
settings.indentSwitchLabels = style.IndentCaseLabels;
|
||||
#if LLVM_VERSION_MAJOR >= 11
|
||||
|
||||
@@ -207,13 +207,13 @@ void fromCppCodeStyleSettings(clang::format::FormatStyle &style,
|
||||
else
|
||||
style.AccessModifierOffset = -1 * style.IndentWidth;
|
||||
|
||||
if (settings.indentNamespaceBody || settings.indentNamespaceBraces)
|
||||
if (settings.indentNamespaceBody && settings.indentNamespaceBraces)
|
||||
style.NamespaceIndentation = FormatStyle::NamespaceIndentationKind::NI_All;
|
||||
else
|
||||
style.NamespaceIndentation = FormatStyle::NamespaceIndentationKind::NI_None;
|
||||
|
||||
if (settings.indentClassBraces || settings.indentEnumBraces || settings.indentBlockBraces
|
||||
|| settings.indentFunctionBraces)
|
||||
if (settings.indentClassBraces && settings.indentEnumBraces && settings.indentBlockBraces
|
||||
&& settings.indentFunctionBraces)
|
||||
style.BreakBeforeBraces = FormatStyle::BS_Whitesmiths;
|
||||
else
|
||||
style.BreakBeforeBraces = FormatStyle::BS_Custom;
|
||||
|
||||
@@ -64,9 +64,8 @@ static QString appendYamlSuffix(const char *filePathFragment)
|
||||
void ReadExportedDiagnosticsTest::testTidy()
|
||||
{
|
||||
const FilePath sourceFile = filePath("tidy.modernize-use-nullptr.cpp");
|
||||
const FilePath exportedFile = createFile(
|
||||
filePath(appendYamlSuffix("tidy.modernize-use-nullptr")).toString(),
|
||||
sourceFile.toString());
|
||||
const FilePath exportedFile
|
||||
= createFile(filePath(appendYamlSuffix("tidy.modernize-use-nullptr")), sourceFile);
|
||||
Diagnostic expectedDiag;
|
||||
expectedDiag.name = "modernize-use-nullptr";
|
||||
expectedDiag.location = {sourceFile, 2, 25};
|
||||
@@ -86,8 +85,8 @@ void ReadExportedDiagnosticsTest::testTidy()
|
||||
|
||||
void ReadExportedDiagnosticsTest::testAcceptDiagsFromFilePaths_None()
|
||||
{
|
||||
const QString sourceFile = filePath("tidy.modernize-use-nullptr.cpp").toString();
|
||||
const FilePath exportedFile = createFile(filePath("tidy.modernize-use-nullptr.yaml").toString(),
|
||||
const FilePath sourceFile = filePath("tidy.modernize-use-nullptr.cpp");
|
||||
const FilePath exportedFile = createFile(filePath("tidy.modernize-use-nullptr.yaml"),
|
||||
sourceFile);
|
||||
const auto acceptNone = [](const FilePath &) { return false; };
|
||||
const expected_str<Diagnostics> diags
|
||||
@@ -101,8 +100,7 @@ void ReadExportedDiagnosticsTest::testTidy_ClangAnalyzer()
|
||||
{
|
||||
const FilePath sourceFile = filePath("clang-analyzer.dividezero.cpp");
|
||||
const FilePath exportedFile
|
||||
= createFile(filePath(appendYamlSuffix("clang-analyzer.dividezero")).toString(),
|
||||
sourceFile.toString());
|
||||
= createFile(filePath(appendYamlSuffix("clang-analyzer.dividezero")), sourceFile);
|
||||
Diagnostic expectedDiag;
|
||||
expectedDiag.name = "clang-analyzer-core.DivideZero";
|
||||
expectedDiag.location = {sourceFile, 4, 15};
|
||||
@@ -134,8 +132,8 @@ void ReadExportedDiagnosticsTest::testTidy_ClangAnalyzer()
|
||||
void ReadExportedDiagnosticsTest::testClazy()
|
||||
{
|
||||
const FilePath sourceFile = filePath("clazy.qgetenv.cpp");
|
||||
const FilePath exportedFile = createFile(filePath(appendYamlSuffix("clazy.qgetenv")).toString(),
|
||||
sourceFile.toString());
|
||||
const FilePath exportedFile = createFile(filePath(appendYamlSuffix("clazy.qgetenv")),
|
||||
sourceFile);
|
||||
Diagnostic expectedDiag;
|
||||
expectedDiag.name = "clazy-qgetenv";
|
||||
expectedDiag.location = {sourceFile, 7, 5};
|
||||
@@ -259,17 +257,16 @@ void ReadExportedDiagnosticsTest::testOffsetMultiByteCodePoint2()
|
||||
}
|
||||
|
||||
// Replace FILE_PATH with a real absolute file path in the *.yaml files.
|
||||
FilePath ReadExportedDiagnosticsTest::createFile(const QString &yamlFilePath,
|
||||
const QString &filePathToInject) const
|
||||
FilePath ReadExportedDiagnosticsTest::createFile(const Utils::FilePath &yamlFilePath,
|
||||
const Utils::FilePath &filePathToInject) const
|
||||
{
|
||||
QTC_ASSERT(QDir::isAbsolutePath(filePathToInject), return {});
|
||||
const FilePath newFileName = m_baseDir->absolutePath(QFileInfo(yamlFilePath).fileName());
|
||||
QTC_ASSERT(filePathToInject.isAbsolutePath(), return {});
|
||||
const FilePath newFileName = m_baseDir->filePath().resolvePath(yamlFilePath);
|
||||
|
||||
FileReader reader;
|
||||
if (QTC_GUARD(reader.fetch(FilePath::fromString(yamlFilePath),
|
||||
QIODevice::ReadOnly | QIODevice::Text))) {
|
||||
if (QTC_GUARD(reader.fetch(yamlFilePath, QIODevice::ReadOnly | QIODevice::Text))) {
|
||||
QByteArray contents = reader.data();
|
||||
contents.replace("FILE_PATH", filePathToInject.toLocal8Bit());
|
||||
contents.replace("FILE_PATH", filePathToInject.toString().toLocal8Bit());
|
||||
|
||||
FileSaver fileSaver(newFileName, QIODevice::WriteOnly | QIODevice::Text);
|
||||
QTC_CHECK(fileSaver.write(contents));
|
||||
|
||||
@@ -44,7 +44,8 @@ private slots:
|
||||
void testOffsetMultiByteCodePoint2();
|
||||
|
||||
private:
|
||||
Utils::FilePath createFile(const QString &yamlFilePath, const QString &filePathToInject) const;
|
||||
Utils::FilePath createFile(const Utils::FilePath &yamlFilePath,
|
||||
const Utils::FilePath &filePathToInject) const;
|
||||
Utils::FilePath filePath(const QString &fileName) const;
|
||||
|
||||
CppEditor::Tests::TemporaryCopiedDir * const m_baseDir;
|
||||
|
||||
@@ -298,10 +298,6 @@ ProjectWizardPage::ProjectWizardPage(QWidget *parent)
|
||||
scrollArea,
|
||||
}.attachTo(this);
|
||||
|
||||
connect(m_projectComboBox, &QComboBox::currentIndexChanged,
|
||||
this, &ProjectWizardPage::projectChanged);
|
||||
connect(m_addToVersionControlComboBox, &QComboBox::currentIndexChanged,
|
||||
this, &ProjectWizardPage::versionControlChanged);
|
||||
connect(m_vcsManageButton, &QAbstractButton::clicked, this, &ProjectWizardPage::manageVcs);
|
||||
setProperty(SHORT_TITLE_PROPERTY, Tr::tr("Summary"));
|
||||
|
||||
@@ -376,6 +372,7 @@ void ProjectWizardPage::initializeVersionControls()
|
||||
// 2) Directory is managed and VCS does not support "Add" -> None available
|
||||
// 3) Directory is not managed -> Offer all VCS that support "CreateRepository"
|
||||
|
||||
m_addToVersionControlComboBox->disconnect();
|
||||
QList<IVersionControl *> versionControls = VcsManager::versionControls();
|
||||
if (versionControls.isEmpty())
|
||||
hideVersionControlUiElements();
|
||||
@@ -419,6 +416,9 @@ void ProjectWizardPage::initializeVersionControls()
|
||||
int newIdx = m_activeVersionControls.indexOf(currentSelection) + 1;
|
||||
setVersionControlIndex(newIdx);
|
||||
}
|
||||
|
||||
connect(m_addToVersionControlComboBox, &QComboBox::currentIndexChanged,
|
||||
this, &ProjectWizardPage::versionControlChanged);
|
||||
}
|
||||
|
||||
bool ProjectWizardPage::runVersionControl(const QList<GeneratedFile> &files, QString *errorMessage)
|
||||
@@ -457,6 +457,7 @@ void ProjectWizardPage::initializeProjectTree(Node *context, const FilePaths &pa
|
||||
IWizardFactory::WizardKind kind,
|
||||
ProjectAction action)
|
||||
{
|
||||
m_projectComboBox->disconnect();
|
||||
BestNodeSelector selector(m_commonDirectory, paths);
|
||||
|
||||
TreeItem *root = m_model.rootItem();
|
||||
@@ -489,6 +490,8 @@ void ProjectWizardPage::initializeProjectTree(Node *context, const FilePaths &pa
|
||||
setAddingSubProject(action == AddSubProject);
|
||||
|
||||
m_projectComboBox->setEnabled(m_model.rowCount(QModelIndex()) > 1);
|
||||
connect(m_projectComboBox, &QComboBox::currentIndexChanged,
|
||||
this, &ProjectWizardPage::projectChanged);
|
||||
}
|
||||
|
||||
void ProjectWizardPage::setNoneLabel(const QString &label)
|
||||
|
||||
@@ -31,7 +31,7 @@ add_qtc_library(QmlDesignerUtils STATIC
|
||||
)
|
||||
|
||||
extend_qtc_library(QmlDesignerUtils
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
@@ -84,7 +84,7 @@ endif()
|
||||
|
||||
|
||||
extend_qtc_library(QmlDesignerCore
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
@@ -481,7 +481,7 @@ add_qtc_plugin(QmlDesigner
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
@@ -1088,7 +1088,7 @@ add_qtc_plugin(assetexporterplugin
|
||||
)
|
||||
|
||||
extend_qtc_plugin(assetexporterplugin
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
@@ -1121,7 +1121,7 @@ add_qtc_plugin(componentsplugin
|
||||
)
|
||||
|
||||
extend_qtc_plugin(componentsplugin
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
@@ -1141,7 +1141,7 @@ add_qtc_plugin(qmlpreviewplugin
|
||||
)
|
||||
|
||||
extend_qtc_plugin(qmlpreviewplugin
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
@@ -1163,7 +1163,7 @@ add_qtc_plugin(qtquickplugin
|
||||
)
|
||||
|
||||
extend_qtc_plugin(qtquickplugin
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
env_with_default("QDS_DISABLE_COMPILE_WARNING_AS_ERROR" ENV_QDS_DISABLE_COMPILE_WARNING_AS_ERROR OFF)
|
||||
option(DISABLE_COMPILE_WARNING_AS_ERROR "Dont treat warnings as errors" ${ENV_QDS_DISABLE_COMPILE_WARNING_AS_ERROR})
|
||||
add_feature_info("Treat warnings as errors" ${DISABLE_COMPILE_WARNING_AS_ERROR} "")
|
||||
if(BUILD_DESIGNSTUDIO AND ($<CONFIG:Debug> OR WITH_TESTS))
|
||||
set(ENABLE_COMPILE_WARNING_AS_ERROR_DEFAULT ON)
|
||||
else()
|
||||
set(ENABLE_COMPILE_WARNING_AS_ERROR_DEFAULT OFF)
|
||||
endif()
|
||||
env_with_default("QDS_ENABLE_COMPILE_WARNING_AS_ERROR" ENV_ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
${ENABLE_COMPILE_WARNING_AS_ERROR_DEFAULT})
|
||||
option(ENABLE_COMPILE_WARNING_AS_ERROR "Treat warnings as errors in QmlDesigner" ${ENV_ENABLE_COMPILE_WARNING_AS_ERROR})
|
||||
add_feature_info("Treat warnings as errors in QmlDesigner" ${ENABLE_COMPILE_WARNING_AS_ERROR} "")
|
||||
|
||||
add_qtc_plugin(QmlDesignerBase
|
||||
CONDITION TARGET Qt::QuickWidgets
|
||||
@@ -12,7 +18,7 @@ add_qtc_plugin(QmlDesignerBase
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesignerBase
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ add_qtc_plugin(QmlProjectManager
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlProjectManager
|
||||
CONDITION NOT DISABLE_COMPILE_WARNING_AS_ERROR
|
||||
CONDITION ENABLE_COMPILE_WARNING_AS_ERROR
|
||||
PROPERTIES COMPILE_WARNING_AS_ERROR ON
|
||||
)
|
||||
|
||||
|
||||
@@ -301,6 +301,21 @@ expected_str<QList<ExampleItem *>> parseExamples(const QByteArray &manifestData,
|
||||
return items;
|
||||
}
|
||||
|
||||
// ordered list of "known" categories
|
||||
// TODO this should be defined in the manifest
|
||||
Q_GLOBAL_STATIC_WITH_ARGS(QList<QString>,
|
||||
defaultOrder,
|
||||
{QStringList() << "Application Examples"
|
||||
<< "Desktop"
|
||||
<< "Mobile"
|
||||
<< "Embedded"
|
||||
<< "Graphics"
|
||||
<< "Input/Output"
|
||||
<< "Connectivity"
|
||||
<< "Networking"
|
||||
<< "Positioning & Location"
|
||||
<< "Internationalization"});
|
||||
|
||||
static bool sortByHighlightedAndName(ExampleItem *first, ExampleItem *second)
|
||||
{
|
||||
if (first->isHighlighted && !second->isHighlighted)
|
||||
@@ -350,15 +365,20 @@ QList<std::pair<Core::Section, QList<ExampleItem *>>> getCategories(const QList<
|
||||
} else {
|
||||
// All original items have been copied into a category or other, delete.
|
||||
qDeleteAll(items);
|
||||
static const int defaultOrderSize = defaultOrder->size();
|
||||
int index = 0;
|
||||
const auto end = categoryMap.constKeyValueEnd();
|
||||
for (auto it = categoryMap.constKeyValueBegin(); it != end; ++it) {
|
||||
categories.append({{it->first, index, /*maxRows=*/index == 0 ? 2 : 1}, it->second});
|
||||
// order "known" categories as wanted, others come afterwards
|
||||
const int defaultIndex = defaultOrder->indexOf(it->first);
|
||||
const int priority = defaultIndex >= 0 ? defaultIndex : (index + defaultOrderSize);
|
||||
categories.append({{it->first, priority, /*maxRows=*/index == 0 ? 2 : 1}, it->second});
|
||||
++index;
|
||||
}
|
||||
if (!other.isEmpty())
|
||||
categories.append({{otherDisplayName, index, /*maxRows=*/1}, other});
|
||||
categories.append({{otherDisplayName, index + defaultOrderSize, /*maxRows=*/1}, other});
|
||||
}
|
||||
|
||||
const auto end = categories.end();
|
||||
for (auto it = categories.begin(); it != end; ++it)
|
||||
sort(it->second, sortByHighlightedAndName);
|
||||
|
||||
39
tests/auto/qml/codemodel/check/accessById.qml
Normal file
39
tests/auto/qml/codemodel/check/accessById.qml
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Window
|
||||
|
||||
Window {
|
||||
id: root
|
||||
width: 640
|
||||
height: 480
|
||||
visible: true
|
||||
title: qsTr("Hello World")
|
||||
|
||||
Rectangle {
|
||||
id: rect
|
||||
|
||||
Rectangle {
|
||||
id: innerRect
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: myText
|
||||
width: 50
|
||||
wrapMode: Text.WordWrap
|
||||
text: "a text string that is longer than 50 pixels"
|
||||
|
||||
Text {
|
||||
id: innerText
|
||||
}
|
||||
states: State {
|
||||
name: "widerText"
|
||||
PropertyChanges { myText.width: undefined }
|
||||
AnchorChanges { innerRect.width: undefined } // 16 29 37
|
||||
}
|
||||
}
|
||||
|
||||
Binding {rect.width: innerText.width}
|
||||
}
|
||||
Reference in New Issue
Block a user