Merge remote-tracking branch 'origin/6.0'
Change-Id: Ia7fc255ee8680e6beac5d4d878f446fe40873183
BIN
doc/qtcreator/images/qtcreator-options-clangd.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 19 KiB |
@@ -138,10 +138,6 @@
|
||||
edit the value for the \uicontrol {Do not index files greater than}
|
||||
check box. To index all files, deselect the check box.
|
||||
|
||||
\li To use clangd instead of the built-in code model for features such as
|
||||
\e {Find References to Symbol}, check the \uicontrol {Use clangd} checkbox.
|
||||
\note This is an experimental feature, which might not work reliably yet.
|
||||
|
||||
\li The \uicontrol {Diagnostic Configuration} field shows the Clang
|
||||
checks to perform. Click the value of the field to open the
|
||||
\uicontrol {Diagnostic Configurations} dialog, where you can
|
||||
@@ -151,6 +147,51 @@
|
||||
|
||||
\endlist
|
||||
|
||||
\section1 Configuring clangd
|
||||
|
||||
You can use the experimental clangd support instead of libclang to receive
|
||||
exact and complete results for services such as finding references,
|
||||
following symbols under cursor, and using the locator, even for complex
|
||||
constructs that the built-in code model cannot handle correctly. These
|
||||
improvements are based on clangd's \e index. When you \l{Opening Projects}
|
||||
{open a project}, clangd scans the source files to generate the index. For
|
||||
large projects, this can take a while, but the index is persistent and
|
||||
re-scanning is incremental, so nothing is lost by closing and re-starting
|
||||
\QC.
|
||||
|
||||
Because clangd considers only the on-disk state of included header files
|
||||
when parsing a source file, you need to save changes in header files to
|
||||
have them considered elsewhere for completion, diagnostics, and so on.
|
||||
Partly for this reason, files that are changed by refactoring actions are
|
||||
saved automatically. To disable this feature, select \uicontrol Tools >
|
||||
\uicontrol Options > \uicontrol Environment > \uicontrol System >
|
||||
\uicontrol {Auto-save files after refactoring}.
|
||||
|
||||
The document outline in the \l{Viewing Defined Types and Symbols}
|
||||
{Outline} view is backed by clangd's document symbol support, which
|
||||
makes the results more reliable than before.
|
||||
|
||||
To use clangd for the current project instead of the built-in code model or
|
||||
Clang:
|
||||
|
||||
\list 1
|
||||
\li Select \uicontrol Tools > \uicontrol Options > \uicontrol C++ >
|
||||
\uicontrol Clang > \uicontrol {Use clangd (EXPERIMENTAL)}.
|
||||
\image qtcreator-options-clangd.png "clangd options"
|
||||
\li In \uicontrol {Path to executable}, enter the path to clangd
|
||||
version 13, or later.
|
||||
\li For more accurate results during global symbol searches, select
|
||||
\uicontrol {Enable background indexing}. However, this increases the
|
||||
CPU load the first time you open the project.
|
||||
\li Select \uicontrol {Insert header files on completion} to allow
|
||||
clangd to insert header files as part of symbol completion.
|
||||
\li By default, clangd attempts to use all unused cores. You can set a
|
||||
fixed number of cores to use in \uicontrol {Worker thread count}.
|
||||
\li In \uicontrol {Document update threshold}, specify the amount of
|
||||
time \QC waits before sending document changes to the server.
|
||||
If the document changes again while waiting, this timeout is reset.
|
||||
\endlist
|
||||
|
||||
\section1 Clang Checks
|
||||
|
||||
In addition to using the built-in checks, you can select \uicontrol Copy to
|
||||
|
@@ -116,7 +116,8 @@
|
||||
|
||||
\section1 Advanced Search
|
||||
|
||||
To search through projects, files on a file system or currently open files:
|
||||
To search through projects, files on a file system, files in all project
|
||||
directories, or currently open files:
|
||||
|
||||
\list 1
|
||||
|
||||
@@ -136,6 +137,9 @@
|
||||
\li \uicontrol {Current Project} searches from the project you
|
||||
are currently editing.
|
||||
|
||||
\li \uicontrol {Files in All Project Directories} searches from
|
||||
all project directories.
|
||||
|
||||
\li \uicontrol {Files in File System} recursively searches from
|
||||
the selected directory.
|
||||
|
||||
@@ -206,6 +210,9 @@
|
||||
To clear the search results, select the \inlineimage clean_pane_small.png
|
||||
(\uicontrol Clear) button.
|
||||
|
||||
To expand and collapse the search results, select the
|
||||
\uicontrol {Expand All} button.
|
||||
|
||||
To start a new search, select the \inlineimage qtcreator-new-search-icon.png
|
||||
(\uicontrol {New Search}) button.
|
||||
|
||||
|
@@ -38,6 +38,9 @@
|
||||
\uicontrol Design mode:
|
||||
|
||||
\image qtcreator-filesystem-view-design.png "File System view in the Design mode"
|
||||
\else
|
||||
\image qtcreator-filesystem-view.png "File System view in the sidebar"
|
||||
\endif
|
||||
|
||||
To move to the root directory of the file system, select \uicontrol Computer
|
||||
in the menu (1). Select \uicontrol Home to move to the user's home
|
||||
@@ -89,14 +92,19 @@
|
||||
\li Collapse all open folders.
|
||||
\endlist
|
||||
|
||||
\section1 File System View in Sidebar
|
||||
\endif
|
||||
\section1 File System View Toolbar
|
||||
|
||||
\if defined(qtdesignstudio)
|
||||
In the \uicontrol Edit and \uicontrol Debug mode, the
|
||||
\uicontrol {File System} view is displayed in the \l{Working with Sidebars}
|
||||
{sidebar}. It has a toolbar with additional options:
|
||||
{sidebar}. It has a toolbar with additional options.
|
||||
|
||||
\image qtcreator-filesystem-view.png "File System view in the sidebar"
|
||||
\else
|
||||
The toolbar in the \uicontrol {File System} view contains additional
|
||||
options.
|
||||
\endif
|
||||
|
||||
|
||||
To manage view contents, select \inlineimage filtericon.png
|
||||
(\uicontrol Options):
|
||||
|
@@ -45,6 +45,9 @@
|
||||
\uicontrol Design mode:
|
||||
|
||||
\image qtcreator-projects-view-design.png "Projects view in the Design mode"
|
||||
\else
|
||||
\image qtcreator-projects-view-edit.png "Projects view in the sidebar"
|
||||
\endif
|
||||
|
||||
You can use the project tree in the following ways:
|
||||
|
||||
@@ -97,23 +100,29 @@
|
||||
\li Expand or collapse the tree view to show or hide all files and
|
||||
folders.
|
||||
\li Close all files in a project.
|
||||
\li Close projects. By default, all files in the project are also
|
||||
\li Close the selected project or all projects except the selected
|
||||
one. By default, all files in the projects are also
|
||||
closed. To keep them open, deselect the \uicontrol Tools >
|
||||
\uicontrol Options > \uicontrol {Build & Run} > \uicontrol General
|
||||
> \uicontrol {Close source files along with project} check box.
|
||||
\endlist
|
||||
|
||||
For managing files and directories, the same functions are available as in
|
||||
the \l {File System} view.
|
||||
the \l {File System} view. To view a project in it, select
|
||||
\uicontrol {Show in File System View}.
|
||||
|
||||
\section1 Projects View in Sidebar
|
||||
\endif
|
||||
\section1 Projects View Toolbar
|
||||
|
||||
\if defined(qtdesignstudio)
|
||||
In the \uicontrol Edit and \uicontrol Debug mode, the \uicontrol Projects
|
||||
view is displayed in the \l{Working with Sidebars}{sidebar}. It has a
|
||||
toolbar with additional options:
|
||||
toolbar with additional options.
|
||||
|
||||
\image qtcreator-projects-view-edit.png "Projects view in the sidebar"
|
||||
\else
|
||||
The toolbar in the \uicontrol Projects view contains additional options.
|
||||
\endif
|
||||
|
||||
|
||||
To filter view contents, select \inlineimage filtericon.png
|
||||
(\uicontrol {Filter Tree}):
|
||||
@@ -141,9 +150,7 @@
|
||||
(currently qmake and Qbs). The faithful display of the project structure
|
||||
allows to specify exactly where a new file should be placed in the build
|
||||
system.
|
||||
\endif
|
||||
|
||||
\if defined(qtcreator)
|
||||
If the project is under version control, information from the version
|
||||
control system might be displayed in brackets after the project name.
|
||||
This is currently implemented for Git (the branch name or a tag is
|
||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 7.7 KiB |
@@ -200,12 +200,7 @@
|
||||
|
||||
To create an arc with an outline, select the \uicontrol {Full outline}
|
||||
check box. The \uicontrol {Outline width} field sets the width of
|
||||
the arc outline, including the stroke. The \uicontrol {Outline start}
|
||||
and \uicontrol {Outline end} fields set the width of the start and
|
||||
end points of the outline separately. The width of the outline between
|
||||
them is calculated automatically. You can adjust the inner and outer
|
||||
curves of the outline in the \uicontrol {Inner radius} and
|
||||
\uicontrol {Outer radius} fields.
|
||||
the arc outline, including the stroke.
|
||||
|
||||
The \uicontrol {Round outline}, \uicontrol {Round start}, and
|
||||
\uicontrol {Round end} properties specify whether the end points of the
|
||||
|
@@ -33,9 +33,18 @@ namespace QmlDesigner {
|
||||
View3DActionCommand::View3DActionCommand(Type type, bool enable)
|
||||
: m_type(type)
|
||||
, m_enabled(enable)
|
||||
, m_position(0)
|
||||
{
|
||||
}
|
||||
|
||||
View3DActionCommand::View3DActionCommand(int pos)
|
||||
: m_type(ParticlesSeek)
|
||||
, m_enabled(true)
|
||||
, m_position(pos)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool View3DActionCommand::isEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
@@ -46,10 +55,16 @@ View3DActionCommand::Type View3DActionCommand::type() const
|
||||
return m_type;
|
||||
}
|
||||
|
||||
int View3DActionCommand::position() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const View3DActionCommand &command)
|
||||
{
|
||||
out << qint32(command.isEnabled());
|
||||
out << qint32(command.type());
|
||||
out << qint32(command.position());
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -58,10 +73,13 @@ QDataStream &operator>>(QDataStream &in, View3DActionCommand &command)
|
||||
{
|
||||
qint32 enabled;
|
||||
qint32 type;
|
||||
qint32 pos;
|
||||
in >> enabled;
|
||||
in >> type;
|
||||
in >> pos;
|
||||
command.m_enabled = bool(enabled);
|
||||
command.m_type = View3DActionCommand::Type(type);
|
||||
command.m_position = pos;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
@@ -44,18 +44,34 @@ public:
|
||||
CameraToggle,
|
||||
OrientationToggle,
|
||||
EditLightToggle,
|
||||
ShowGrid
|
||||
ShowGrid,
|
||||
Edit3DParticleModeToggle,
|
||||
ParticlesPlay,
|
||||
ParticlesRestart,
|
||||
ParticlesSeek,
|
||||
};
|
||||
|
||||
explicit View3DActionCommand(Type type, bool enable);
|
||||
|
||||
View3DActionCommand() = default;
|
||||
|
||||
bool isEnabled() const;
|
||||
Type type() const;
|
||||
int position() const;
|
||||
|
||||
private:
|
||||
Type m_type = Empty;
|
||||
bool m_enabled = false;
|
||||
int m_position = 0;
|
||||
|
||||
protected:
|
||||
View3DActionCommand(int pos);
|
||||
};
|
||||
|
||||
class View3DSeekActionCommand : public View3DActionCommand
|
||||
{
|
||||
public:
|
||||
View3DSeekActionCommand(int pos) : View3DActionCommand(pos) {}
|
||||
};
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const View3DActionCommand &command);
|
||||
|
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "animationdriver.h"
|
||||
#include "private/qabstractanimation_p.h"
|
||||
|
||||
AnimationDriver::AnimationDriver(QObject *parent)
|
||||
: QAnimationDriver(parent)
|
||||
{
|
||||
setProperty("allowNegativeDelta", true);
|
||||
install();
|
||||
connect(this, SIGNAL(started()), this, SLOT(startTimer()));
|
||||
connect(this, SIGNAL(stopped()), this, SLOT(stopTimer()));
|
||||
}
|
||||
|
||||
AnimationDriver::~AnimationDriver()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AnimationDriver::timerEvent(QTimerEvent *e)
|
||||
{
|
||||
Q_ASSERT(e->timerId() == m_timer.timerId());
|
||||
Q_UNUSED(e);
|
||||
|
||||
quint32 old = elapsed();
|
||||
// Provide same time for all users
|
||||
if (m_seekerEnabled) {
|
||||
m_seekerElapsed += (m_seekerPos * 100) / 30;
|
||||
if (m_seekerElapsed + m_elapsed < -100) // -100 to allow small negative value
|
||||
m_seekerElapsed = -m_elapsed - 100;
|
||||
} else {
|
||||
m_elapsed = QAnimationDriver::elapsed();
|
||||
}
|
||||
m_delta = elapsed() - old;
|
||||
advance();
|
||||
Q_EMIT advanced();
|
||||
}
|
||||
|
||||
void AnimationDriver::startTimer()
|
||||
{
|
||||
m_timer.start(m_interval, Qt::PreciseTimer, this);
|
||||
}
|
||||
|
||||
void AnimationDriver::stopTimer()
|
||||
{
|
||||
m_timer.stop();
|
||||
}
|
||||
|
||||
void AnimationDriver::setSeekerPosition(int position)
|
||||
{
|
||||
if (!m_seekerEnabled)
|
||||
return;
|
||||
|
||||
if (!m_timer.isActive())
|
||||
restart();
|
||||
|
||||
m_seekerPos = position;
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qabstractanimation.h>
|
||||
#include <QtCore/qbasictimer.h>
|
||||
#include <QtCore/qmath.h>
|
||||
|
||||
class AnimationDriver : public QAnimationDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AnimationDriver(QObject *parent = nullptr);
|
||||
~AnimationDriver();
|
||||
void timerEvent(QTimerEvent *e) override;
|
||||
void setInterval(int interval)
|
||||
{
|
||||
m_interval = qBound(1, interval, 60);
|
||||
}
|
||||
int interval() const
|
||||
{
|
||||
return m_interval;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
stop();
|
||||
stopTimer();
|
||||
}
|
||||
void restart()
|
||||
{
|
||||
start();
|
||||
startTimer();
|
||||
}
|
||||
qint64 elapsed() const override
|
||||
{
|
||||
return m_elapsed + m_seekerElapsed;
|
||||
}
|
||||
void setSeekerPosition(int position);
|
||||
void setSeekerEnabled(bool enable)
|
||||
{
|
||||
m_seekerEnabled = enable;
|
||||
}
|
||||
bool isSeekerEnabled() const
|
||||
{
|
||||
return m_seekerEnabled;
|
||||
}
|
||||
bool isAnimating() const
|
||||
{
|
||||
return (!m_seekerEnabled && m_timer.isActive()) || (m_seekerEnabled && m_delta && m_seekerPos);
|
||||
}
|
||||
Q_SIGNALS:
|
||||
void advanced();
|
||||
|
||||
private:
|
||||
Q_SLOT void startTimer();
|
||||
Q_SLOT void stopTimer();
|
||||
|
||||
QBasicTimer m_timer;
|
||||
int m_interval = 16;
|
||||
int m_seekerPos = 0;
|
||||
bool m_seekerEnabled = false;
|
||||
qint64 m_elapsed = 0;
|
||||
qint64 m_seekerElapsed = 0;
|
||||
qint64 m_delta = 0;
|
||||
};
|
@@ -44,6 +44,8 @@ HEADERS += $$PWD/qt5nodeinstanceserver.h \
|
||||
$$PWD/qt3dpresentationnodeinstance.h \
|
||||
$$PWD/quick3dnodeinstance.h \
|
||||
$$PWD/quick3dtexturenodeinstance.h \
|
||||
$$PWD/viewconfig.h \
|
||||
$$PWD/animationdriver.h
|
||||
|
||||
|
||||
SOURCES += $$PWD/qt5nodeinstanceserver.cpp \
|
||||
@@ -74,4 +76,6 @@ SOURCES += $$PWD/qt5nodeinstanceserver.cpp \
|
||||
$$PWD/layoutnodeinstance.cpp \
|
||||
$$PWD/qt3dpresentationnodeinstance.cpp \
|
||||
$$PWD/quick3dnodeinstance.cpp \
|
||||
$$PWD/quick3dtexturenodeinstance.cpp
|
||||
$$PWD/quick3dtexturenodeinstance.cpp \
|
||||
$$PWD/viewconfig.cpp \
|
||||
$$PWD/animationdriver.cpp
|
||||
|
@@ -332,7 +332,8 @@ void NodeInstanceServer::createScene(const CreateSceneCommand &command)
|
||||
registerFonts(command.resourceUrl);
|
||||
setTranslationLanguage(command.language);
|
||||
|
||||
Internal::QmlPrivateGate::stopUnifiedTimer();
|
||||
if (!ViewConfig::isParticleViewMode())
|
||||
Internal::QmlPrivateGate::stopUnifiedTimer();
|
||||
|
||||
setupScene(command);
|
||||
setupState(command.stateInstanceId);
|
||||
@@ -783,6 +784,15 @@ QList<QQmlContext *> NodeInstanceServer::allSubContextsForObject(QObject *object
|
||||
return contextList;
|
||||
}
|
||||
|
||||
QList<QObject *> NodeInstanceServer::allSubObjectsForObject(QObject *object)
|
||||
{
|
||||
QList<QObject *> subChildren;
|
||||
if (object)
|
||||
subChildren = object->findChildren<QObject *>();
|
||||
|
||||
return subChildren;
|
||||
}
|
||||
|
||||
void NodeInstanceServer::removeAllInstanceRelationships()
|
||||
{
|
||||
for (ServerNodeInstance &instance : m_objectInstanceHash) {
|
||||
@@ -1563,4 +1573,39 @@ bool NodeInstanceServer::isInformationServer() const
|
||||
return false;
|
||||
}
|
||||
|
||||
static QString baseProperty(const QString &property)
|
||||
{
|
||||
int index = property.indexOf('.');
|
||||
if (index > 0)
|
||||
return property.left(index);
|
||||
return property;
|
||||
}
|
||||
|
||||
void NodeInstanceServer::addAnimation(QQuickAbstractAnimation *animation)
|
||||
{
|
||||
if (!m_animations.contains(animation)) {
|
||||
m_animations.push_back(animation);
|
||||
|
||||
QQuickPropertyAnimation *panim = qobject_cast<QQuickPropertyAnimation *>(animation);
|
||||
if (panim) {
|
||||
QObject *target = panim->target();
|
||||
QString property = panim->property();
|
||||
QVariant value = target->property(qPrintable(baseProperty(property)));
|
||||
m_defaultValues.push_back(value);
|
||||
} else {
|
||||
m_defaultValues.push_back({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVector<QQuickAbstractAnimation *> NodeInstanceServer::animations() const
|
||||
{
|
||||
return m_animations;
|
||||
}
|
||||
|
||||
QVariant NodeInstanceServer::animationDefaultValue(int index) const
|
||||
{
|
||||
return m_defaultValues.at(index);
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -43,6 +43,20 @@
|
||||
#include <nodeinstanceserverinterface.h>
|
||||
#include "servernodeinstance.h"
|
||||
#include "debugoutputcommand.h"
|
||||
#include "viewconfig.h"
|
||||
|
||||
#include <private/qabstractanimation_p.h>
|
||||
#include <private/qobject_p.h>
|
||||
#include <private/qquickbehavior_p.h>
|
||||
#include <private/qquicktext_p.h>
|
||||
#include <private/qquicktextinput_p.h>
|
||||
#include <private/qquicktextedit_p.h>
|
||||
#include <private/qquicktransition_p.h>
|
||||
#include <private/qquickloader_p.h>
|
||||
|
||||
#include <private/qquickanimation_p.h>
|
||||
#include <private/qqmlmetatype_p.h>
|
||||
#include <private/qqmltimer_p.h>
|
||||
|
||||
namespace QtHelpers {
|
||||
template <class T>
|
||||
@@ -217,6 +231,9 @@ public:
|
||||
virtual QImage grabItem(QQuickItem *item) = 0;
|
||||
|
||||
virtual bool isInformationServer() const;
|
||||
void addAnimation(QQuickAbstractAnimation *animation);
|
||||
QVector<QQuickAbstractAnimation *> animations() const;
|
||||
QVariant animationDefaultValue(int index) const;
|
||||
|
||||
public slots:
|
||||
void refreshLocalFileProperty(const QString &path);
|
||||
@@ -291,7 +308,8 @@ protected:
|
||||
void setupDefaultDummyData();
|
||||
QList<ServerNodeInstance> setupInstances(const CreateSceneCommand &command);
|
||||
|
||||
QList<QQmlContext *> allSubContextsForObject(QObject *object);
|
||||
QList<QQmlContext*> allSubContextsForObject(QObject *object);
|
||||
static QList<QObject*> allSubObjectsForObject(QObject *object);
|
||||
|
||||
virtual void resizeCanvasToRootItem() = 0;
|
||||
void setupState(qint32 stateInstanceId);
|
||||
@@ -322,6 +340,8 @@ private:
|
||||
std::unique_ptr<MultiLanguage::Link> multilanguageLink;
|
||||
int m_needsExtraRenderCount = 0;
|
||||
int m_extraRenderCurrentPass = 0;
|
||||
QVector<QQuickAbstractAnimation *> m_animations;
|
||||
QVector<QVariant> m_defaultValues;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -87,6 +87,7 @@
|
||||
#include <QQmlEngine>
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
#include <QtQuick/private/qquickrendercontrol_p.h>
|
||||
@@ -103,10 +104,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
#include <QtQuick3DParticles/private/qquick3dparticlesystem_p.h>
|
||||
#endif
|
||||
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
#include <QtQuick3DAssetImport/private/qssgassetimportmanager_p.h>
|
||||
#endif
|
||||
@@ -216,7 +213,7 @@ void Qt5InformationNodeInstanceServer::createAuxiliaryQuickView(const QUrl &url,
|
||||
|
||||
void Qt5InformationNodeInstanceServer::updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances)
|
||||
{
|
||||
if (!isQuick3DMode())
|
||||
if (!ViewConfig::isQuick3DMode())
|
||||
return;
|
||||
|
||||
// We only want to update the topmost parents in the set
|
||||
@@ -406,9 +403,83 @@ void Qt5InformationNodeInstanceServer::createEditView3D()
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
void Qt5InformationNodeInstanceServer::resetParticleSystem()
|
||||
{
|
||||
if (!m_targetParticleSystem)
|
||||
return;
|
||||
m_targetParticleSystem->reset();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 2)
|
||||
m_targetParticleSystem->setEditorTime(0);
|
||||
#endif
|
||||
if (m_particleAnimationDriver)
|
||||
m_particleAnimationDriver->reset();
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::handleParticleSystemSelected(QQuick3DParticleSystem* targetParticleSystem)
|
||||
{
|
||||
if (!m_particleAnimationDriver)
|
||||
return;
|
||||
|
||||
m_particleAnimationDriver->reset();
|
||||
// stop the previously selected from animating
|
||||
resetParticleSystem();
|
||||
|
||||
m_targetParticleSystem = targetParticleSystem;
|
||||
|
||||
resetParticleSystem();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 2)
|
||||
QObject::disconnect(m_particleAnimationConnection);
|
||||
m_particleAnimationConnection = connect(m_particleAnimationDriver, &AnimationDriver::advanced, [this] () {
|
||||
if (m_targetParticleSystem)
|
||||
m_targetParticleSystem->setEditorTime(m_particleAnimationDriver->elapsed());
|
||||
});
|
||||
#endif
|
||||
if (m_particleAnimationPlaying && m_targetParticleSystem->visible())
|
||||
m_particleAnimationDriver->restart();
|
||||
QObject::connect(m_targetParticleSystem, &QQuick3DNode::visibleChanged, [this] () {
|
||||
if (m_particleAnimationPlaying && m_targetParticleSystem->visible()) {
|
||||
m_particleAnimationDriver->restart();
|
||||
} else {
|
||||
m_particleAnimationDriver->reset();
|
||||
resetParticleSystem();
|
||||
}
|
||||
});
|
||||
|
||||
const auto anim = animations();
|
||||
for (auto a : anim)
|
||||
a->restart();
|
||||
}
|
||||
|
||||
static QString baseProperty(const QString &property)
|
||||
{
|
||||
int index = property.indexOf('.');
|
||||
if (index > 0)
|
||||
return property.left(index);
|
||||
return property;
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::handleParticleSystemDeselected()
|
||||
{
|
||||
m_targetParticleSystem = nullptr;
|
||||
const auto anim = animations();
|
||||
int i = 0;
|
||||
for (auto a : anim) {
|
||||
a->stop();
|
||||
QQuickPropertyAnimation *panim = qobject_cast<QQuickPropertyAnimation *>(a);
|
||||
if (panim)
|
||||
panim->target()->setProperty(qPrintable(baseProperty(panim->property())), animationDefaultValue(i));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// The selection has changed in the edit view 3D. Empty list indicates selection is cleared.
|
||||
void Qt5InformationNodeInstanceServer::handleSelectionChanged(const QVariant &objs)
|
||||
{
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
resetParticleSystem();
|
||||
#endif
|
||||
QList<ServerNodeInstance> instanceList;
|
||||
const QVariantList varObjs = objs.value<QVariantList>();
|
||||
for (const auto &object : varObjs) {
|
||||
@@ -829,6 +900,12 @@ void Qt5InformationNodeInstanceServer::doRender3DEditView()
|
||||
m_render3DEditViewTimer.start(0);
|
||||
--m_need3DEditViewRender;
|
||||
}
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
if (ViewConfig::isParticleViewMode()
|
||||
&& m_particleAnimationDriver && m_particleAnimationDriver->isAnimating()) {
|
||||
m_need3DEditViewRender++;
|
||||
}
|
||||
#endif
|
||||
#ifdef FPS_COUNTER
|
||||
// Force constant rendering for accurate fps count
|
||||
if (!m_render3DEditViewTimer.isActive())
|
||||
@@ -1084,6 +1161,12 @@ Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceC
|
||||
_fpsTimer->start();
|
||||
}
|
||||
#endif
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
if (ViewConfig::isParticleViewMode()) {
|
||||
m_particleAnimationDriver = new AnimationDriver(this);
|
||||
m_particleAnimationDriver->setInterval(17);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
|
||||
@@ -1205,7 +1288,7 @@ QList<ServerNodeInstance> Qt5InformationNodeInstanceServer::createInstances(
|
||||
void Qt5InformationNodeInstanceServer::initializeAuxiliaryViews()
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (isQuick3DMode())
|
||||
if (ViewConfig::isQuick3DMode())
|
||||
createEditView3D();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/qt6/ModelNode3DImageView.qml"),
|
||||
@@ -1665,7 +1748,7 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
|
||||
sendChildrenChangedCommand(instanceList);
|
||||
nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList));
|
||||
|
||||
if (isQuick3DMode()) {
|
||||
if (ViewConfig::isQuick3DMode()) {
|
||||
setup3DEditView(instanceList, command.edit3dToolStates);
|
||||
updateRotationBlocks(command.auxiliaryChanges);
|
||||
}
|
||||
@@ -1735,7 +1818,9 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
|
||||
{
|
||||
if (!m_editView3DSetupDone)
|
||||
return;
|
||||
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
resetParticleSystem();
|
||||
#endif
|
||||
m_lastSelectionChangeCommand = command;
|
||||
if (m_selectionChangeTimer.isActive()) {
|
||||
// If selection was recently changed by puppet, hold updating the selection for a bit to
|
||||
@@ -1762,13 +1847,17 @@ void Qt5InformationNodeInstanceServer::changeSelection(const ChangeSelectionComm
|
||||
if (firstSceneRoot && sceneRoot == firstSceneRoot && instance.isSubclassOf("QQuick3DNode"))
|
||||
object = instance.internalObject();
|
||||
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
auto particlesystem = qobject_cast<QQuick3DParticleSystem *>(instance.internalObject());
|
||||
if (particlesystem)
|
||||
handleParticleSystemSelected(particlesystem);
|
||||
else
|
||||
handleParticleSystemDeselected();
|
||||
#endif
|
||||
auto isSelectableAsRoot = [&]() -> bool {
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (qobject_cast<QQuick3DModel *>(object)
|
||||
|| qobject_cast<QQuick3DCamera *>(object)
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
|| qobject_cast<QQuick3DParticleSystem *>(object)
|
||||
#endif
|
||||
|| qobject_cast<QQuick3DAbstractLight *>(object)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1900,6 +1989,33 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
||||
case View3DActionCommand::ShowGrid:
|
||||
updatedState.insert("showGrid", command.isEnabled());
|
||||
break;
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
case View3DActionCommand::Edit3DParticleModeToggle:
|
||||
updatedState.insert("enableParticleViewMode", command.isEnabled());
|
||||
break;
|
||||
case View3DActionCommand::ParticlesPlay:
|
||||
m_particleAnimationPlaying = command.isEnabled();
|
||||
if (m_particleAnimationPlaying) {
|
||||
m_particleAnimationDriver->reset();
|
||||
m_particleAnimationDriver->restart();
|
||||
m_particleAnimationDriver->setSeekerEnabled(false);
|
||||
m_particleAnimationDriver->setSeekerPosition(0);
|
||||
} else {
|
||||
m_particleAnimationDriver->reset();
|
||||
m_particleAnimationDriver->setSeekerEnabled(true);
|
||||
}
|
||||
break;
|
||||
case View3DActionCommand::ParticlesRestart:
|
||||
resetParticleSystem();
|
||||
m_particleAnimationPlaying = true;
|
||||
m_particleAnimationDriver->restart();
|
||||
m_particleAnimationDriver->setSeekerEnabled(false);
|
||||
m_particleAnimationDriver->setSeekerPosition(0);
|
||||
break;
|
||||
case View3DActionCommand::ParticlesSeek:
|
||||
m_particleAnimationDriver->setSeekerPosition(static_cast<const View3DSeekActionCommand &>(command).position());
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1977,7 +2093,7 @@ void Qt5InformationNodeInstanceServer::handleInstanceLocked(const ServerNodeInst
|
||||
bool enable, bool checkAncestors)
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (!isQuick3DMode())
|
||||
if (!ViewConfig::isQuick3DMode())
|
||||
return;
|
||||
|
||||
bool edit3dLocked = enable;
|
||||
@@ -2015,7 +2131,7 @@ void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInst
|
||||
bool enable, bool checkAncestors)
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (!isQuick3DMode())
|
||||
if (!ViewConfig::isQuick3DMode())
|
||||
return;
|
||||
|
||||
bool edit3dHidden = enable;
|
||||
|
@@ -32,8 +32,14 @@
|
||||
#include "requestmodelnodepreviewimagecommand.h"
|
||||
#include "propertybindingcontainer.h"
|
||||
#include "propertyabstractcontainer.h"
|
||||
#include "animationdriver.h"
|
||||
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
#include <QtQuick3DParticles/private/qquick3dparticlesystem_p.h>
|
||||
#endif
|
||||
|
||||
#include <QTimer>
|
||||
#include <QElapsedTimer>
|
||||
#include <QVariant>
|
||||
#include <QPointer>
|
||||
#include <QImage>
|
||||
@@ -140,6 +146,11 @@ private:
|
||||
void removeRotationBlocks(const QVector<qint32> &instanceIds);
|
||||
|
||||
void createAuxiliaryQuickView(const QUrl &url, RenderViewData &viewData);
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
void handleParticleSystemSelected(QQuick3DParticleSystem* targetParticleSystem);
|
||||
void resetParticleSystem();
|
||||
void handleParticleSystemDeselected();
|
||||
#endif
|
||||
|
||||
RenderViewData m_editView3DData;
|
||||
RenderViewData m_modelNode3DImageViewData;
|
||||
@@ -161,6 +172,12 @@ private:
|
||||
QTimer m_render3DEditViewTimer;
|
||||
QTimer m_renderModelNodeImageViewTimer;
|
||||
QTimer m_inputEventTimer;
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
bool m_particleAnimationPlaying = true;
|
||||
AnimationDriver *m_particleAnimationDriver = nullptr;
|
||||
QMetaObject::Connection m_particleAnimationConnection;
|
||||
QQuick3DParticleSystem* m_targetParticleSystem = nullptr;
|
||||
#endif
|
||||
QObjectList m_changedNodes;
|
||||
QList<PropertyName> m_changedProperties;
|
||||
ChangeSelectionCommand m_lastSelectionChangeCommand;
|
||||
|
@@ -82,6 +82,7 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) :
|
||||
setNodeInstanceServer(std::make_unique<Qt5PreviewNodeInstanceServer>(this));
|
||||
initializeSocket();
|
||||
} else if (QCoreApplication::arguments().at(2) == QLatin1String("editormode")) {
|
||||
ViewConfig::enableParticleView(true);
|
||||
setNodeInstanceServer(std::make_unique<Qt5InformationNodeInstanceServer>(this));
|
||||
initializeSocket();
|
||||
} else if (QCoreApplication::arguments().at(2) == QLatin1String("rendermode")) {
|
||||
|
@@ -60,7 +60,8 @@ namespace QmlDesigner {
|
||||
Qt5NodeInstanceServer::Qt5NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient)
|
||||
: NodeInstanceServer(nodeInstanceClient)
|
||||
{
|
||||
DesignerSupport::activateDesignerMode();
|
||||
if (!ViewConfig::isParticleViewMode())
|
||||
DesignerSupport::activateDesignerMode();
|
||||
}
|
||||
|
||||
Qt5NodeInstanceServer::~Qt5NodeInstanceServer()
|
||||
|
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "viewconfig.h"
|
||||
#include <QtGlobal>
|
||||
|
||||
bool ViewConfig::isQuick3DMode()
|
||||
{
|
||||
static bool mode3D = qEnvironmentVariableIsSet("QMLDESIGNER_QUICK3D_MODE");
|
||||
return mode3D;
|
||||
}
|
||||
|
||||
static bool particleViewEnabled = false;
|
||||
void ViewConfig::enableParticleView(bool enable)
|
||||
{
|
||||
particleViewEnabled = enable;
|
||||
}
|
||||
|
||||
bool ViewConfig::isParticleViewMode()
|
||||
{
|
||||
static bool particleviewmode = !qEnvironmentVariableIsSet("QT_QUICK3D_DISABLE_PARTICLE_SYSTEMS");
|
||||
return particleviewmode && particleViewEnabled;
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
class ViewConfig
|
||||
{
|
||||
public:
|
||||
static bool isQuick3DMode();
|
||||
static void enableParticleView(bool enable);
|
||||
static bool isParticleViewMode();
|
||||
};
|
@@ -34,6 +34,7 @@
|
||||
#include <QQuickItem>
|
||||
#include <QQmlComponent>
|
||||
#include <QFileInfo>
|
||||
#include <QProcessEnvironment>
|
||||
|
||||
#include <private/qabstractfileengine_p.h>
|
||||
#include <private/qfsfileengine_p.h>
|
||||
@@ -47,6 +48,19 @@
|
||||
#include <private/qqmldata_p.h>
|
||||
#include <private/qqmlcomponentattached_p.h>
|
||||
|
||||
#include <private/qabstractanimation_p.h>
|
||||
#include <private/qobject_p.h>
|
||||
#include <private/qquickbehavior_p.h>
|
||||
#include <private/qquicktext_p.h>
|
||||
#include <private/qquicktextinput_p.h>
|
||||
#include <private/qquicktextedit_p.h>
|
||||
#include <private/qquicktransition_p.h>
|
||||
#include <private/qquickloader_p.h>
|
||||
|
||||
#include <private/qquickanimation_p.h>
|
||||
#include <private/qqmlmetatype_p.h>
|
||||
#include <private/qqmltimer_p.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
namespace Internal {
|
||||
@@ -382,8 +396,15 @@ void doComponentCompleteRecursive(QObject *object, NodeInstanceServer *nodeInsta
|
||||
static_cast<QQmlParserStatus *>(item)->componentComplete();
|
||||
} else {
|
||||
QQmlParserStatus *qmlParserStatus = dynamic_cast<QQmlParserStatus *>(object);
|
||||
if (qmlParserStatus)
|
||||
if (qmlParserStatus) {
|
||||
qmlParserStatus->componentComplete();
|
||||
auto *anim = dynamic_cast<QQuickAbstractAnimation *>(object);
|
||||
if (anim && ViewConfig::isParticleViewMode()) {
|
||||
nodeInstanceServer->addAnimation(anim);
|
||||
anim->setEnableUserControl();
|
||||
anim->stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -116,7 +116,7 @@ Item {
|
||||
text: qsTr("Remove Module")
|
||||
visible: itemsView.currentCategory === null
|
||||
height: visible ? implicitHeight : 0
|
||||
enabled: itemsView.importToRemove !== ""
|
||||
enabled: itemsView.importToRemove !== "" && !rootView.subCompEditMode
|
||||
onTriggered: rootView.removeImport(itemsView.importToRemove)
|
||||
}
|
||||
|
||||
|
@@ -93,8 +93,10 @@ Item {
|
||||
anchors.topMargin: 1
|
||||
width: 24
|
||||
height: 24
|
||||
color: mouseArea.containsMouse ? StudioTheme.Values.themeControlBackgroundHover
|
||||
: StudioTheme.Values.themeControlBackground
|
||||
color: mouseArea.containsMouse && enabled
|
||||
? StudioTheme.Values.themeControlBackgroundHover
|
||||
: StudioTheme.Values.themeControlBackground
|
||||
enabled: index !== 0 || !rootView.subCompEditMode
|
||||
|
||||
Label { // + sign
|
||||
text: StudioTheme.Constants.plus
|
||||
|
@@ -162,10 +162,17 @@ QtObject {
|
||||
readonly property string visibilityOff: "\u009D" // visibilityOff2
|
||||
readonly property string visibilityOn: "\u009E"
|
||||
readonly property string wildcard: "\u009F"
|
||||
readonly property string zoomAll: "\u00A0"
|
||||
readonly property string zoomIn: "\u00A1"
|
||||
readonly property string zoomOut: "\u00A2"
|
||||
readonly property string zoomSelection: "\u00A3"
|
||||
readonly property string wizardsAutomotive: "\u00A0"
|
||||
readonly property string wizardsDesktop: "\u00A1"
|
||||
readonly property string wizardsGeneric: "\u00A2"
|
||||
readonly property string wizardsMcuEmpty: "\u00A3"
|
||||
readonly property string wizardsMcuGraph: "\u00A4"
|
||||
readonly property string wizardsMobile: "\u00A5"
|
||||
readonly property string wizardsUnknown: "\u00A6"
|
||||
readonly property string zoomAll: "\u00A7"
|
||||
readonly property string zoomIn: "\u00A8"
|
||||
readonly property string zoomOut: "\u00A9"
|
||||
readonly property string zoomSelection: "\u00AA"
|
||||
|
||||
readonly property font iconFont: Qt.font({
|
||||
"family": controlIcons.name,
|
||||
|
@@ -47,5 +47,17 @@ QDebug operator<<(QDebug debug, const DiagnosticContainer &container)
|
||||
return debug;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const QVector<DiagnosticContainer> &containers)
|
||||
{
|
||||
debug.nospace() << "{";
|
||||
for (int i = 0; i < containers.size(); i++) {
|
||||
debug.nospace() << containers[i];
|
||||
if (i < containers.size() - 1)
|
||||
debug.nospace() << ", ";
|
||||
}
|
||||
debug.nospace() << "}";
|
||||
return debug;
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
|
@@ -123,5 +123,8 @@ public:
|
||||
};
|
||||
|
||||
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const DiagnosticContainer &container);
|
||||
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const QVector<DiagnosticContainer> &container);
|
||||
|
||||
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -39,5 +39,17 @@ QDebug operator<<(QDebug debug, const FixItContainer &container)
|
||||
return debug;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const QVector<FixItContainer> &containers)
|
||||
{
|
||||
debug.nospace() << "{";
|
||||
for (int i = 0; i < containers.size(); i++) {
|
||||
debug.nospace() << containers[i];
|
||||
if (i < containers.size() - 1)
|
||||
debug.nospace() << ", ";
|
||||
}
|
||||
debug.nospace() << "}";
|
||||
return debug;
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
|
@@ -69,5 +69,6 @@ public:
|
||||
};
|
||||
|
||||
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const FixItContainer &container);
|
||||
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const QVector<FixItContainer> &container);
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -39,4 +39,16 @@ QDebug operator<<(QDebug debug, const SourceRangeContainer &container)
|
||||
return debug;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const QVector<SourceRangeContainer> &containers)
|
||||
{
|
||||
debug.nospace() << "{";
|
||||
for (int i = 0; i < containers.size(); i++) {
|
||||
debug.nospace() << containers[i];
|
||||
if (i < containers.size() - 1)
|
||||
debug.nospace() << ", ";
|
||||
}
|
||||
debug.nospace() << "}";
|
||||
return debug;
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -85,5 +85,6 @@ public:
|
||||
};
|
||||
|
||||
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const SourceRangeContainer &container);
|
||||
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const QVector<SourceRangeContainer> &container);
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -1275,6 +1275,9 @@ static bool isIntegerValue(const Value *value)
|
||||
|
||||
static bool strictCompareConstant(const Value *lhs, const Value *rhs)
|
||||
{
|
||||
// attached properties and working at runtime cases may be undefined at evaluation time
|
||||
if (lhs->asUndefinedValue() || rhs->asUndefinedValue())
|
||||
return false;
|
||||
if (lhs->asUnknownValue() || rhs->asUnknownValue())
|
||||
return false;
|
||||
if (lhs->asFunctionValue() || rhs->asFunctionValue()) // function evaluation not implemented
|
||||
@@ -1283,12 +1286,11 @@ static bool strictCompareConstant(const Value *lhs, const Value *rhs)
|
||||
return false;
|
||||
if (lhs->asBooleanValue() && !rhs->asBooleanValue())
|
||||
return true;
|
||||
// attached properties and working at runtime cases may be undefined at evaluation time
|
||||
if (lhs->asNumberValue() && (!rhs->asNumberValue() && !rhs->asUndefinedValue()))
|
||||
if (lhs->asNumberValue() && !rhs->asNumberValue())
|
||||
return true;
|
||||
if (lhs->asStringValue() && !rhs->asStringValue())
|
||||
return true;
|
||||
if (lhs->asObjectValue() && (!rhs->asObjectValue() || !rhs->asNullValue() || !rhs->asUndefinedValue()))
|
||||
if (lhs->asObjectValue() && (!rhs->asObjectValue() || !rhs->asNullValue()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include "qtcassert.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QElapsedTimer>
|
||||
#include <QLocalSocket>
|
||||
#include <QMutexLocker>
|
||||
|
||||
@@ -542,14 +541,11 @@ bool CallerHandle::isCalledFromLaunchersThread() const
|
||||
bool LauncherHandle::waitForSignal(int msecs, CallerHandle::SignalType newSignal)
|
||||
{
|
||||
QTC_ASSERT(!isCalledFromLaunchersThread(), return false);
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
QDeadlineTimer deadline(msecs);
|
||||
while (true) {
|
||||
const int remainingMsecs = msecs - timer.elapsed();
|
||||
if (remainingMsecs <= 0)
|
||||
if (deadline.hasExpired())
|
||||
break;
|
||||
const bool timedOut = !doWaitForSignal(qMax(remainingMsecs, 0), newSignal);
|
||||
if (timedOut)
|
||||
if (!doWaitForSignal(deadline, newSignal))
|
||||
break;
|
||||
m_awaitingShouldContinue = true; // TODO: make it recursive?
|
||||
const QList<CallerHandle::SignalType> flushedSignals = m_callerHandle->flushFor(newSignal);
|
||||
@@ -563,14 +559,12 @@ bool LauncherHandle::waitForSignal(int msecs, CallerHandle::SignalType newSignal
|
||||
return true;
|
||||
if (wasCanceled)
|
||||
return true; // or false? is false only in case of timeout?
|
||||
if (timer.hasExpired(msecs))
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Called from caller's thread exclusively.
|
||||
bool LauncherHandle::doWaitForSignal(int msecs, CallerHandle::SignalType newSignal)
|
||||
bool LauncherHandle::doWaitForSignal(QDeadlineTimer deadline, CallerHandle::SignalType newSignal)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QTC_ASSERT(isCalledFromCallersThread(), return false);
|
||||
@@ -585,7 +579,7 @@ bool LauncherHandle::doWaitForSignal(int msecs, CallerHandle::SignalType newSign
|
||||
return true;
|
||||
|
||||
m_waitingFor = newSignal;
|
||||
const bool ret = m_waitCondition.wait(&m_mutex, msecs);
|
||||
const bool ret = m_waitCondition.wait(&m_mutex, deadline);
|
||||
m_waitingFor = CallerHandle::SignalType::NoSignal;
|
||||
return ret;
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "launcherpackets.h"
|
||||
#include "processutils.h"
|
||||
|
||||
#include <QDeadlineTimer>
|
||||
#include <QHash>
|
||||
#include <QMutex>
|
||||
#include <QObject>
|
||||
@@ -213,7 +214,7 @@ public:
|
||||
|
||||
private:
|
||||
// Called from caller's thread exclusively.
|
||||
bool doWaitForSignal(int msecs, CallerHandle::SignalType newSignal);
|
||||
bool doWaitForSignal(QDeadlineTimer deadline, CallerHandle::SignalType newSignal);
|
||||
// Called from launcher's thread exclusively. Call me with mutex locked.
|
||||
void wakeUpIfWaitingFor(CallerHandle::SignalType newSignal);
|
||||
|
||||
|
@@ -294,7 +294,7 @@ static QTextLine currentTextLine(const QTextCursor &cursor)
|
||||
return layout->lineForTextPosition(relativePos);
|
||||
}
|
||||
|
||||
bool multiCursorAddEvent(QKeyEvent *e, QKeySequence::StandardKey matchKey)
|
||||
bool MultiTextCursor::multiCursorAddEvent(QKeyEvent *e, QKeySequence::StandardKey matchKey)
|
||||
{
|
||||
uint searchkey = (e->modifiers() | e->key())
|
||||
& ~(Qt::KeypadModifier
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "utils_global.h"
|
||||
|
||||
#include <QKeySequence>
|
||||
#include <QTextCursor>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@@ -99,6 +100,8 @@ public:
|
||||
const_iterator constBegin() const { return m_cursors.constBegin(); }
|
||||
const_iterator constEnd() const { return m_cursors.constEnd(); }
|
||||
|
||||
static bool multiCursorAddEvent(QKeyEvent *e, QKeySequence::StandardKey matchKey);
|
||||
|
||||
private:
|
||||
QList<QTextCursor> m_cursors;
|
||||
};
|
||||
|
@@ -847,7 +847,7 @@ bool AndroidConfig::isValidNdk(const QString &ndkLocation) const
|
||||
return false;
|
||||
|
||||
const QVersionNumber version = ndkVersion(ndkPath);
|
||||
if (ndkVersion(ndkPath).isNull())
|
||||
if (version.isNull())
|
||||
return false;
|
||||
|
||||
const FilePath ndkPlatformsDir = ndkPath.pathAppended("platforms");
|
||||
|
@@ -81,12 +81,12 @@ using namespace Android::Internal;
|
||||
|
||||
namespace Android {
|
||||
|
||||
const QLatin1String AndroidManifestName("AndroidManifest.xml");
|
||||
const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber");
|
||||
const QLatin1String AndroidDeviceAbis("AndroidDeviceAbis");
|
||||
const QLatin1String ApiLevelKey("AndroidVersion.ApiLevel");
|
||||
const char qtcSignature[] = "This file is generated by QtCreator to be read by androiddeployqt "
|
||||
"and should not be modified by hand.";
|
||||
const char AndroidManifestName[] = "AndroidManifest.xml";
|
||||
const char AndroidDeviceSn[] = "AndroidDeviceSerialNumber";
|
||||
const char AndroidDeviceAbis[] = "AndroidDeviceAbis";
|
||||
const char ApiLevelKey[] = "AndroidVersion.ApiLevel";
|
||||
const char qtcSignature[] = "This file is generated by QtCreator to be read by "
|
||||
"androiddeployqt and should not be modified by hand.";
|
||||
|
||||
static Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager", QtWarningMsg)
|
||||
|
||||
@@ -132,7 +132,8 @@ QString AndroidManager::activityName(const Target *target)
|
||||
QDomDocument doc;
|
||||
if (!openManifest(target, doc))
|
||||
return QString();
|
||||
QDomElement activityElem = doc.documentElement().firstChildElement(QLatin1String("application")).firstChildElement(QLatin1String("activity"));
|
||||
QDomElement activityElem = doc.documentElement().firstChildElement(
|
||||
QLatin1String("application")).firstChildElement(QLatin1String("activity"));
|
||||
return activityElem.attribute(QLatin1String("android:name"));
|
||||
}
|
||||
|
||||
@@ -418,17 +419,18 @@ static QString preferredAbi(const QStringList &appAbis, const Target *target)
|
||||
|
||||
QString AndroidManager::apkDevicePreferredAbi(const Target *target)
|
||||
{
|
||||
auto libsPath = androidBuildDirectory(target).pathAppended("libs");
|
||||
const FilePath libsPath = androidBuildDirectory(target).pathAppended("libs");
|
||||
if (!libsPath.exists()) {
|
||||
if (const ProjectNode *node = currentProjectNode(target))
|
||||
return preferredAbi(node->data(Android::Constants::AndroidAbis).toStringList(),
|
||||
target);
|
||||
}
|
||||
QStringList apkAbis;
|
||||
const auto libsPaths = QDir{libsPath.toString()}.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
for (const auto &abi : libsPaths)
|
||||
if (!QDir{libsPath.pathAppended(abi).toString()}.entryList(QStringList("*.so"), QDir::Files | QDir::NoDotAndDotDot).isEmpty())
|
||||
apkAbis << abi;
|
||||
const FilePaths libsPaths = libsPath.dirEntries(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
for (const FilePath &abiDir : libsPaths) {
|
||||
if (!abiDir.dirEntries(QStringList("*.so"), QDir::Files | QDir::NoDotAndDotDot).isEmpty())
|
||||
apkAbis << abiDir.fileName();
|
||||
}
|
||||
return preferredAbi(apkAbis, target);
|
||||
}
|
||||
|
||||
|
@@ -195,7 +195,9 @@ static FilePath debugServer(bool useLldb, const Target *target)
|
||||
const QString abiNeedle = lldbServerArch2(preferredAbi);
|
||||
|
||||
// The new, built-in LLDB.
|
||||
QDirIterator it(prebuilt.toString(), QDir::Files|QDir::Executable, QDirIterator::Subdirectories);
|
||||
const QDir::Filters dirFilter = HostOsInfo::isWindowsHost() ? QDir::Files
|
||||
: QDir::Files|QDir::Executable;
|
||||
QDirIterator it(prebuilt.toString(), dirFilter, QDirIterator::Subdirectories);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
const QString filePath = it.filePath();
|
||||
|
@@ -928,6 +928,7 @@ public:
|
||||
m_started = false;
|
||||
qCDebug(clangdLogTiming).noquote().nospace() << m_task << ": took " << m_elapsedMs
|
||||
<< " ms in UI thread";
|
||||
m_elapsedMs = 0;
|
||||
}
|
||||
void startSubtask()
|
||||
{
|
||||
|
@@ -168,7 +168,7 @@ static FilePath qmakeFromCMakeCache(const CMakeConfig &config)
|
||||
"project(qmake-probe LANGUAGES NONE)\n"
|
||||
"\n"
|
||||
"# Bypass Qt6's usage of find_dependency, which would require compiler\n"
|
||||
"# and source code probing, which slows things unnecessarily"
|
||||
"# and source code probing, which slows things unnecessarily\n"
|
||||
"file(WRITE \"${CMAKE_SOURCE_DIR}/CMakeFindDependencyMacro.cmake\"\n"
|
||||
"[=["
|
||||
" macro(find_dependency dep)\n"
|
||||
|
@@ -255,15 +255,16 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
|
||||
layout->addLayout(formLayout);
|
||||
layout->addStretch(1);
|
||||
|
||||
const auto toggleEnabled = [=](const bool checked) {
|
||||
chooserLabel->setEnabled(checked);
|
||||
d->clangdChooser.setEnabled(checked);
|
||||
indexingLabel->setEnabled(checked);
|
||||
d->indexingCheckBox.setEnabled(checked);
|
||||
autoIncludeHeadersLabel->setEnabled(checked);
|
||||
d->autoIncludeHeadersCheckBox.setEnabled(checked);
|
||||
d->threadLimitSpinBox.setEnabled(checked);
|
||||
d->versionWarningLabel.setEnabled(checked);
|
||||
static const auto setWidgetsEnabled = [](QLayout *layout, bool enabled, const auto &f) -> void {
|
||||
for (int i = 0; i < layout->count(); ++i) {
|
||||
if (QWidget * const w = layout->itemAt(i)->widget())
|
||||
w->setEnabled(enabled);
|
||||
else if (QLayout * const l = layout->itemAt(i)->layout())
|
||||
f(l, enabled, f);
|
||||
}
|
||||
};
|
||||
const auto toggleEnabled = [formLayout](const bool checked) {
|
||||
setWidgetsEnabled(formLayout, checked, setWidgetsEnabled);
|
||||
};
|
||||
connect(&d->useClangdCheckBox, &QCheckBox::toggled, toggleEnabled);
|
||||
toggleEnabled(d->useClangdCheckBox.isChecked());
|
||||
|
@@ -213,7 +213,15 @@ void LldbEngine::setupEngine()
|
||||
showMessage("STARTING LLDB: " + lldbCmd.toUserOutput());
|
||||
Environment environment = runParameters().debugger.environment;
|
||||
environment.appendOrSet("PYTHONUNBUFFERED", "1"); // avoid flushing problem on macOS
|
||||
if (lldbCmd.path().contains("/ndk-bundle/")) {
|
||||
FilePath androidPythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3");
|
||||
if (HostOsInfo::isAnyUnixHost())
|
||||
androidPythonDir = androidPythonDir.pathAppended("bin");
|
||||
if (androidPythonDir.exists())
|
||||
environment.prependOrSetPath(androidPythonDir.path());
|
||||
}
|
||||
m_lldbProc.setEnvironment(environment);
|
||||
|
||||
if (runParameters().debugger.workingDirectory.isDir())
|
||||
m_lldbProc.setWorkingDirectory(runParameters().debugger.workingDirectory);
|
||||
|
||||
|
@@ -49,12 +49,7 @@ extend_qtc_plugin(Help
|
||||
macwebkithelpviewer.mm
|
||||
)
|
||||
|
||||
set(BUILD_HELPVIEWERBACKEND_QTWEBENGINE_DEFAULT YES)
|
||||
if (Qt6_FOUND)
|
||||
set(BUILD_HELPVIEWERBACKEND_QTWEBENGINE_DEFAULT NO)
|
||||
endif ()
|
||||
|
||||
option(BUILD_HELPVIEWERBACKEND_QTWEBENGINE "Build QtWebEngine based help viewer backend." ${BUILD_HELPVIEWERBACKEND_QTWEBENGINE_DEFAULT})
|
||||
option(BUILD_HELPVIEWERBACKEND_QTWEBENGINE "Build QtWebEngine based help viewer backend." YES)
|
||||
find_package(Qt5 COMPONENTS WebEngineWidgets QUIET)
|
||||
extend_qtc_plugin(Help
|
||||
CONDITION BUILD_HELPVIEWERBACKEND_QTWEBENGINE AND TARGET Qt5::WebEngineWidgets
|
||||
|
@@ -37,7 +37,11 @@
|
||||
#include <QDesktopServices>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
#include <QWebEngineContextMenuRequest>
|
||||
#else
|
||||
#include <QWebEngineContextMenuData>
|
||||
#endif
|
||||
#include <QWebEngineHistory>
|
||||
#include <QWebEngineProfile>
|
||||
#include <QWebEngineSettings>
|
||||
@@ -335,7 +339,11 @@ bool WebView::eventFilter(QObject *src, QEvent *e)
|
||||
|
||||
void WebView::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
QMenu *menu = createStandardContextMenu();
|
||||
#else
|
||||
QMenu *menu = page()->createStandardContextMenu();
|
||||
#endif
|
||||
// insert Open as New Page etc if OpenLinkInThisWindow is also there
|
||||
const QList<QAction*> actions = menu->actions();
|
||||
auto it = std::find(actions.cbegin(), actions.cend(),
|
||||
@@ -344,7 +352,11 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
|
||||
// insert after
|
||||
++it;
|
||||
QAction *before = (it == actions.cend() ? 0 : *it);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
|
||||
QUrl url = lastContextMenuRequest()->linkUrl();
|
||||
#else
|
||||
QUrl url = page()->contextMenuData().linkUrl();
|
||||
#endif
|
||||
if (m_viewer->isActionVisible(HelpViewer::Action::NewPage)) {
|
||||
auto openLink = new QAction(QCoreApplication::translate("HelpViewer",
|
||||
Constants::TR_OPEN_LINK_AS_NEW_PAGE), menu);
|
||||
|
@@ -494,6 +494,11 @@ void JsonWizardFactory::addWizardPath(const FilePath &path)
|
||||
searchPaths().append(path);
|
||||
}
|
||||
|
||||
void JsonWizardFactory::clearWizardPaths()
|
||||
{
|
||||
searchPaths().clear();
|
||||
}
|
||||
|
||||
void JsonWizardFactory::setVerbose(int level)
|
||||
{
|
||||
m_verbose = level;
|
||||
|
@@ -51,6 +51,7 @@ class PROJECTEXPLORER_EXPORT JsonWizardFactory : public Core::IWizardFactory
|
||||
public:
|
||||
// Add search paths for wizard.json files. All subdirs are going to be checked.
|
||||
static void addWizardPath(const Utils::FilePath &path);
|
||||
static void clearWizardPaths();
|
||||
|
||||
// actual interface of the wizard factory:
|
||||
class Generator {
|
||||
|
@@ -4,7 +4,7 @@ if (APPLE)
|
||||
endif()
|
||||
|
||||
add_qtc_plugin(QmlDesigner
|
||||
CONDITION TARGET Qt5::QuickWidgets
|
||||
CONDITION TARGET Qt5::QuickWidgets AND TARGET Qt5::Svg
|
||||
DEPENDS
|
||||
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
|
||||
Qt5::QuickWidgets Qt5::CorePrivate Sqlite Qt5::Xml Qt5::Svg
|
||||
@@ -27,6 +27,7 @@ add_qtc_plugin(QmlDesigner
|
||||
designmodewidget.cpp designmodewidget.h
|
||||
documentmanager.cpp documentmanager.h
|
||||
documentwarningwidget.cpp documentwarningwidget.h
|
||||
cmakegeneratordialog.h cmakegeneratordialog.cpp
|
||||
generateresource.cpp generateresource.h
|
||||
generatecmakelists.cpp generatecmakelists.h
|
||||
openuiqmlfiledialog.cpp openuiqmlfiledialog.h openuiqmlfiledialog.ui
|
||||
@@ -201,6 +202,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
rubberbandselectionmanipulator.cpp rubberbandselectionmanipulator.h
|
||||
scaleitem.cpp scaleitem.h
|
||||
scalemanipulator.cpp scalemanipulator.h
|
||||
seekerslider.cpp seekerslider.h
|
||||
selectionindicator.cpp selectionindicator.h
|
||||
selectionrectangle.cpp selectionrectangle.h
|
||||
selectiontool.cpp selectiontool.h
|
||||
|
154
src/plugins/qmldesigner/cmakegeneratordialog.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Design Tooling
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "cmakegeneratordialog.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QPushButton>
|
||||
#include <QLayout>
|
||||
#include <QLabel>
|
||||
#include <QListView>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace GenerateCmake {
|
||||
|
||||
CmakeGeneratorDialog::CmakeGeneratorDialog(const FilePath &rootDir, const FilePaths &files)
|
||||
: QDialog()
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel);
|
||||
|
||||
auto *okButton = buttons->button(QDialogButtonBox::Ok);
|
||||
okButton->setDefault(true);
|
||||
|
||||
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
model = new CheckableFileListModel(rootDir, files, this);
|
||||
|
||||
QListView *list = new QListView(this);
|
||||
list->setModel(model);
|
||||
|
||||
layout->addWidget(list);
|
||||
layout->addWidget(buttons);
|
||||
}
|
||||
|
||||
FilePaths CmakeGeneratorDialog::getFilePaths()
|
||||
{
|
||||
FilePaths paths;
|
||||
|
||||
QList<CheckableStandardItem*> items = model->checkedItems();
|
||||
for (CheckableStandardItem *item: items) {
|
||||
paths.append(FilePath::fromString(item->text()));
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
CheckableFileListModel::CheckableFileListModel(const FilePath &rootDir, const FilePaths &files, QObject *parent)
|
||||
:QStandardItemModel(parent),
|
||||
rootDir(rootDir)
|
||||
{
|
||||
for (const FilePath &file: files) {
|
||||
appendRow(new CheckableStandardItem(file.toString(), true));
|
||||
}
|
||||
}
|
||||
|
||||
QList<CheckableStandardItem*> CheckableFileListModel::checkedItems() const
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
QList<QStandardItem*> allItems = findItems("*", Qt::MatchWildcard);
|
||||
#else
|
||||
QList<QStandardItem*> allItems = findItems(".*", Qt::MatchRegularExpression);
|
||||
#endif
|
||||
QList<CheckableStandardItem*> checkedItems;
|
||||
for (QStandardItem *standardItem : allItems) {
|
||||
CheckableStandardItem *item = static_cast<CheckableStandardItem*>(standardItem);
|
||||
if (item->isChecked())
|
||||
checkedItems.append(item);
|
||||
}
|
||||
|
||||
return checkedItems;
|
||||
}
|
||||
|
||||
CheckableStandardItem::CheckableStandardItem(const QString &text, bool checked)
|
||||
:QStandardItem(text),
|
||||
checked(checked)
|
||||
{
|
||||
setFlags(flags() |= Qt::ItemIsUserCheckable);
|
||||
}
|
||||
|
||||
void CheckableStandardItem::setChecked(bool checked)
|
||||
{
|
||||
this->checked = checked;
|
||||
}
|
||||
|
||||
bool CheckableStandardItem::isChecked() const
|
||||
{
|
||||
return this->checked;
|
||||
}
|
||||
|
||||
int CheckableStandardItem::type() const
|
||||
{
|
||||
return QStandardItem::UserType + 0x74d4f1;
|
||||
}
|
||||
|
||||
QVariant CheckableFileListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.isValid()) {
|
||||
if (role == Qt::CheckStateRole) {
|
||||
CheckableStandardItem *item = static_cast<CheckableStandardItem*>(QStandardItemModel::item(index.row()));
|
||||
return item->isChecked() ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
else if (role == Qt::DisplayRole) {
|
||||
QVariant data = QStandardItemModel::data(index, role);
|
||||
QString relativePath = data.toString().remove(rootDir.toString());
|
||||
return QVariant(relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
return QStandardItemModel::data(index, role);
|
||||
}
|
||||
|
||||
bool CheckableFileListModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (index.isValid() && role == Qt::CheckStateRole)
|
||||
{
|
||||
CheckableStandardItem *item = static_cast<CheckableStandardItem*>(QStandardItemModel::item(index.row()));
|
||||
item->setChecked(value.value<bool>());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return QStandardItemModel::setData(index, value, role);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
77
src/plugins/qmldesigner/cmakegeneratordialog.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Design Tooling
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef CMAKEGENERATORDIALOG_H
|
||||
#define CMAKEGENERATORDIALOG_H
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace GenerateCmake {
|
||||
|
||||
class CheckableStandardItem : public QStandardItem
|
||||
{
|
||||
public:
|
||||
explicit CheckableStandardItem(const QString &text = QString(), bool checked = false);
|
||||
bool isChecked() const;
|
||||
void setChecked(bool checked);
|
||||
int type() const;
|
||||
|
||||
private:
|
||||
bool checked;
|
||||
};
|
||||
|
||||
class CheckableFileListModel : public QStandardItemModel
|
||||
{
|
||||
public:
|
||||
CheckableFileListModel(const Utils::FilePath &rootDir, const Utils::FilePaths &files, QObject *parent = nullptr);
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
QList<CheckableStandardItem*> checkedItems() const;
|
||||
|
||||
private:
|
||||
Utils::FilePath rootDir;
|
||||
};
|
||||
|
||||
class CmakeGeneratorDialog : public QDialog
|
||||
{
|
||||
public:
|
||||
CmakeGeneratorDialog(const Utils::FilePath &rootDir, const Utils::FilePaths &files);
|
||||
Utils::FilePaths getFilePaths();
|
||||
|
||||
private:
|
||||
CheckableFileListModel *model;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(QmlDesigner::GenerateCmake::CheckableStandardItem)
|
||||
|
||||
#endif // CMAKEGENERATORDIALOG_H
|
@@ -170,6 +170,13 @@ public:
|
||||
visibilityOff, // visibilityOff2
|
||||
visibilityOn,
|
||||
wildcard,
|
||||
wizardsAutomotive,
|
||||
wizardsDesktop,
|
||||
wizardsGeneric,
|
||||
wizardsMcuEmpty,
|
||||
wizardsMcuGraph,
|
||||
wizardsMobile,
|
||||
wizardsUnknown,
|
||||
zoomAll,
|
||||
zoomIn,
|
||||
zoomOut,
|
||||
|
@@ -34,5 +34,15 @@
|
||||
<file>images/select_item@2x.png</file>
|
||||
<file>images/orthographic_camera.png</file>
|
||||
<file>images/orthographic_camera@2x.png</file>
|
||||
</qresource>
|
||||
<file>images/particles_off.png</file>
|
||||
<file>images/particles_off@2x.png</file>
|
||||
<file>images/particles_on.png</file>
|
||||
<file>images/particles_on@2x.png</file>
|
||||
<file>images/particles_play.png</file>
|
||||
<file>images/particles_play@2x.png</file>
|
||||
<file>images/particles_pause.png</file>
|
||||
<file>images/particles_pause@2x.png</file>
|
||||
<file>images/particles_restart.png</file>
|
||||
<file>images/particles_restart@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include <designeractionmanager.h>
|
||||
#include <designersettings.h>
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <viewmanager.h>
|
||||
#include <qmldesignericons.h>
|
||||
#include <designmodecontext.h>
|
||||
@@ -209,6 +210,11 @@ QSize Edit3DView::canvasSize() const
|
||||
return {};
|
||||
}
|
||||
|
||||
void Edit3DView::setSeeker(SeekerSlider *slider)
|
||||
{
|
||||
m_seeker = slider;
|
||||
}
|
||||
|
||||
void Edit3DView::createEdit3DActions()
|
||||
{
|
||||
m_selectionModeAction
|
||||
@@ -272,9 +278,59 @@ void Edit3DView::createEdit3DActions()
|
||||
Icons::EDIT3D_GRID_ON.icon());
|
||||
|
||||
SelectionContextOperation resetTrigger = [this](const SelectionContext &) {
|
||||
m_particlesPlayAction->action()->setEnabled(particlemode);
|
||||
m_particlesRestartAction->action()->setEnabled(particlemode);
|
||||
if (particlemode)
|
||||
m_particlesPlayAction->action()->setChecked(true);
|
||||
if (m_seeker)
|
||||
m_seeker->setEnabled(false);
|
||||
setCurrentStateNode(rootModelNode());
|
||||
resetPuppet();
|
||||
};
|
||||
|
||||
SelectionContextOperation particlesTrigger = [this](const SelectionContext &) {
|
||||
particlemode = !particlemode;
|
||||
m_particlesPlayAction->action()->setEnabled(particlemode);
|
||||
m_particlesRestartAction->action()->setEnabled(particlemode);
|
||||
if (m_seeker)
|
||||
m_seeker->setEnabled(false);
|
||||
QmlDesigner::DesignerSettings::setValue("particleMode", particlemode);
|
||||
setCurrentStateNode(rootModelNode());
|
||||
resetPuppet();
|
||||
};
|
||||
|
||||
SelectionContextOperation particlesRestartTrigger = [this](const SelectionContext &) {
|
||||
m_particlesPlayAction->action()->setChecked(true);
|
||||
if (m_seeker)
|
||||
m_seeker->setEnabled(false);
|
||||
};
|
||||
|
||||
SelectionContextOperation particlesPlayTrigger = [this](const SelectionContext &) {
|
||||
if (m_seeker)
|
||||
m_seeker->setEnabled(!m_particlesPlayAction->action()->isChecked());
|
||||
};
|
||||
|
||||
m_particleViewModeAction
|
||||
= new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_PARTICLE_MODE, View3DActionCommand::Edit3DParticleModeToggle,
|
||||
QCoreApplication::translate("ParticleViewModeAction", "Toggle particle animation On/Off"),
|
||||
QKeySequence(Qt::Key_V), true, false, Icons::EDIT3D_PARTICLE_OFF.icon(),
|
||||
Icons::EDIT3D_PARTICLE_ON.icon(), particlesTrigger);
|
||||
particlemode = false;
|
||||
m_particlesPlayAction
|
||||
= new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_PARTICLES_PLAY, View3DActionCommand::ParticlesPlay,
|
||||
QCoreApplication::translate("ParticlesPlayAction", "Play Particles"),
|
||||
QKeySequence(Qt::Key_W), true, true, Icons::EDIT3D_PARTICLE_PLAY.icon(),
|
||||
Icons::EDIT3D_PARTICLE_PAUSE.icon(), particlesPlayTrigger);
|
||||
m_particlesRestartAction
|
||||
= new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_PARTICLES_RESTART, View3DActionCommand::ParticlesRestart,
|
||||
QCoreApplication::translate("ParticlesRestartAction", "Restart Particles"),
|
||||
QKeySequence(Qt::Key_E), false, false, Icons::EDIT3D_PARTICLE_RESTART.icon(),
|
||||
Icons::EDIT3D_PARTICLE_RESTART.icon(), particlesRestartTrigger);
|
||||
m_particlesPlayAction->action()->setEnabled(particlemode);
|
||||
m_particlesRestartAction->action()->setEnabled(particlemode);
|
||||
m_resetAction
|
||||
= new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_RESET_VIEW, View3DActionCommand::Empty,
|
||||
@@ -296,6 +352,10 @@ void Edit3DView::createEdit3DActions()
|
||||
m_leftActions << m_editLightAction;
|
||||
m_leftActions << m_showGridAction;
|
||||
|
||||
m_rightActions << m_particleViewModeAction;
|
||||
m_rightActions << m_particlesPlayAction;
|
||||
m_rightActions << m_particlesRestartAction;
|
||||
m_rightActions << nullptr;
|
||||
m_rightActions << m_resetAction;
|
||||
}
|
||||
|
||||
@@ -311,7 +371,8 @@ QVector<Edit3DAction *> Edit3DView::rightActions() const
|
||||
|
||||
void Edit3DView::addQuick3DImport()
|
||||
{
|
||||
if (model()) {
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
if (document && !document->inFileComponentModelActive() && model()) {
|
||||
const QList<Import> imports = model()->possibleImports();
|
||||
for (const auto &import : imports) {
|
||||
if (import.url() == "QtQuick3D") {
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "view3dactioncommand.h"
|
||||
#include "seekerslider.h"
|
||||
|
||||
#include <abstractview.h>
|
||||
#include <QtGui/qevent.h>
|
||||
@@ -68,6 +69,7 @@ public:
|
||||
void createEdit3DActions();
|
||||
QVector<Edit3DAction *> leftActions() const;
|
||||
QVector<Edit3DAction *> rightActions() const;
|
||||
void setSeeker(SeekerSlider *slider);
|
||||
|
||||
void addQuick3DImport();
|
||||
|
||||
@@ -90,6 +92,11 @@ private:
|
||||
Edit3DAction *m_editLightAction = nullptr;
|
||||
Edit3DAction *m_showGridAction = nullptr;
|
||||
Edit3DAction *m_resetAction = nullptr;
|
||||
Edit3DAction *m_particleViewModeAction = nullptr;
|
||||
Edit3DAction *m_particlesPlayAction = nullptr;
|
||||
Edit3DAction *m_particlesRestartAction = nullptr;
|
||||
SeekerSlider *m_seeker = nullptr;
|
||||
int particlemode;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -33,6 +33,8 @@
|
||||
#include "qmldesignerplugin.h"
|
||||
#include "qmlvisualnode.h"
|
||||
#include "viewmanager.h"
|
||||
#include <seekerslider.h>
|
||||
#include <nodeinstanceview.h>
|
||||
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
@@ -64,8 +66,11 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
|
||||
fillLayout->setSpacing(0);
|
||||
setLayout(fillLayout);
|
||||
|
||||
SeekerSlider *seeker = new SeekerSlider(this);
|
||||
seeker->setEnabled(false);
|
||||
|
||||
// Initialize toolbar
|
||||
m_toolBox = new ToolBox(this);
|
||||
m_toolBox = new ToolBox(seeker, this);
|
||||
fillLayout->addWidget(m_toolBox.data());
|
||||
|
||||
// Iterate through view actions. A null action indicates a separator and a second null action
|
||||
@@ -100,7 +105,10 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
|
||||
auto separator = new QAction(this);
|
||||
separator->setSeparator(true);
|
||||
addAction(separator);
|
||||
m_toolBox->addLeftSideAction(separator);
|
||||
if (left)
|
||||
m_toolBox->addLeftSideAction(separator);
|
||||
else
|
||||
m_toolBox->addRightSideAction(separator);
|
||||
previousWasSeparator = true;
|
||||
}
|
||||
}
|
||||
@@ -109,6 +117,14 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
|
||||
addActionsToToolBox(view->leftActions(), true);
|
||||
addActionsToToolBox(view->rightActions(), false);
|
||||
|
||||
view->setSeeker(seeker);
|
||||
seeker->setToolTip(QLatin1String("Seek particle system time when paused."));
|
||||
|
||||
QObject::connect(seeker, &SeekerSlider::positionChanged, [this, seeker](){
|
||||
QmlDesignerPlugin::instance()->viewManager().nodeInstanceView()
|
||||
->view3DAction(View3DSeekActionCommand(seeker->position()));
|
||||
});
|
||||
|
||||
// Onboarding label contains instructions for new users how to get 3D content into the project
|
||||
m_onboardingLabel = new QLabel(this);
|
||||
QString labelText =
|
||||
|
After Width: | Height: | Size: 226 B |
After Width: | Height: | Size: 395 B |
After Width: | Height: | Size: 299 B |
After Width: | Height: | Size: 375 B |
After Width: | Height: | Size: 116 B |
After Width: | Height: | Size: 105 B |
After Width: | Height: | Size: 157 B |
After Width: | Height: | Size: 203 B |
After Width: | Height: | Size: 214 B |
After Width: | Height: | Size: 375 B |
BIN
src/plugins/qmldesigner/components/edit3d/images/playpause.png
Normal file
After Width: | Height: | Size: 300 B |
After Width: | Height: | Size: 1.1 KiB |
@@ -42,7 +42,8 @@ SOURCES += formeditoritem.cpp \
|
||||
backgroundaction.cpp \
|
||||
formeditortoolbutton.cpp \
|
||||
formeditorannotationicon.cpp \
|
||||
transitiontool.cpp
|
||||
transitiontool.cpp \
|
||||
seekerslider.cpp
|
||||
|
||||
HEADERS += formeditorscene.h \
|
||||
formeditorwidget.h \
|
||||
@@ -87,6 +88,7 @@ HEADERS += formeditorscene.h \
|
||||
backgroundaction.h \
|
||||
formeditortoolbutton.h \
|
||||
formeditorannotationicon.h \
|
||||
transitiontool.h
|
||||
transitiontool.h \
|
||||
seekerslider.h
|
||||
|
||||
RESOURCES += formeditor.qrc
|
||||
|
@@ -8,5 +8,11 @@
|
||||
<file>snapping_and_anchoring@2x.png</file>
|
||||
<file>annotationsIcon.png</file>
|
||||
<file>annotationsIconActive.png</file>
|
||||
<file>scrubbg.png</file>
|
||||
<file>scrubbg@2x.png</file>
|
||||
<file>scrubhandle-24.png</file>
|
||||
<file>scrubhandle-48.png</file>
|
||||
<file>scrubhandle-disabled-24.png</file>
|
||||
<file>scrubhandle-disabled-48.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -326,13 +326,15 @@ void FormEditorView::propertiesAboutToBeRemoved(const QList<AbstractProperty>& p
|
||||
m_currentTool->itemsAboutToRemoved(removedItems);
|
||||
}
|
||||
|
||||
static inline bool hasNodeSourceParent(const ModelNode &node)
|
||||
static inline bool hasNodeSourceOrNonItemParent(const ModelNode &node)
|
||||
{
|
||||
if (node.hasParentProperty() && node.parentProperty().parentModelNode().isValid()) {
|
||||
ModelNode parent = node.parentProperty().parentModelNode();
|
||||
if (parent.nodeSourceType() != ModelNode::NodeWithoutSource)
|
||||
if (parent.nodeSourceType() != ModelNode::NodeWithoutSource
|
||||
|| !QmlItemNode::isItemOrWindow(parent)) {
|
||||
return true;
|
||||
return hasNodeSourceParent(parent);
|
||||
}
|
||||
return hasNodeSourceOrNonItemParent(parent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -867,7 +869,7 @@ void FormEditorView::addOrRemoveFormEditorItem(const ModelNode &node)
|
||||
removeNodeFromScene(itemNode);
|
||||
}
|
||||
};
|
||||
if (hasNodeSourceParent(node)) {
|
||||
if (hasNodeSourceOrNonItemParent(node)) {
|
||||
removeItemFromScene();
|
||||
} else if (itemNode.isValid()) {
|
||||
if (node.nodeSourceType() == ModelNode::NodeWithoutSource) {
|
||||
|
@@ -139,7 +139,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
||||
addAction(m_rootHeightAction.data());
|
||||
upperActions.append(m_rootHeightAction.data());
|
||||
|
||||
m_toolBox = new ToolBox(this);
|
||||
m_toolBox = new ToolBox(nullptr, this);
|
||||
fillLayout->addWidget(m_toolBox.data());
|
||||
|
||||
m_toolBox->setLeftSideActions(upperActions);
|
||||
@@ -246,14 +246,14 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
||||
};
|
||||
|
||||
m_zoomInAction = new QAction(zoomInIcon, tr("Zoom In"), this);
|
||||
m_zoomInAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_Plus));
|
||||
m_zoomInAction->setShortcut(QKeySequence(QKeySequence::ZoomIn));
|
||||
addAction(m_zoomInAction.data());
|
||||
upperActions.append(m_zoomInAction.data());
|
||||
m_toolBox->addRightSideAction(m_zoomInAction.data());
|
||||
connect(m_zoomInAction.data(), &QAction::triggered, zoomIn);
|
||||
|
||||
m_zoomOutAction = new QAction(zoomOutIcon, tr("Zoom Out"), this);
|
||||
m_zoomOutAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_Minus));
|
||||
m_zoomOutAction->setShortcut(QKeySequence(QKeySequence::ZoomOut));
|
||||
addAction(m_zoomOutAction.data());
|
||||
upperActions.append(m_zoomOutAction.data());
|
||||
m_toolBox->addRightSideAction(m_zoomOutAction.data());
|
||||
@@ -266,7 +266,8 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
||||
connect(m_zoomAction.data(), &ZoomAction::zoomLevelChanged, setZoomLevel);
|
||||
|
||||
m_zoomAllAction = new QAction(zoomAllIcon, tr("Zoom screen to fit all content."), this);
|
||||
m_zoomAllAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_0));
|
||||
m_zoomAllAction->setShortcut(QKeySequence(tr("Ctrl+Alt+0")));
|
||||
|
||||
addAction(m_zoomAllAction.data());
|
||||
upperActions.append(m_zoomAllAction.data());
|
||||
m_toolBox->addRightSideAction(m_zoomAllAction.data());
|
||||
@@ -275,7 +276,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view)
|
||||
m_zoomSelectionAction = new QAction(zoomSelectionIcon,
|
||||
tr("Zoom screen to fit current selection."),
|
||||
this);
|
||||
m_zoomSelectionAction->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_I));
|
||||
m_zoomSelectionAction->setShortcut(QKeySequence(tr("Ctrl+Alt+i")));
|
||||
addAction(m_zoomSelectionAction.data());
|
||||
upperActions.append(m_zoomSelectionAction.data());
|
||||
m_toolBox->addRightSideAction(m_zoomSelectionAction.data());
|
||||
|
BIN
src/plugins/qmldesigner/components/formeditor/scrubbg.png
Normal file
After Width: | Height: | Size: 152 B |
BIN
src/plugins/qmldesigner/components/formeditor/scrubbg@2x.png
Normal file
After Width: | Height: | Size: 166 B |
BIN
src/plugins/qmldesigner/components/formeditor/scrubhandle-24.png
Normal file
After Width: | Height: | Size: 362 B |
BIN
src/plugins/qmldesigner/components/formeditor/scrubhandle-48.png
Normal file
After Width: | Height: | Size: 695 B |
After Width: | Height: | Size: 438 B |
After Width: | Height: | Size: 829 B |
138
src/plugins/qmldesigner/components/formeditor/seekerslider.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "seekerslider.h"
|
||||
#include <utils/icon.h>
|
||||
|
||||
#include <QStyleOption>
|
||||
#include <QSlider>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
SeekerSlider::SeekerSlider(QWidget *parentWidget)
|
||||
: QWidget(parentWidget),
|
||||
m_bgIcon(QLatin1String(":/icon/layout/scrubbg.png"))
|
||||
{
|
||||
m_handleIcon.addFile(QLatin1String(":/icon/layout/scrubhandle-24.png"), QSize(24, 24));
|
||||
m_handleIcon.addFile(QLatin1String(":/icon/layout/scrubhandle-48.png"), QSize(48, 48));
|
||||
m_handleIcon.addFile(QLatin1String(":/icon/layout/scrubhandle-disabled-24.png"), QSize(24, 24), QIcon::Disabled);
|
||||
m_handleIcon.addFile(QLatin1String(":/icon/layout/scrubhandle-disabled-48.png"), QSize(48, 48), QIcon::Disabled);
|
||||
const Utils::Icon bg({{":/icon/layout/scrubbg.png", Utils::Theme::IconsBaseColor}});
|
||||
m_bgWidth = bg.pixmap().width();
|
||||
m_bgHeight = bg.pixmap().height();
|
||||
m_handleWidth = m_bgHeight;
|
||||
m_handleHeight = m_bgHeight;
|
||||
int width = m_bgWidth + m_handleWidth * 2;
|
||||
m_sliderHalfWidth = m_bgWidth / 2;
|
||||
setMinimumWidth(width);
|
||||
setMaximumWidth(width);
|
||||
setProperty("panelwidget", true);
|
||||
setProperty("panelwidget_singlerow", true);
|
||||
}
|
||||
|
||||
void SeekerSlider::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
QPainter painter(this);
|
||||
{
|
||||
QStyleOptionToolBar option;
|
||||
option.rect = rect();
|
||||
option.state = QStyle::State_Horizontal;
|
||||
style()->drawControl(QStyle::CE_ToolBar, &option, &painter, this);
|
||||
}
|
||||
|
||||
int x = rect().width() / 2;
|
||||
int y = rect().height() / 2;
|
||||
|
||||
const QPixmap bg = m_bgIcon.pixmap(QSize(m_bgWidth, m_bgHeight), isEnabled() ? QIcon::Normal : QIcon::Disabled, QIcon::On);
|
||||
painter.drawPixmap(x - m_bgWidth / 2, y - m_bgHeight / 2, bg);
|
||||
|
||||
if (m_moving) {
|
||||
const QPixmap handle = m_handleIcon.pixmap(QSize(m_handleWidth, m_handleHeight), QIcon::Active, QIcon::On);
|
||||
painter.drawPixmap(x - m_handleWidth / 2 + m_sliderPos, y - m_handleHeight / 2, handle);
|
||||
} else {
|
||||
const QPixmap handle = m_handleIcon.pixmap(QSize(m_handleWidth, m_handleHeight), isEnabled() ? QIcon::Normal : QIcon::Disabled, QIcon::On);
|
||||
painter.drawPixmap(x - m_handleWidth / 2, y - m_handleHeight / 2, handle);
|
||||
}
|
||||
}
|
||||
|
||||
void SeekerSlider::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() != Qt::LeftButton) {
|
||||
QWidget::mousePressEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
int x = rect().width() / 2;
|
||||
int y = rect().height() / 2;
|
||||
auto pos = event->localPos();
|
||||
if (pos.x() >= x - m_handleWidth / 2 && pos.x() <= x + m_handleWidth / 2
|
||||
&& pos.y() >= y - m_handleHeight / 2 && pos.y() <= y + m_handleHeight / 2) {
|
||||
m_moving = true;
|
||||
m_startPos = pos.x();
|
||||
}
|
||||
}
|
||||
|
||||
void SeekerSlider::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!m_moving) {
|
||||
QWidget::mouseMoveEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
auto pos = event->localPos();
|
||||
int delta = pos.x() - m_startPos;
|
||||
m_sliderPos = qBound(-m_sliderHalfWidth, delta, m_sliderHalfWidth);
|
||||
delta = m_maxPosition * m_sliderPos / m_sliderHalfWidth;
|
||||
if (delta != m_position) {
|
||||
m_position = delta;
|
||||
Q_EMIT positionChanged();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void SeekerSlider::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (!m_moving) {
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
m_moving = false;
|
||||
m_position = 0;
|
||||
m_startPos = 0;
|
||||
m_sliderPos = 0;
|
||||
Q_EMIT positionChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
int SeekerSlider::position() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
73
src/plugins/qmldesigner/components/formeditor/seekerslider.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QMouseEvent>
|
||||
#include <QIcon>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class SeekerSlider : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SeekerSlider(QWidget *parentWidget);
|
||||
int position() const;
|
||||
int maxPosition() const
|
||||
{
|
||||
return m_maxPosition;
|
||||
}
|
||||
|
||||
void setMaxPosition(int pos)
|
||||
{
|
||||
m_maxPosition = qMax(0, pos);
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void positionChanged();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
int m_position = 0;
|
||||
int m_startPos = 0;
|
||||
int m_sliderPos = 0;
|
||||
int m_sliderHalfWidth = 0;
|
||||
int m_maxPosition = 30;
|
||||
bool m_moving = false;
|
||||
int m_bgWidth;
|
||||
int m_bgHeight;
|
||||
int m_handleWidth;
|
||||
int m_handleHeight;
|
||||
QIcon m_bgIcon;
|
||||
QIcon m_handleIcon;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -33,10 +33,11 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
ToolBox::ToolBox(QWidget *parentWidget)
|
||||
ToolBox::ToolBox(SeekerSlider *seeker, QWidget *parentWidget)
|
||||
: Utils::StyledBar(parentWidget),
|
||||
m_leftToolBar(new QToolBar(QLatin1String("LeftSidebar"), this)),
|
||||
m_rightToolBar(new QToolBar(QLatin1String("RightSidebar"), this))
|
||||
m_rightToolBar(new QToolBar(QLatin1String("RightSidebar"), this)),
|
||||
m_seeker(seeker)
|
||||
{
|
||||
m_leftToolBar->setFloatable(true);
|
||||
m_leftToolBar->setMovable(true);
|
||||
@@ -62,6 +63,8 @@ ToolBox::ToolBox(QWidget *parentWidget)
|
||||
m_rightToolBar->setOrientation(Qt::Horizontal);
|
||||
horizontalLayout->addWidget(m_leftToolBar);
|
||||
horizontalLayout->addWidget(stretchToolbar);
|
||||
if (seeker)
|
||||
horizontalLayout->addWidget(m_seeker);
|
||||
horizontalLayout->addWidget(m_rightToolBar);
|
||||
}
|
||||
|
||||
@@ -94,4 +97,9 @@ QList<QAction*> ToolBox::actions() const
|
||||
return m_leftToolBar->actions() + m_rightToolBar->actions();
|
||||
}
|
||||
|
||||
SeekerSlider *ToolBox::seeker() const
|
||||
{
|
||||
return m_seeker;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <utils/styledbar.h>
|
||||
#include <seekerslider.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QToolBar;
|
||||
@@ -37,16 +38,18 @@ namespace QmlDesigner {
|
||||
class ToolBox : public Utils::StyledBar
|
||||
{
|
||||
public:
|
||||
ToolBox(QWidget *parentWidget);
|
||||
ToolBox(SeekerSlider *seeker, QWidget *parentWidget);
|
||||
void setLeftSideActions(const QList<QAction*> &actions);
|
||||
void setRightSideActions(const QList<QAction*> &actions);
|
||||
void addLeftSideAction(QAction *action);
|
||||
void addRightSideAction(QAction *action);
|
||||
QList<QAction*> actions() const;
|
||||
SeekerSlider *seeker() const;
|
||||
|
||||
private:
|
||||
QToolBar *m_leftToolBar;
|
||||
QToolBar *m_rightToolBar;
|
||||
SeekerSlider *m_seeker;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -210,6 +210,11 @@ bool DesignDocument::pasteSVG()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DesignDocument::inFileComponentModelActive() const
|
||||
{
|
||||
return !m_inFileComponentModel.isNull();
|
||||
}
|
||||
|
||||
QList<DocumentMessage> DesignDocument::qmlParseWarnings() const
|
||||
{
|
||||
return m_rewriterView->warnings();
|
||||
|
@@ -76,6 +76,7 @@ public:
|
||||
|
||||
Model *currentModel() const;
|
||||
Model *documentModel() const;
|
||||
bool inFileComponentModelActive() const;
|
||||
|
||||
void contextHelp(const Core::IContext::HelpCallback &callback) const;
|
||||
QList<DocumentMessage> qmlParseWarnings() const;
|
||||
|
@@ -354,7 +354,8 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
||||
beginResetModel();
|
||||
clearSections();
|
||||
|
||||
Utils::FilePath qmlFileName = QmlDesignerPlugin::instance()->currentDesignDocument()->fileName();
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
Utils::FilePath qmlFileName = document->fileName();
|
||||
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::projectForFile(qmlFileName);
|
||||
QString projectName = project ? project->displayName() : "";
|
||||
|
||||
@@ -398,6 +399,7 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
||||
itemLibImport->setImportExpanded(loadExpandedState(itemLibImport->importUrl()));
|
||||
}
|
||||
|
||||
const bool blockNewImports = document->inFileComponentModelActive();
|
||||
const QList<ItemLibraryEntry> itemLibEntries = itemLibraryInfo->entries();
|
||||
for (const ItemLibraryEntry &entry : itemLibEntries) {
|
||||
NodeMetaInfo metaInfo = model->metaInfo(entry.typeName());
|
||||
@@ -429,7 +431,7 @@ void ItemLibraryModel::update(ItemLibraryInfo *itemLibraryInfo, Model *model)
|
||||
bool hasImport = model->hasImport(import, true, true);
|
||||
bool isImportPossible = false;
|
||||
if (!hasImport)
|
||||
isImportPossible = model->isImportPossible(import, true, true);
|
||||
isImportPossible = !blockNewImports && model->isImportPossible(import, true, true);
|
||||
bool isUsable = (valid && (isItem || forceVisibility))
|
||||
&& (entry.requiredImport().isEmpty() || hasImport);
|
||||
if (!blocked && (isUsable || isImportPossible)) {
|
||||
|
@@ -400,6 +400,17 @@ void ItemLibraryWidget::setModel(Model *model)
|
||||
return;
|
||||
|
||||
setItemLibraryInfo(model->metaInfo().itemLibraryInfo());
|
||||
|
||||
if (DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument()) {
|
||||
const bool subCompEditMode = document->inFileComponentModelActive();
|
||||
if (m_subCompEditMode != subCompEditMode) {
|
||||
m_subCompEditMode = subCompEditMode;
|
||||
// Switch out of module add panel if it's active
|
||||
if (m_subCompEditMode && m_stackedWidget->currentIndex() == 2)
|
||||
m_stackedWidget->setCurrentIndex(0);
|
||||
emit subCompEditModeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::handleTabChanged(int index)
|
||||
@@ -545,6 +556,11 @@ QPair<QString, QByteArray> ItemLibraryWidget::getAssetTypeAndData(const QString
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ItemLibraryWidget::subCompEditMode() const
|
||||
{
|
||||
return m_subCompEditMode;
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::setFlowMode(bool b)
|
||||
{
|
||||
m_itemLibraryModel->setFlowMode(b);
|
||||
|
@@ -71,6 +71,8 @@ class ItemLibraryWidget : public QFrame
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_PROPERTY(bool subCompEditMode READ subCompEditMode NOTIFY subCompEditModeChanged)
|
||||
|
||||
ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
AsynchronousImageCache &asynchronousFontImageCache,
|
||||
SynchronousImageCache &synchronousFontImageCache);
|
||||
@@ -94,6 +96,8 @@ public:
|
||||
|
||||
inline static bool isHorizontalLayout = false;
|
||||
|
||||
bool subCompEditMode() const;
|
||||
|
||||
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos);
|
||||
Q_INVOKABLE void startDragAsset(const QStringList &assetPaths, const QPointF &mousePos);
|
||||
Q_INVOKABLE void removeImport(const QString &importUrl);
|
||||
@@ -108,7 +112,8 @@ public:
|
||||
Q_INVOKABLE QSet<QString> supportedDropSuffixes();
|
||||
|
||||
signals:
|
||||
void itemActivated(const QString& itemName);
|
||||
void itemActivated(const QString &itemName);
|
||||
void subCompEditModeChanged();
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
@@ -152,6 +157,7 @@ private:
|
||||
bool m_updateRetry = false;
|
||||
QString m_filterText;
|
||||
QPoint m_dragStartPoint;
|
||||
bool m_subCompEditMode = false;
|
||||
|
||||
inline static int HORIZONTAL_LAYOUT_WIDTH_LIMIT = 600;
|
||||
};
|
||||
|
@@ -551,20 +551,24 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData,
|
||||
QList<ModelNode> addedNodes;
|
||||
ModelNode currNode;
|
||||
|
||||
QSet<QString> neededImports;
|
||||
for (const QString &assetPath : assetsPaths) {
|
||||
QString assetType = ItemLibraryWidget::getAssetTypeAndData(assetPath).first;
|
||||
if (assetType == "application/vnd.bauhaus.libraryresource.shader")
|
||||
neededImports.insert("QtQuick3D");
|
||||
else if (assetType == "application/vnd.bauhaus.libraryresource.sound")
|
||||
neededImports.insert("QtMultimedia");
|
||||
// Adding required imports is skipped if we are editing in-file subcomponent
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
if (document && !document->inFileComponentModelActive()) {
|
||||
QSet<QString> neededImports;
|
||||
for (const QString &assetPath : assetsPaths) {
|
||||
QString assetType = ItemLibraryWidget::getAssetTypeAndData(assetPath).first;
|
||||
if (assetType == "application/vnd.bauhaus.libraryresource.shader")
|
||||
neededImports.insert("QtQuick3D");
|
||||
else if (assetType == "application/vnd.bauhaus.libraryresource.sound")
|
||||
neededImports.insert("QtMultimedia");
|
||||
|
||||
if (neededImports.size() == 2)
|
||||
break;
|
||||
};
|
||||
if (neededImports.size() == 2)
|
||||
break;
|
||||
};
|
||||
|
||||
for (const QString &import : std::as_const(neededImports))
|
||||
addImport(import);
|
||||
for (const QString &import : std::as_const(neededImports))
|
||||
addImport(import);
|
||||
}
|
||||
|
||||
m_view->executeInTransaction("NavigatorTreeModel::dropMimeData", [&] {
|
||||
for (const QString &assetPath : assetsPaths) {
|
||||
|
Before Width: | Height: | Size: 97 B After Width: | Height: | Size: 113 B |
Before Width: | Height: | Size: 110 B After Width: | Height: | Size: 118 B |
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 121 B |
Before Width: | Height: | Size: 107 B After Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 122 B After Width: | Height: | Size: 103 B |
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 130 B |
Before Width: | Height: | Size: 92 B After Width: | Height: | Size: 115 B |
Before Width: | Height: | Size: 110 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 126 B |