Merge "Merge remote-tracking branch 'origin/4.15'"
@@ -844,39 +844,7 @@ class Dumper(DumperBase):
|
|||||||
if typeobj is not None:
|
if typeobj is not None:
|
||||||
return typeobj
|
return typeobj
|
||||||
|
|
||||||
return self.lookupNativeTypeInAllModules(name)
|
return lldb.SBType()
|
||||||
|
|
||||||
def lookupNativeTypeInAllModules(self, name):
|
|
||||||
needle = self.canonicalTypeName(name)
|
|
||||||
#DumperBase.warn('NEEDLE: %s ' % needle)
|
|
||||||
DumperBase.warn('Searching for type %s across all target modules, this could be very slow' % name)
|
|
||||||
for i in range(self.target.GetNumModules()):
|
|
||||||
module = self.target.GetModuleAtIndex(i)
|
|
||||||
# SBModule.GetType is new somewhere after early 300.x
|
|
||||||
# So this may fail.
|
|
||||||
for t in module.GetTypes():
|
|
||||||
n = self.canonicalTypeName(t.GetName())
|
|
||||||
#DumperBase.warn('N: %s' % n)
|
|
||||||
if n == needle:
|
|
||||||
#DumperBase.warn('FOUND TYPE DIRECT 2: %s ' % t)
|
|
||||||
self.typeCache[name] = t
|
|
||||||
return t
|
|
||||||
if n == needle + '*':
|
|
||||||
res = t.GetPointeeType()
|
|
||||||
self.typeCache[name] = res
|
|
||||||
x = self.fromNativeType(res) # Register under both names
|
|
||||||
self.registerTypeAlias(x.typeId, name)
|
|
||||||
#DumperBase.warn('FOUND TYPE BY POINTER: %s ' % res.name)
|
|
||||||
return res
|
|
||||||
if n == needle + '&':
|
|
||||||
res = t.GetDereferencedType().GetUnqualifiedType()
|
|
||||||
self.typeCache[name] = res
|
|
||||||
x = self.fromNativeType(res) # Register under both names
|
|
||||||
self.registerTypeAlias(x.typeId, name)
|
|
||||||
#DumperBase.warn('FOUND TYPE BY REFERENCE: %s ' % res.name)
|
|
||||||
return res
|
|
||||||
#DumperBase.warn('NOT FOUND: %s ' % needle)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def setupInferior(self, args):
|
def setupInferior(self, args):
|
||||||
""" Set up SBTarget instance """
|
""" Set up SBTarget instance """
|
||||||
@@ -904,14 +872,6 @@ class Dumper(DumperBase):
|
|||||||
except: # Could have been deleted in the mean time.
|
except: # Could have been deleted in the mean time.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.ignoreStops = 0
|
|
||||||
if platform.system() == 'Linux':
|
|
||||||
if self.startMode_ == DebuggerStartMode.AttachCore:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
if self.useTerminal_:
|
|
||||||
self.ignoreStops = 1
|
|
||||||
|
|
||||||
if self.platform_:
|
if self.platform_:
|
||||||
self.debugger.SetCurrentPlatform(self.platform_)
|
self.debugger.SetCurrentPlatform(self.platform_)
|
||||||
# sysroot has to be set *after* the platform
|
# sysroot has to be set *after* the platform
|
||||||
@@ -1450,9 +1410,6 @@ class Dumper(DumperBase):
|
|||||||
if self.isInterrupting_:
|
if self.isInterrupting_:
|
||||||
self.isInterrupting_ = False
|
self.isInterrupting_ = False
|
||||||
self.reportState("inferiorstopok")
|
self.reportState("inferiorstopok")
|
||||||
elif self.ignoreStops > 0:
|
|
||||||
self.ignoreStops -= 1
|
|
||||||
self.process.Continue()
|
|
||||||
else:
|
else:
|
||||||
self.reportState("stopped")
|
self.reportState("stopped")
|
||||||
else:
|
else:
|
||||||
@@ -2086,10 +2043,6 @@ class SummaryDumper(Dumper, LogMixin):
|
|||||||
def report(self, stuff):
|
def report(self, stuff):
|
||||||
return # Don't mess up lldb output
|
return # Don't mess up lldb output
|
||||||
|
|
||||||
def lookupNativeTypeInAllModules(self, name):
|
|
||||||
self.warn('Failed to resolve type %s' % name)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def dump_summary(self, valobj, expanded=False):
|
def dump_summary(self, valobj, expanded=False):
|
||||||
try:
|
try:
|
||||||
from pygdbmi import gdbmiparser
|
from pygdbmi import gdbmiparser
|
||||||
|
@@ -30,8 +30,6 @@ import QtQuickDesignerTheme 1.0
|
|||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
signal addImport(int index)
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: header
|
id: header
|
||||||
text: qsTr("Select a Module to Add")
|
text: qsTr("Select a Module to Add")
|
||||||
@@ -78,7 +76,7 @@ Column {
|
|||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: addImport(index)
|
onClicked: rootView.handleAddImport(index)
|
||||||
enabled: !isSeparator
|
enabled: !isSeparator
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -87,6 +87,12 @@ ScrollView {
|
|||||||
itemContextMenu.close()
|
itemContextMenu.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onContentHeightChanged: {
|
||||||
|
var maxPosition = Math.max(contentHeight - height, 0)
|
||||||
|
if (contentY > maxPosition)
|
||||||
|
contentY = maxPosition
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: styleConstants
|
id: styleConstants
|
||||||
property int textWidth: 58
|
property int textWidth: 58
|
||||||
|
@@ -26,17 +26,14 @@
|
|||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls 2.15
|
||||||
import QtQuickDesignerTheme 1.0
|
import QtQuickDesignerTheme 1.0
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
width: 200
|
width: 200
|
||||||
height: 75
|
height: 75
|
||||||
|
|
||||||
signal tabChanged(int index)
|
|
||||||
signal filterChanged(string filterText)
|
|
||||||
signal addModuleClicked()
|
|
||||||
signal addAssetClicked()
|
|
||||||
|
|
||||||
function setTab(index)
|
function setTab(index)
|
||||||
{
|
{
|
||||||
tabBar.setCurrentIndex(index);
|
tabBar.setCurrentIndex(index);
|
||||||
@@ -69,46 +66,60 @@ Item {
|
|||||||
{title: qsTr("Assets"), addToolTip: qsTr("Add new assets to project.")}]
|
{title: qsTr("Assets"), addToolTip: qsTr("Add new assets to project.")}]
|
||||||
|
|
||||||
TabButton {
|
TabButton {
|
||||||
contentItem: Text { // TabButton text
|
topPadding: 4
|
||||||
text: modelData.title
|
bottomPadding: 4
|
||||||
font.pixelSize: 13
|
contentItem: Item {
|
||||||
font.bold: true
|
implicitHeight: plusButton.height
|
||||||
color: tabBar.currentIndex === index ? "#0094ce" : "#dadada"
|
|
||||||
anchors.bottomMargin: 2
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
|
||||||
verticalAlignment: Text.AlignBottom
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
|
|
||||||
background: Item { // TabButton background
|
Text { // TabButton text
|
||||||
Rectangle { // + button
|
text: modelData.title
|
||||||
anchors.right: parent.right
|
font.pixelSize: 13
|
||||||
|
font.bold: true
|
||||||
|
color: tabBar.currentIndex === index ? "#0094ce" : "#dadada"
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.rightMargin: 2
|
anchors.right: plusButton.left
|
||||||
anchors.bottomMargin: 2
|
anchors.bottomMargin: 2
|
||||||
width: img.width + 10
|
horizontalAlignment: Text.AlignLeft
|
||||||
height: img.height + 10
|
verticalAlignment: Text.AlignBottom
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle { // + button
|
||||||
|
id: plusButton
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 1
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
color: mouseArea.containsMouse ? "#353535" : "#262626"
|
color: mouseArea.containsMouse ? "#353535" : "#262626"
|
||||||
|
|
||||||
ToolTip.delay: 500
|
ToolTip.delay: 500
|
||||||
ToolTip.text: modelData.addToolTip
|
ToolTip.text: modelData.addToolTip
|
||||||
ToolTip.visible: mouseArea.containsMouse
|
ToolTip.visible: mouseArea.containsMouse
|
||||||
|
|
||||||
Image {
|
Label { // + sign
|
||||||
id: img
|
text: StudioTheme.Constants.plus
|
||||||
source: tabBar.currentIndex === index ? "../images/add.png"
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
: "../images/add_unselected.png"
|
font.pixelSize: StudioTheme.Values.myIconFontSize
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
color: tabBar.currentIndex === index ? "#0094ce" : "#a8a8a8"
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: index == 0 ? addModuleClicked() : addAssetClicked()
|
onClicked: index == 0 ? rootView.handleAddModule()
|
||||||
|
: rootView.handleAddAsset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Item { // TabButton background
|
||||||
Rectangle { // bottom strip
|
Rectangle { // bottom strip
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -117,7 +128,7 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClicked: tabChanged(index)
|
onClicked: rootView.handleTabChanged(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,16 +149,30 @@ Item {
|
|||||||
anchors.rightMargin: 5
|
anchors.rightMargin: 5
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
|
|
||||||
onTextChanged: filterChanged(text)
|
onTextChanged: rootView.handleSearchfilterChanged(text)
|
||||||
|
|
||||||
Image { // clear text button
|
Rectangle { // x button
|
||||||
source: "../images/x.png"
|
width: 15
|
||||||
|
height: 15
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 5
|
anchors.rightMargin: 5
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: searchFilterText.text !== ""
|
visible: searchFilterText.text !== ""
|
||||||
|
color: xMouseArea.containsMouse ? "#353535" : "transparent"
|
||||||
|
|
||||||
|
Label {
|
||||||
|
text: StudioTheme.Constants.closeCross
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
font.pixelSize: StudioTheme.Values.myIconFontSize
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: "#dadada"
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
id: xMouseArea
|
||||||
|
hoverEnabled: true
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: searchFilterText.text = ""
|
onClicked: searchFilterText.text = ""
|
||||||
}
|
}
|
@@ -716,7 +716,7 @@ StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return StringType{"", 0};
|
return {};
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@@ -349,7 +349,7 @@ public:
|
|||||||
bindValues(queryValues...);
|
bindValues(queryValues...);
|
||||||
|
|
||||||
while (BaseStatement::next())
|
while (BaseStatement::next())
|
||||||
pushBackToContainer<ResultTypeCount>(container);
|
emplaceBackValues<ResultTypeCount>(container);
|
||||||
|
|
||||||
resetter.reset();
|
resetter.reset();
|
||||||
}
|
}
|
||||||
@@ -448,19 +448,6 @@ private:
|
|||||||
return callCallable(callable, std::make_integer_sequence<int, ResultTypeCount>{});
|
return callCallable(callable, std::make_integer_sequence<int, ResultTypeCount>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container, int... ColumnIndices>
|
|
||||||
void pushBackToContainer(Container &container, std::integer_sequence<int, ColumnIndices...>)
|
|
||||||
{
|
|
||||||
using Type = typename Container::value_type;
|
|
||||||
container.push_back(Type(ValueGetter(*this, ColumnIndices)...));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int ResultTypeCount, typename Container>
|
|
||||||
void pushBackToContainer(Container &container)
|
|
||||||
{
|
|
||||||
pushBackToContainer(container, std::make_integer_sequence<int, ResultTypeCount>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
void bindValuesByIndex(int index, const ValueType &value)
|
void bindValuesByIndex(int index, const ValueType &value)
|
||||||
{
|
{
|
||||||
|
@@ -611,6 +611,18 @@ bool ConsoleProcess::start()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utils::ConsoleProcess::kickoffProcess()
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// Not used.
|
||||||
|
#else
|
||||||
|
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
|
||||||
|
d->m_stubSocket->write("c", 1);
|
||||||
|
d->m_stubSocket->flush();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void ConsoleProcess::interruptProcess()
|
void ConsoleProcess::interruptProcess()
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
@@ -90,6 +90,7 @@ public:
|
|||||||
bool isRunning() const; // This reflects the state of the console+stub
|
bool isRunning() const; // This reflects the state of the console+stub
|
||||||
qint64 applicationPID() const;
|
qint64 applicationPID() const;
|
||||||
|
|
||||||
|
void kickoffProcess();
|
||||||
void interruptProcess();
|
void interruptProcess();
|
||||||
void killProcess();
|
void killProcess();
|
||||||
void killStub();
|
void killStub();
|
||||||
|
@@ -57,6 +57,7 @@ extern char **environ;
|
|||||||
static int qtcFd;
|
static int qtcFd;
|
||||||
static char *sleepMsg;
|
static char *sleepMsg;
|
||||||
static int chldPipe[2];
|
static int chldPipe[2];
|
||||||
|
static int blockingPipe[2];
|
||||||
static int isDebug;
|
static int isDebug;
|
||||||
static volatile int isDetached;
|
static volatile int isDetached;
|
||||||
static volatile int chldPid;
|
static volatile int chldPid;
|
||||||
@@ -236,10 +237,21 @@ int main(int argc, char *argv[])
|
|||||||
perror("Cannot create status pipe");
|
perror("Cannot create status pipe");
|
||||||
doExit(3);
|
doExit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The debugged program is not supposed to inherit these handles. But we cannot
|
/* The debugged program is not supposed to inherit these handles. But we cannot
|
||||||
* close the writing end before calling exec(). Just handle both ends the same way ... */
|
* close the writing end before calling exec(). Just handle both ends the same way ... */
|
||||||
fcntl(chldPipe[0], F_SETFD, FD_CLOEXEC);
|
fcntl(chldPipe[0], F_SETFD, FD_CLOEXEC);
|
||||||
fcntl(chldPipe[1], F_SETFD, FD_CLOEXEC);
|
fcntl(chldPipe[1], F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
if (isDebug) {
|
||||||
|
/* Create execution start notification pipe. The child waits on this until
|
||||||
|
the parent writes to it, triggered by an 'c' message from Creator */
|
||||||
|
if (pipe(blockingPipe)) {
|
||||||
|
perror("Cannot create blocking pipe");
|
||||||
|
doExit(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch ((chldPid = fork())) {
|
switch ((chldPid = fork())) {
|
||||||
case -1:
|
case -1:
|
||||||
perror("Cannot fork child process");
|
perror("Cannot fork child process");
|
||||||
@@ -262,9 +274,15 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
prctl(PR_SET_PTRACER, atoi(argv[ArgPid]));
|
prctl(PR_SET_PTRACER, atoi(argv[ArgPid]));
|
||||||
#endif
|
#endif
|
||||||
/* Stop the child to allow the debugger to attach */
|
/* Block to allow the debugger to attach */
|
||||||
if (isDebug)
|
if (isDebug) {
|
||||||
kill(chldPid, SIGSTOP);
|
char buf;
|
||||||
|
int res = read(blockingPipe[0], &buf, 1);
|
||||||
|
if (res < 0)
|
||||||
|
perror("Could not read from blocking pipe");
|
||||||
|
close(blockingPipe[0]);
|
||||||
|
close(blockingPipe[1]);
|
||||||
|
}
|
||||||
|
|
||||||
if (env)
|
if (env)
|
||||||
environ = env;
|
environ = env;
|
||||||
@@ -296,6 +314,7 @@ int main(int argc, char *argv[])
|
|||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
|
char c = 'i';
|
||||||
for (i = 0; i < nbytes; ++i) {
|
for (i = 0; i < nbytes; ++i) {
|
||||||
switch (buffer[i]) {
|
switch (buffer[i]) {
|
||||||
case 'k':
|
case 'k':
|
||||||
@@ -305,13 +324,12 @@ int main(int argc, char *argv[])
|
|||||||
kill(chldPid, SIGKILL);
|
kill(chldPid, SIGKILL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'c': {
|
||||||
if (chldPid > 0) {
|
int res = write(blockingPipe[1], &c, 1);
|
||||||
int res = kill(chldPid, SIGINT);
|
if (res < 0)
|
||||||
if (res)
|
perror("Could not write to blocking pipe");
|
||||||
perror("Stub could not interrupt inferior");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 'd':
|
case 'd':
|
||||||
isDetached = 1;
|
isDetached = 1;
|
||||||
break;
|
break;
|
||||||
|
@@ -64,8 +64,8 @@ template<uint Size>
|
|||||||
class BasicSmallString
|
class BasicSmallString
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using iterator = Internal::SmallStringIterator<std::random_access_iterator_tag, char>;
|
using iterator = SmallStringView::iterator;
|
||||||
using const_iterator = Internal::SmallStringIterator<std::random_access_iterator_tag, const char>;
|
using const_iterator = SmallStringView::const_iterator;
|
||||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
@@ -113,8 +113,15 @@ public:
|
|||||||
|
|
||||||
BasicSmallString(const char *string, size_type size)
|
BasicSmallString(const char *string, size_type size)
|
||||||
: BasicSmallString(string, size, size)
|
: BasicSmallString(string, size, size)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
explicit BasicSmallString(const_iterator begin, const_iterator end)
|
||||||
|
: BasicSmallString(SmallStringView{begin, end})
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit BasicSmallString(iterator begin, iterator end)
|
||||||
|
: BasicSmallString(SmallStringView{begin, end})
|
||||||
|
{}
|
||||||
|
|
||||||
template<typename Type, typename = std::enable_if_t<std::is_pointer<Type>::value>>
|
template<typename Type, typename = std::enable_if_t<std::is_pointer<Type>::value>>
|
||||||
BasicSmallString(Type characterPointer)
|
BasicSmallString(Type characterPointer)
|
||||||
|
@@ -49,6 +49,7 @@ class SmallStringView
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using const_iterator = Internal::SmallStringIterator<std::random_access_iterator_tag, const char>;
|
using const_iterator = Internal::SmallStringIterator<std::random_access_iterator_tag, const char>;
|
||||||
|
using iterator = Internal::SmallStringIterator<std::random_access_iterator_tag, char>;
|
||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
using size_type = std::size_t;
|
using size_type = std::size_t;
|
||||||
|
|
||||||
@@ -62,14 +63,22 @@ public:
|
|||||||
constexpr SmallStringView(const char *const string, const size_type size) noexcept
|
constexpr SmallStringView(const char *const string, const size_type size) noexcept
|
||||||
: m_pointer(string)
|
: m_pointer(string)
|
||||||
, m_size(size)
|
, m_size(size)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
constexpr SmallStringView(const const_iterator begin, const const_iterator end) noexcept
|
constexpr SmallStringView(const char *const begin, const char *const end) noexcept
|
||||||
|
: m_pointer(begin)
|
||||||
|
, m_size(static_cast<std::size_t>(std::distance(begin, end)))
|
||||||
|
{}
|
||||||
|
|
||||||
|
constexpr SmallStringView(const_iterator begin, const_iterator end) noexcept
|
||||||
: m_pointer(begin.data())
|
: m_pointer(begin.data())
|
||||||
, m_size(std::size_t(end - begin))
|
, m_size(std::size_t(end - begin))
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
constexpr SmallStringView(iterator begin, iterator end) noexcept
|
||||||
|
: m_pointer(begin.data())
|
||||||
|
, m_size(std::size_t(end - begin))
|
||||||
|
{}
|
||||||
|
|
||||||
template<typename String, typename Utils::enable_if_has_char_data_pointer<String> = 0>
|
template<typename String, typename Utils::enable_if_has_char_data_pointer<String> = 0>
|
||||||
constexpr SmallStringView(const String &string) noexcept
|
constexpr SmallStringView(const String &string) noexcept
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include <android/androidconstants.h>
|
#include <android/androidconstants.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
|
#include <coreplugin/reaper.h>
|
||||||
#include <cpptools/cppprojectupdater.h>
|
#include <cpptools/cppprojectupdater.h>
|
||||||
#include <cpptools/cpptoolsconstants.h>
|
#include <cpptools/cpptoolsconstants.h>
|
||||||
#include <cpptools/generatedcodemodelsupport.h>
|
#include <cpptools/generatedcodemodelsupport.h>
|
||||||
@@ -59,6 +60,7 @@
|
|||||||
#include <utils/macroexpander.h>
|
#include <utils/macroexpander.h>
|
||||||
#include <utils/mimetypes/mimetype.h>
|
#include <utils/mimetypes/mimetype.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/runextensions.h>
|
||||||
|
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -207,6 +209,7 @@ CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc)
|
|||||||
|
|
||||||
CMakeBuildSystem::~CMakeBuildSystem()
|
CMakeBuildSystem::~CMakeBuildSystem()
|
||||||
{
|
{
|
||||||
|
m_futureSynchronizer.waitForFinished();
|
||||||
if (!m_treeScanner.isFinished()) {
|
if (!m_treeScanner.isFinished()) {
|
||||||
auto future = m_treeScanner.future();
|
auto future = m_treeScanner.future();
|
||||||
future.cancel();
|
future.cancel();
|
||||||
@@ -576,7 +579,7 @@ void CMakeBuildSystem::combineScanAndParse()
|
|||||||
|
|
||||||
emitBuildSystemUpdated();
|
emitBuildSystemUpdated();
|
||||||
|
|
||||||
QTimer::singleShot(0, this, &CMakeBuildSystem::runCTest);
|
runCTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeBuildSystem::checkAndReportError(QString &errorMessage)
|
void CMakeBuildSystem::checkAndReportError(QString &errorMessage)
|
||||||
@@ -921,42 +924,62 @@ void CMakeBuildSystem::runCTest()
|
|||||||
}
|
}
|
||||||
qCDebug(cmakeBuildSystemLog) << "Requesting ctest run after cmake run";
|
qCDebug(cmakeBuildSystemLog) << "Requesting ctest run after cmake run";
|
||||||
|
|
||||||
BuildDirParameters parameters(cmakeBuildConfiguration());
|
const BuildDirParameters parameters(cmakeBuildConfiguration());
|
||||||
QTC_ASSERT(parameters.isValid(), return);
|
QTC_ASSERT(parameters.isValid(), return);
|
||||||
|
|
||||||
FilePath workingDirectory = workDirectory(parameters);
|
const CommandLine cmd { m_ctestPath, { "-N", "--show-only=json-v1" } };
|
||||||
CommandLine cmd{m_ctestPath, {"-N", "--show-only=json-v1"}};
|
const QString workingDirectory = workDirectory(parameters).toString();
|
||||||
SynchronousProcess ctest;
|
const QStringList environment = cmakeBuildConfiguration()->environment().toStringList();
|
||||||
ctest.setTimeoutS(1);
|
|
||||||
ctest.setEnvironment(cmakeBuildConfiguration()->environment().toStringList());
|
|
||||||
ctest.setWorkingDirectory(workingDirectory.toString());
|
|
||||||
|
|
||||||
const SynchronousProcessResponse response = ctest.run(cmd);
|
auto future = Utils::runAsync([cmd, workingDirectory, environment]
|
||||||
if (response.result == SynchronousProcessResponse::Finished) {
|
(QFutureInterface<QByteArray> &futureInterface) {
|
||||||
const QJsonDocument json = QJsonDocument::fromJson(response.allRawOutput());
|
QProcess process;
|
||||||
if (!json.isEmpty() && json.isObject()) {
|
process.setEnvironment(environment);
|
||||||
const QJsonObject jsonObj = json.object();
|
process.setWorkingDirectory(workingDirectory);
|
||||||
const QJsonObject btGraph = jsonObj.value("backtraceGraph").toObject();
|
process.start(cmd.executable().toString(), cmd.splitArguments(), QIODevice::ReadOnly);
|
||||||
const QJsonArray cmakelists = btGraph.value("files").toArray();
|
|
||||||
const QJsonArray nodes = btGraph.value("nodes").toArray();
|
if (!process.waitForStarted(1000) || !process.waitForFinished(1000)) {
|
||||||
const QJsonArray tests = jsonObj.value("tests").toArray();
|
if (process.state() == QProcess::NotRunning)
|
||||||
for (const QJsonValue &testVal : tests) {
|
return;
|
||||||
const QJsonObject test = testVal.toObject();
|
process.terminate();
|
||||||
QTC_ASSERT(!test.isEmpty(), continue);
|
if (process.waitForFinished(1000))
|
||||||
const int bt = test.value("backtrace").toInt(-1);
|
return;
|
||||||
QTC_ASSERT(bt != -1, continue);
|
process.kill();
|
||||||
const QJsonObject btRef = nodes.at(bt).toObject();
|
process.waitForFinished(1000);
|
||||||
int file = btRef.value("file").toInt(-1);
|
return;
|
||||||
int line = btRef.value("line").toInt(-1);
|
}
|
||||||
QTC_ASSERT(file != -1 && line != -1, continue);
|
if (process.exitCode() || process.exitStatus() != QProcess::NormalExit)
|
||||||
m_testNames.append({test.value("name").toString(),
|
return;
|
||||||
FilePath::fromString(cmakelists.at(file).toString()),
|
futureInterface.reportResult(process.readAllStandardOutput());
|
||||||
line
|
});
|
||||||
});
|
|
||||||
|
Utils::onFinished(future, this, [this](const QFuture<QByteArray> &future) {
|
||||||
|
if (future.resultCount()) {
|
||||||
|
const QJsonDocument json = QJsonDocument::fromJson(future.result());
|
||||||
|
if (!json.isEmpty() && json.isObject()) {
|
||||||
|
const QJsonObject jsonObj = json.object();
|
||||||
|
const QJsonObject btGraph = jsonObj.value("backtraceGraph").toObject();
|
||||||
|
const QJsonArray cmakelists = btGraph.value("files").toArray();
|
||||||
|
const QJsonArray nodes = btGraph.value("nodes").toArray();
|
||||||
|
const QJsonArray tests = jsonObj.value("tests").toArray();
|
||||||
|
for (const QJsonValue &testVal : tests) {
|
||||||
|
const QJsonObject test = testVal.toObject();
|
||||||
|
QTC_ASSERT(!test.isEmpty(), continue);
|
||||||
|
const int bt = test.value("backtrace").toInt(-1);
|
||||||
|
QTC_ASSERT(bt != -1, continue);
|
||||||
|
const QJsonObject btRef = nodes.at(bt).toObject();
|
||||||
|
int file = btRef.value("file").toInt(-1);
|
||||||
|
int line = btRef.value("line").toInt(-1);
|
||||||
|
QTC_ASSERT(file != -1 && line != -1, continue);
|
||||||
|
m_testNames.append({ test.value("name").toString(),
|
||||||
|
FilePath::fromString(cmakelists.at(file).toString()), line });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
emit testInformationUpdated();
|
||||||
emit testInformationUpdated();
|
});
|
||||||
|
|
||||||
|
m_futureSynchronizer.addFuture(future);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const
|
CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const
|
||||||
|
@@ -35,6 +35,8 @@
|
|||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/temporarydirectory.h>
|
#include <utils/temporarydirectory.h>
|
||||||
|
|
||||||
|
#include <QFutureSynchronizer>
|
||||||
|
|
||||||
namespace ProjectExplorer { class ExtraCompiler; }
|
namespace ProjectExplorer { class ExtraCompiler; }
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
@@ -181,6 +183,7 @@ private:
|
|||||||
// CTest integration
|
// CTest integration
|
||||||
QString m_ctestPath;
|
QString m_ctestPath;
|
||||||
QList<ProjectExplorer::TestCaseInfo> m_testNames;
|
QList<ProjectExplorer::TestCaseInfo> m_testNames;
|
||||||
|
QFutureSynchronizer<QByteArray> m_futureSynchronizer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -1147,26 +1147,6 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore signals from the process stub.
|
|
||||||
const GdbMi frame = data["frame"];
|
|
||||||
if (terminal()
|
|
||||||
&& data["reason"].data() == "signal-received"
|
|
||||||
&& data["signal-name"].data() == "SIGSTOP")
|
|
||||||
{
|
|
||||||
const QString from = frame["from"].data();
|
|
||||||
const QString func = frame["func"].data();
|
|
||||||
if (from.endsWith("/ld-linux.so.2")
|
|
||||||
|| from.endsWith("/ld-linux-x86-64.so.2")
|
|
||||||
|| func == "clone"
|
|
||||||
|| func == "kill")
|
|
||||||
{
|
|
||||||
showMessage("INTERNAL CONTINUE AFTER SIGSTOP FROM STUB", LogMisc);
|
|
||||||
notifyInferiorSpontaneousStop();
|
|
||||||
continueInferiorInternal();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_onStop.isEmpty()) {
|
if (!m_onStop.isEmpty()) {
|
||||||
notifyInferiorStopOk();
|
notifyInferiorStopOk();
|
||||||
showMessage("HANDLING QUEUED COMMANDS AFTER TEMPORARY STOP", LogMisc);
|
showMessage("HANDLING QUEUED COMMANDS AFTER TEMPORARY STOP", LogMisc);
|
||||||
@@ -1184,6 +1164,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
|
|||||||
QString fullName;
|
QString fullName;
|
||||||
QString function;
|
QString function;
|
||||||
QString language;
|
QString language;
|
||||||
|
const GdbMi frame = data["frame"];
|
||||||
if (frame.isValid()) {
|
if (frame.isValid()) {
|
||||||
const GdbMi lineNumberG = frame["line"];
|
const GdbMi lineNumberG = frame["line"];
|
||||||
function = frame["function"].data(); // V4 protocol
|
function = frame["function"].data(); // V4 protocol
|
||||||
@@ -4920,7 +4901,9 @@ void GdbEngine::handleStubAttached(const DebuggerResponse &response, qint64 main
|
|||||||
notifyEngineRunAndInferiorStopOk();
|
notifyEngineRunAndInferiorStopOk();
|
||||||
continueInferiorInternal();
|
continueInferiorInternal();
|
||||||
} else {
|
} else {
|
||||||
showMessage("INFERIOR ATTACHED AND RUNNING");
|
showMessage("INFERIOR ATTACHED");
|
||||||
|
QTC_ASSERT(terminal(), return);
|
||||||
|
terminal()->kickoffProcess();
|
||||||
//notifyEngineRunAndInferiorRunOk();
|
//notifyEngineRunAndInferiorRunOk();
|
||||||
// Wait for the upcoming *stopped and handle it there.
|
// Wait for the upcoming *stopped and handle it there.
|
||||||
}
|
}
|
||||||
|
@@ -183,6 +183,11 @@ TerminalRunner::TerminalRunner(RunControl *runControl, const Runnable &stubRunna
|
|||||||
this, [this] { reportDone(); });
|
this, [this] { reportDone(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TerminalRunner::kickoffProcess()
|
||||||
|
{
|
||||||
|
m_stubProc.kickoffProcess();
|
||||||
|
}
|
||||||
|
|
||||||
void TerminalRunner::interruptProcess()
|
void TerminalRunner::interruptProcess()
|
||||||
{
|
{
|
||||||
m_stubProc.interruptProcess();
|
m_stubProc.interruptProcess();
|
||||||
|
@@ -77,6 +77,7 @@ public:
|
|||||||
qint64 applicationPid() const { return m_applicationPid; }
|
qint64 applicationPid() const { return m_applicationPid; }
|
||||||
qint64 applicationMainThreadId() const { return m_applicationMainThreadId; }
|
qint64 applicationMainThreadId() const { return m_applicationMainThreadId; }
|
||||||
|
|
||||||
|
void kickoffProcess();
|
||||||
void interruptProcess();
|
void interruptProcess();
|
||||||
void setRunAsRoot(bool on);
|
void setRunAsRoot(bool on);
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@ add_qtc_plugin(QmlDesigner
|
|||||||
settingspage.cpp settingspage.h settingspage.ui
|
settingspage.cpp settingspage.h settingspage.ui
|
||||||
shortcutmanager.cpp shortcutmanager.h
|
shortcutmanager.cpp shortcutmanager.h
|
||||||
designermcumanager.cpp designermcumanager.h
|
designermcumanager.cpp designermcumanager.h
|
||||||
|
richtexteditordialog.cpp richtexteditordialog.h
|
||||||
EXPLICIT_MOC
|
EXPLICIT_MOC
|
||||||
components/propertyeditor/propertyeditorvalue.h
|
components/propertyeditor/propertyeditorvalue.h
|
||||||
components/connectioneditor/connectionviewwidget.h
|
components/connectioneditor/connectionviewwidget.h
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#include <QStyleOptionGraphicsItem>
|
#include <QStyleOptionGraphicsItem>
|
||||||
#include <QTimeLine>
|
#include <QTimeLine>
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
|
#include <QtMath>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
@@ -57,8 +58,8 @@ const int blockRadius = 18;
|
|||||||
const int blockAdjust = 40;
|
const int blockAdjust = 40;
|
||||||
const int startItemOffset = 96;
|
const int startItemOffset = 96;
|
||||||
|
|
||||||
const qreal fontSize = 10; // points
|
const qreal labelFontSize = 10;
|
||||||
const qreal zoomLevelLabel = 0.5; // Everything lower than that will hide all labels
|
const qreal labelShowThreshold = 0.25; // Everything lower than that will hide all labels
|
||||||
const qreal defaultDpi = 96.0;
|
const qreal defaultDpi = 96.0;
|
||||||
|
|
||||||
void drawIcon(QPainter *painter,
|
void drawIcon(QPainter *painter,
|
||||||
@@ -627,12 +628,68 @@ void FormEditorFlowItem::updateGeometry()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FormEditorFlowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||||
|
{
|
||||||
|
FormEditorItem::paint(painter, option, widget);
|
||||||
|
|
||||||
|
if (!painter->isActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!qmlItemNode().isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
QPen pen;
|
||||||
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
|
|
||||||
|
QColor flowColor(0xe71919);
|
||||||
|
|
||||||
|
if (qmlItemNode().rootModelNode().hasAuxiliaryData("areaColor"))
|
||||||
|
flowColor = qmlItemNode().rootModelNode().auxiliaryData("areaColor").value<QColor>();
|
||||||
|
|
||||||
|
if (qmlItemNode().modelNode().hasAuxiliaryData("color"))
|
||||||
|
flowColor = qmlItemNode().modelNode().auxiliaryData("color").value<QColor>();
|
||||||
|
|
||||||
|
pen.setColor(flowColor);
|
||||||
|
|
||||||
|
qreal width = 2;
|
||||||
|
|
||||||
|
// if (qmlItemNode().modelNode().hasAuxiliaryData("width"))
|
||||||
|
// width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
|
||||||
|
|
||||||
|
width *= getLineScaleFactor();
|
||||||
|
|
||||||
|
pen.setWidthF(width);
|
||||||
|
|
||||||
|
|
||||||
|
bool dash = false;
|
||||||
|
|
||||||
|
if (qmlItemNode().modelNode().hasAuxiliaryData("dash"))
|
||||||
|
dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
|
||||||
|
|
||||||
|
if (dash)
|
||||||
|
pen.setStyle(Qt::DashLine);
|
||||||
|
else
|
||||||
|
pen.setStyle(Qt::SolidLine);
|
||||||
|
|
||||||
|
pen.setCosmetic(false);
|
||||||
|
painter->setPen(pen);
|
||||||
|
|
||||||
|
QColor fillColor = QColor(Qt::transparent);
|
||||||
|
painter->setBrush(fillColor);
|
||||||
|
|
||||||
|
painter->drawRoundedRect(boundingRect(), blockRadius, blockRadius);
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
|
}
|
||||||
|
|
||||||
QPointF FormEditorFlowItem::instancePosition() const
|
QPointF FormEditorFlowItem::instancePosition() const
|
||||||
{
|
{
|
||||||
return qmlItemNode().flowPosition();
|
return qmlItemNode().flowPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FormEditorFlowActionItem::setDataModelPosition(const QPointF &position)
|
void FormEditorFlowActionItem::setDataModelPosition(const QPointF &position)
|
||||||
{
|
{
|
||||||
qmlItemNode().setPosition(position);
|
qmlItemNode().setPosition(position);
|
||||||
@@ -691,7 +748,6 @@ void FormEditorFlowActionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setJoinStyle(Qt::MiterJoin);
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
pen.setCosmetic(true);
|
|
||||||
|
|
||||||
QColor flowColor(0xe71919);
|
QColor flowColor(0xe71919);
|
||||||
|
|
||||||
@@ -706,8 +762,9 @@ void FormEditorFlowActionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
if (qmlItemNode().modelNode().hasAuxiliaryData("width"))
|
if (qmlItemNode().modelNode().hasAuxiliaryData("width"))
|
||||||
width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
|
width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
|
||||||
|
|
||||||
bool dash = false;
|
width *= getLineScaleFactor();
|
||||||
|
|
||||||
|
bool dash = false;
|
||||||
|
|
||||||
if (qmlItemNode().modelNode().hasAuxiliaryData("dash"))
|
if (qmlItemNode().modelNode().hasAuxiliaryData("dash"))
|
||||||
dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
|
dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
|
||||||
@@ -719,7 +776,7 @@ void FormEditorFlowActionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
pen.setStyle(Qt::SolidLine);
|
pen.setStyle(Qt::SolidLine);
|
||||||
|
|
||||||
pen.setWidthF(width);
|
pen.setWidthF(width);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(false);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
|
|
||||||
QColor fillColor = QColor(Qt::transparent);
|
QColor fillColor = QColor(Qt::transparent);
|
||||||
@@ -867,10 +924,8 @@ class ConnectionConfiguration
|
|||||||
public:
|
public:
|
||||||
ConnectionConfiguration(const QmlItemNode &node,
|
ConnectionConfiguration(const QmlItemNode &node,
|
||||||
const ResolveConnection &resolveConnection,
|
const ResolveConnection &resolveConnection,
|
||||||
const qreal scaleFactor,
|
|
||||||
bool hitTest = false)
|
bool hitTest = false)
|
||||||
: width(2)
|
: width(2)
|
||||||
, adjustedWidth(width / scaleFactor)
|
|
||||||
, color(QColor(0xe71919))
|
, color(QColor(0xe71919))
|
||||||
, lineBrush(QBrush(color))
|
, lineBrush(QBrush(color))
|
||||||
, penStyle(Qt::SolidLine)
|
, penStyle(Qt::SolidLine)
|
||||||
@@ -883,9 +938,10 @@ public:
|
|||||||
, breakOffset(50)
|
, breakOffset(50)
|
||||||
, radius(8)
|
, radius(8)
|
||||||
, bezier(50)
|
, bezier(50)
|
||||||
|
, fontSize(labelFontSize)
|
||||||
, type(ConnectionType::Default)
|
, type(ConnectionType::Default)
|
||||||
, label()
|
, label()
|
||||||
, labelOffset(14 / scaleFactor)
|
, labelOffset(14)
|
||||||
, labelPosition(50.0)
|
, labelPosition(50.0)
|
||||||
, labelFlags(Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextDontClip)
|
, labelFlags(Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextDontClip)
|
||||||
, labelFlipSide(false)
|
, labelFlipSide(false)
|
||||||
@@ -895,12 +951,12 @@ public:
|
|||||||
{
|
{
|
||||||
// width
|
// width
|
||||||
if (node.modelNode().hasAuxiliaryData("width"))
|
if (node.modelNode().hasAuxiliaryData("width"))
|
||||||
width = node.modelNode().auxiliaryData("width").toInt();
|
width = node.modelNode().auxiliaryData("width").toFloat();
|
||||||
// adjusted width
|
// adjusted width
|
||||||
if (node.modelNode().isSelected())
|
if (node.modelNode().isSelected())
|
||||||
width += 2;
|
width += 2;
|
||||||
if (hitTest)
|
if (hitTest)
|
||||||
width = width * 8 / scaleFactor;
|
width = width * 8;
|
||||||
// color
|
// color
|
||||||
if (resolveConnection.isStartLine)
|
if (resolveConnection.isStartLine)
|
||||||
color = QColor("blue");
|
color = QColor("blue");
|
||||||
@@ -966,7 +1022,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
qreal width;
|
qreal width;
|
||||||
qreal adjustedWidth;
|
|
||||||
QColor color; // TODO private/setter
|
QColor color; // TODO private/setter
|
||||||
QBrush lineBrush;
|
QBrush lineBrush;
|
||||||
Qt::PenStyle penStyle;
|
Qt::PenStyle penStyle;
|
||||||
@@ -980,6 +1035,7 @@ public:
|
|||||||
int breakOffset;
|
int breakOffset;
|
||||||
int radius;
|
int radius;
|
||||||
int bezier;
|
int bezier;
|
||||||
|
qreal fontSize;
|
||||||
ConnectionType type;
|
ConnectionType type;
|
||||||
QString label;
|
QString label;
|
||||||
qreal labelOffset;
|
qreal labelOffset;
|
||||||
@@ -1285,7 +1341,7 @@ public:
|
|||||||
const bool boolExitRight = fromRect.right() < toRect.center().x();
|
const bool boolExitRight = fromRect.right() < toRect.center().x();
|
||||||
const bool boolExitBottom = fromRect.bottom() < toRect.center().y();
|
const bool boolExitBottom = fromRect.bottom() < toRect.center().y();
|
||||||
|
|
||||||
const qreal padding = 8;
|
const int padding = 4 * config.width;
|
||||||
|
|
||||||
if (horizontalFirst) {
|
if (horizontalFirst) {
|
||||||
const qreal startX = boolExitRight ? fromRect.right() + padding : fromRect.x() - padding;
|
const qreal startX = boolExitRight ? fromRect.right() + padding : fromRect.x() - padding;
|
||||||
@@ -1405,7 +1461,7 @@ void FormEditorTransitionItem::updateGeometry()
|
|||||||
QPixmap pixmap(640, 480);
|
QPixmap pixmap(640, 480);
|
||||||
QPainter localPainter(&pixmap);
|
QPainter localPainter(&pixmap);
|
||||||
QFont font = localPainter.font();
|
QFont font = localPainter.font();
|
||||||
font.setPointSizeF(getFontSize(&localPainter) / getScaleFactor());
|
font.setPixelSize(labelFontSize * getTextScaleFactor());
|
||||||
localPainter.setFont(font);
|
localPainter.setFont(font);
|
||||||
|
|
||||||
const auto fromNodes = resolved.from;
|
const auto fromNodes = resolved.from;
|
||||||
@@ -1481,7 +1537,7 @@ void FormEditorTransitionItem::drawSingleLabel(QPainter *painter, const Connecti
|
|||||||
QPointF position;
|
QPointF position;
|
||||||
qreal angle;
|
qreal angle;
|
||||||
|
|
||||||
const qreal hMargin = 10.0 / getScaleFactor();
|
const qreal hMargin = 10.0 * getItemScaleFactor();
|
||||||
QFontMetrics metric(painter->font());
|
QFontMetrics metric(painter->font());
|
||||||
|
|
||||||
const qreal lineHeight = metric.boundingRect("Xyz").height();
|
const qreal lineHeight = metric.boundingRect("Xyz").height();
|
||||||
@@ -1506,7 +1562,7 @@ void FormEditorTransitionItem::drawSingleLabel(QPainter *painter, const Connecti
|
|||||||
labelRect.adjust(-hMargin, 0.0, hMargin, 0.0);
|
labelRect.adjust(-hMargin, 0.0, hMargin, 0.0);
|
||||||
|
|
||||||
if (singleEvent && singleSignal)
|
if (singleEvent && singleSignal)
|
||||||
labelRect.setHeight(eventRect.height() + signalRect.height() + (6.0 / getScaleFactor()));
|
labelRect.setHeight(eventRect.height() + signalRect.height() + (6.0 * getTextScaleFactor()));
|
||||||
|
|
||||||
const qreal halfHeight = labelRect.height() * 0.5;
|
const qreal halfHeight = labelRect.height() * 0.5;
|
||||||
|
|
||||||
@@ -1526,7 +1582,7 @@ void FormEditorTransitionItem::drawSingleLabel(QPainter *painter, const Connecti
|
|||||||
|
|
||||||
// Calculate font bounding box without taking into account the cale factor
|
// Calculate font bounding box without taking into account the cale factor
|
||||||
QFont originalFont = painter->font();
|
QFont originalFont = painter->font();
|
||||||
originalFont.setPointSizeF(getFontSize(painter));
|
originalFont.setPixelSize(labelFontSize * getTextScaleFactor());
|
||||||
QFontMetrics originalMetric(originalFont);
|
QFontMetrics originalMetric(originalFont);
|
||||||
QRectF originalTextRect = originalMetric.boundingRect(events);
|
QRectF originalTextRect = originalMetric.boundingRect(events);
|
||||||
originalTextRect.adjust(-10.0, 0.0, 10.0, 0.0);
|
originalTextRect.adjust(-10.0, 0.0, 10.0, 0.0);
|
||||||
@@ -1588,9 +1644,9 @@ void FormEditorTransitionItem::drawSingleLabel(QPainter *painter, const Connecti
|
|||||||
painter->setPen(Qt::white);
|
painter->setPen(Qt::white);
|
||||||
if (singleEvent && singleSignal) {
|
if (singleEvent && singleSignal) {
|
||||||
eventRect.setWidth(labelRect.width());
|
eventRect.setWidth(labelRect.width());
|
||||||
eventRect.moveTopLeft(labelRect.topLeft() + QPointF(0.0, 4.0 / getScaleFactor()));
|
eventRect.moveTopLeft(labelRect.topLeft() + QPointF(0.0, 4.0 * getItemScaleFactor()));
|
||||||
signalRect.setWidth(labelRect.width());
|
signalRect.setWidth(labelRect.width());
|
||||||
signalRect.moveBottomLeft(labelRect.bottomLeft() - QPointF(0.0, 4.0 / getScaleFactor()));
|
signalRect.moveBottomLeft(labelRect.bottomLeft() - QPointF(0.0, 4.0 * getItemScaleFactor()));
|
||||||
|
|
||||||
painter->drawText(eventRect, Qt::AlignCenter, events);
|
painter->drawText(eventRect, Qt::AlignCenter, events);
|
||||||
painter->drawText(signalRect, Qt::AlignCenter, targetSignal);
|
painter->drawText(signalRect, Qt::AlignCenter, targetSignal);
|
||||||
@@ -1619,9 +1675,8 @@ void FormEditorTransitionItem::drawSelectionLabel(QPainter *painter, const Conne
|
|||||||
const QStringList events = connection.config.events.split(',');
|
const QStringList events = connection.config.events.split(',');
|
||||||
const int eventCount = events.size();
|
const int eventCount = events.size();
|
||||||
|
|
||||||
const qreal scaleFactor = getScaleFactor();
|
const qreal radius = 7.0 * getItemScaleFactor();
|
||||||
const qreal radius = 7.0 / scaleFactor;
|
const qreal hMargin = 10.0 * getItemScaleFactor();
|
||||||
const qreal hMargin = 10.0 / scaleFactor;
|
|
||||||
|
|
||||||
QFontMetrics metric(painter->font());
|
QFontMetrics metric(painter->font());
|
||||||
const qreal lineHeight = metric.boundingRect("Xyz").height();
|
const qreal lineHeight = metric.boundingRect("Xyz").height();
|
||||||
@@ -1657,7 +1712,7 @@ void FormEditorTransitionItem::drawSelectionLabel(QPainter *painter, const Conne
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int signalCount = signalList.size();
|
const int signalCount = signalList.size();
|
||||||
const qreal offset = 10.0 / scaleFactor;
|
const qreal offset = 10.0 * getItemScaleFactor();
|
||||||
|
|
||||||
qreal totalHeight = 0;
|
qreal totalHeight = 0;
|
||||||
if (hasEvents)
|
if (hasEvents)
|
||||||
@@ -1730,34 +1785,33 @@ void FormEditorTransitionItem::drawSelectionLabel(QPainter *painter, const Conne
|
|||||||
static void drawArrow(QPainter *painter,
|
static void drawArrow(QPainter *painter,
|
||||||
const QPointF &point,
|
const QPointF &point,
|
||||||
const qreal &angle,
|
const qreal &angle,
|
||||||
const qreal &arrowLength,
|
qreal arrowSize,
|
||||||
const qreal &arrowWidth)
|
qreal arrowTipAngle = 90.0)
|
||||||
{
|
{
|
||||||
const QPointF peakP(0, 0);
|
const QPointF peakP(0, 0);
|
||||||
const QPointF leftP(-arrowLength, -arrowWidth * 0.5);
|
const QPointF endP(-arrowSize, 0);
|
||||||
const QPointF rightP(-arrowLength, arrowWidth * 0.5);
|
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
|
|
||||||
painter->translate(point);
|
painter->translate(point);
|
||||||
painter->rotate(-angle);
|
painter->rotate(-angle - (arrowTipAngle/2.0));
|
||||||
painter->drawLine(leftP, peakP);
|
painter->drawLine(peakP, endP);
|
||||||
painter->drawLine(rightP, peakP);
|
painter->rotate(arrowTipAngle);
|
||||||
|
painter->drawLine(peakP, endP);
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormEditorTransitionItem::paintConnection(QPainter *painter, const Connection &connection)
|
void FormEditorTransitionItem::paintConnection(QPainter *painter, const Connection &connection)
|
||||||
{
|
{
|
||||||
const qreal arrowLength = 4 * connection.config.adjustedWidth;
|
const int arrowSize = 12 * getLineScaleFactor();
|
||||||
const qreal arrowWidth = 8 * connection.config.adjustedWidth;
|
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
painter->setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
// Draw path/connection line
|
// Draw path/connection line
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(false);
|
||||||
pen.setJoinStyle(Qt::MiterJoin);
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
pen.setCapStyle(Qt::RoundCap);
|
pen.setCapStyle(Qt::RoundCap);
|
||||||
pen.setBrush(connection.config.lineBrush);
|
pen.setBrush(connection.config.lineBrush);
|
||||||
@@ -1769,12 +1823,12 @@ void FormEditorTransitionItem::paintConnection(QPainter *painter, const Connecti
|
|||||||
pen.setStyle(connection.config.penStyle);
|
pen.setStyle(connection.config.penStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
pen.setWidthF(connection.config.width);
|
pen.setWidthF(connection.config.width * getLineScaleFactor());
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
|
|
||||||
painter->drawPath(connection.path);
|
painter->drawPath(connection.path);
|
||||||
|
|
||||||
pen.setWidthF(connection.config.width);
|
pen.setWidthF(connection.config.width * getLineScaleFactor());
|
||||||
pen.setStyle(Qt::SolidLine);
|
pen.setStyle(Qt::SolidLine);
|
||||||
pen.setColor(connection.config.color);
|
pen.setColor(connection.config.color);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
@@ -1791,16 +1845,16 @@ void FormEditorTransitionItem::paintConnection(QPainter *painter, const Connecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (connection.config.drawEnd)
|
if (connection.config.drawEnd)
|
||||||
drawArrow(painter, connection.end, angle, arrowLength, arrowWidth);
|
drawArrow(painter, connection.end, angle, arrowSize, 60.0);
|
||||||
|
|
||||||
// Draw start ellipse
|
// Draw start ellipse
|
||||||
if (connection.config.drawStart) {
|
if (connection.config.drawStart) {
|
||||||
painter->setBrush(Qt::white);
|
painter->setBrush(Qt::white);
|
||||||
painter->drawEllipse(connection.start, arrowLength / 2.0, arrowLength / 2.0);
|
painter->drawEllipse(connection.start, arrowSize / 5, arrowSize / 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw labels
|
// Draw labels
|
||||||
if (viewportTransform().m11() >= zoomLevelLabel)
|
if (viewportTransform().m11() >= labelShowThreshold)
|
||||||
drawLabels(painter, connection);
|
drawLabels(painter, connection);
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
@@ -1825,11 +1879,11 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
if (!isModelNodeValid(resolved.from))
|
if (!isModelNodeValid(resolved.from))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ConnectionConfiguration config(qmlItemNode(), resolved, viewportTransform().m11(), m_hitTest);
|
ConnectionConfiguration config(qmlItemNode(), resolved, m_hitTest);
|
||||||
|
|
||||||
QFont f = painter->font();
|
QFont font = painter->font();
|
||||||
f.setPointSizeF(getFontSize(painter) / getScaleFactor());
|
font.setPixelSize(config.fontSize * getTextScaleFactor());
|
||||||
painter->setFont(f);
|
painter->setFont(font);
|
||||||
|
|
||||||
const auto fromNodes = resolved.from;
|
const auto fromNodes = resolved.from;
|
||||||
const auto toNodes = resolved.to;
|
const auto toNodes = resolved.to;
|
||||||
@@ -1896,7 +1950,7 @@ void FormEditorTransitionItem::paint(QPainter *painter, const QStyleOptionGraphi
|
|||||||
const QString icon = Theme::getIconUnicode(Theme::startNode);
|
const QString icon = Theme::getIconUnicode(Theme::startNode);
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(false);
|
||||||
pen.setColor(config.color);
|
pen.setColor(config.color);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
|
|
||||||
@@ -1937,18 +1991,19 @@ QTransform FormEditorItem::viewportTransform() const
|
|||||||
return scene()->views().first()->viewportTransform();
|
return scene()->views().first()->viewportTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal FormEditorItem::getFontSize(QPainter *painter) const
|
qreal FormEditorItem::getItemScaleFactor() const
|
||||||
{
|
{
|
||||||
const int dpi = std::max(painter->device()->logicalDpiX(),
|
return 1.0 / viewportTransform().m11();
|
||||||
painter->device()->logicalDpiY());
|
|
||||||
|
|
||||||
return fontSize * (dpi / defaultDpi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal FormEditorItem::getScaleFactor() const
|
qreal FormEditorItem::getLineScaleFactor() const
|
||||||
{
|
{
|
||||||
// Cap scaling at 100% zoom
|
return 2 / qSqrt(viewportTransform().m11());
|
||||||
return (viewportTransform().m11() >= 1.0) ? viewportTransform().m11() : 1.0;
|
}
|
||||||
|
|
||||||
|
qreal FormEditorItem::getTextScaleFactor() const
|
||||||
|
{
|
||||||
|
return 2 / qSqrt(viewportTransform().m11());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormEditorFlowDecisionItem::updateGeometry()
|
void FormEditorFlowDecisionItem::updateGeometry()
|
||||||
@@ -1960,6 +2015,7 @@ void FormEditorFlowDecisionItem::updateGeometry()
|
|||||||
size = qmlItemNode().modelNode().auxiliaryData("blockSize").toInt();
|
size = qmlItemNode().modelNode().auxiliaryData("blockSize").toInt();
|
||||||
|
|
||||||
QRectF boundingRect(0, 0, size, size);
|
QRectF boundingRect(0, 0, size, size);
|
||||||
|
QRectF selectionRect = boundingRect;
|
||||||
QTransform transform;
|
QTransform transform;
|
||||||
if (qmlItemNode().isFlowDecision()) {
|
if (qmlItemNode().isFlowDecision()) {
|
||||||
transform.translate(boundingRect.center().x(), boundingRect.center().y());
|
transform.translate(boundingRect.center().x(), boundingRect.center().y());
|
||||||
@@ -1982,7 +2038,7 @@ void FormEditorFlowDecisionItem::updateGeometry()
|
|||||||
QPixmap pixmap(640, 480);
|
QPixmap pixmap(640, 480);
|
||||||
QPainter localPainter(&pixmap);
|
QPainter localPainter(&pixmap);
|
||||||
QFont font = localPainter.font();
|
QFont font = localPainter.font();
|
||||||
font.setPointSizeF(getFontSize(&localPainter) / getScaleFactor());
|
font.setPixelSize(labelFontSize * getTextScaleFactor());
|
||||||
localPainter.setFont(font);
|
localPainter.setFont(font);
|
||||||
|
|
||||||
const qreal margin = blockAdjust * 0.5;
|
const qreal margin = blockAdjust * 0.5;
|
||||||
@@ -2018,14 +2074,15 @@ void FormEditorFlowDecisionItem::updateGeometry()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unite the rotate item bounding rect with the label bounding rect.
|
// bounding rect is combination of label and icon but only icon can be clicked
|
||||||
boundingRect = transform.mapRect(boundingRect);
|
boundingRect = transform.mapRect(boundingRect);
|
||||||
|
selectionRect = boundingRect;
|
||||||
boundingRect = boundingRect.united(labelBoundingRect);
|
boundingRect = boundingRect.united(labelBoundingRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_selectionBoundingRect = boundingRect;
|
m_selectionBoundingRect = selectionRect;
|
||||||
m_paintedBoundingRect = m_selectionBoundingRect;
|
m_boundingRect = boundingRect;
|
||||||
m_boundingRect = m_paintedBoundingRect;
|
m_paintedBoundingRect = boundingRect;
|
||||||
setTransform(qmlItemNode().instanceTransformWithContentTransform());
|
setTransform(qmlItemNode().instanceTransformWithContentTransform());
|
||||||
const QPointF pos = qmlItemNode().flowPosition();
|
const QPointF pos = qmlItemNode().flowPosition();
|
||||||
setTransform(QTransform::fromTranslate(pos.x(), pos.y()));
|
setTransform(QTransform::fromTranslate(pos.x(), pos.y()));
|
||||||
@@ -2045,7 +2102,7 @@ void FormEditorFlowDecisionItem::paint(QPainter *painter, const QStyleOptionGrap
|
|||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
pen.setJoinStyle(Qt::MiterJoin);
|
pen.setJoinStyle(Qt::MiterJoin);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(false);
|
||||||
|
|
||||||
QColor flowColor(0xe71919);
|
QColor flowColor(0xe71919);
|
||||||
|
|
||||||
@@ -2055,24 +2112,26 @@ void FormEditorFlowDecisionItem::paint(QPainter *painter, const QStyleOptionGrap
|
|||||||
if (qmlItemNode().modelNode().hasAuxiliaryData("color"))
|
if (qmlItemNode().modelNode().hasAuxiliaryData("color"))
|
||||||
flowColor = qmlItemNode().modelNode().auxiliaryData("color").value<QColor>();
|
flowColor = qmlItemNode().modelNode().auxiliaryData("color").value<QColor>();
|
||||||
|
|
||||||
|
pen.setColor(flowColor);
|
||||||
|
|
||||||
qreal width = 2;
|
qreal width = 2;
|
||||||
|
|
||||||
if (qmlItemNode().modelNode().hasAuxiliaryData("width"))
|
if (qmlItemNode().modelNode().hasAuxiliaryData("width"))
|
||||||
width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
|
width = qmlItemNode().modelNode().auxiliaryData("width").toInt();
|
||||||
|
|
||||||
|
width *= getLineScaleFactor();
|
||||||
|
pen.setWidthF(width);
|
||||||
|
|
||||||
bool dash = false;
|
bool dash = false;
|
||||||
|
|
||||||
if (qmlItemNode().modelNode().hasAuxiliaryData("dash"))
|
if (qmlItemNode().modelNode().hasAuxiliaryData("dash"))
|
||||||
dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
|
dash = qmlItemNode().modelNode().auxiliaryData("dash").toBool();
|
||||||
|
|
||||||
pen.setColor(flowColor);
|
|
||||||
if (dash)
|
if (dash)
|
||||||
pen.setStyle(Qt::DashLine);
|
pen.setStyle(Qt::DashLine);
|
||||||
else
|
else
|
||||||
pen.setStyle(Qt::SolidLine);
|
pen.setStyle(Qt::SolidLine);
|
||||||
|
|
||||||
pen.setWidthF(width);
|
|
||||||
pen.setCosmetic(true);
|
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
|
|
||||||
QColor fillColor = QColor(Qt::transparent);
|
QColor fillColor = QColor(Qt::transparent);
|
||||||
@@ -2119,7 +2178,7 @@ void FormEditorFlowDecisionItem::paint(QPainter *painter, const QStyleOptionGrap
|
|||||||
if (qmlItemNode().modelNode().hasAuxiliaryData("showDialogLabel"))
|
if (qmlItemNode().modelNode().hasAuxiliaryData("showDialogLabel"))
|
||||||
showDialogLabel = qmlItemNode().modelNode().auxiliaryData("showDialogLabel").toBool();
|
showDialogLabel = qmlItemNode().modelNode().auxiliaryData("showDialogLabel").toBool();
|
||||||
|
|
||||||
if (showDialogLabel && viewportTransform().m11() >= zoomLevelLabel) {
|
if (showDialogLabel && viewportTransform().m11() >= labelShowThreshold) {
|
||||||
QString dialogTitle;
|
QString dialogTitle;
|
||||||
if (qmlItemNode().modelNode().hasVariantProperty("dialogTitle"))
|
if (qmlItemNode().modelNode().hasVariantProperty("dialogTitle"))
|
||||||
dialogTitle = qmlItemNode().modelNode().variantProperty("dialogTitle").value().toString();
|
dialogTitle = qmlItemNode().modelNode().variantProperty("dialogTitle").value().toString();
|
||||||
@@ -2127,7 +2186,7 @@ void FormEditorFlowDecisionItem::paint(QPainter *painter, const QStyleOptionGrap
|
|||||||
if (!dialogTitle.isEmpty()) {
|
if (!dialogTitle.isEmpty()) {
|
||||||
|
|
||||||
QFont font = painter->font();
|
QFont font = painter->font();
|
||||||
font.setPointSizeF(getFontSize(painter) / getScaleFactor());
|
font.setPixelSize(labelFontSize * getTextScaleFactor());
|
||||||
painter->setFont(font);
|
painter->setFont(font);
|
||||||
|
|
||||||
QRectF textRect(0, 0, 100, 20);
|
QRectF textRect(0, 0, 100, 20);
|
||||||
|
@@ -128,8 +128,10 @@ protected:
|
|||||||
QList<FormEditorItem*> offspringFormEditorItemsRecursive(const FormEditorItem *formEditorItem) const;
|
QList<FormEditorItem*> offspringFormEditorItemsRecursive(const FormEditorItem *formEditorItem) const;
|
||||||
FormEditorItem(const QmlItemNode &qmlItemNode, FormEditorScene* scene);
|
FormEditorItem(const QmlItemNode &qmlItemNode, FormEditorScene* scene);
|
||||||
QTransform viewportTransform() const;
|
QTransform viewportTransform() const;
|
||||||
qreal getFontSize(QPainter *painter) const;
|
|
||||||
qreal getScaleFactor() const;
|
qreal getItemScaleFactor() const;
|
||||||
|
qreal getLineScaleFactor() const;
|
||||||
|
qreal getTextScaleFactor() const;
|
||||||
|
|
||||||
QRectF m_boundingRect;
|
QRectF m_boundingRect;
|
||||||
QRectF m_paintedBoundingRect;
|
QRectF m_paintedBoundingRect;
|
||||||
@@ -161,6 +163,7 @@ public:
|
|||||||
void setDataModelPositionInBaseState(const QPointF &position) override;
|
void setDataModelPositionInBaseState(const QPointF &position) override;
|
||||||
void updateGeometry() override;
|
void updateGeometry() override;
|
||||||
QPointF instancePosition() const override;
|
QPointF instancePosition() const override;
|
||||||
|
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FormEditorFlowItem(const QmlItemNode &qmlItemNode, FormEditorScene *scene)
|
FormEditorFlowItem(const QmlItemNode &qmlItemNode, FormEditorScene *scene)
|
||||||
|
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 209 B |
Before Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 339 B |
@@ -29,17 +29,7 @@
|
|||||||
<file>images/asset_sound_192.png</file>
|
<file>images/asset_sound_192.png</file>
|
||||||
<file>images/asset_sound_256.png</file>
|
<file>images/asset_sound_256.png</file>
|
||||||
<file>images/asset_sound_384.png</file>
|
<file>images/asset_sound_384.png</file>
|
||||||
<file>images/tab_icon.png</file>
|
|
||||||
<file>images/tab_icon@2x.png</file>
|
|
||||||
<file>images/x.png</file>
|
<file>images/x.png</file>
|
||||||
<file>images/x@2x.png</file>
|
<file>images/x@2x.png</file>
|
||||||
<file>images/add.png</file>
|
|
||||||
<file>images/add@2x.png</file>
|
|
||||||
<file>images/add_unselected.png</file>
|
|
||||||
<file>images/add_unselected@2x.png</file>
|
|
||||||
<file>images/down.png</file>
|
|
||||||
<file>images/down@2x.png</file>
|
|
||||||
<file>qml/libraryheader.qml</file>
|
|
||||||
<file>qml/addimport.qml</file>
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@@ -102,6 +102,7 @@ void ItemLibraryCategoriesModel::expandCategories(bool expand)
|
|||||||
for (const auto &category : std::as_const(m_categoryList)) {
|
for (const auto &category : std::as_const(m_categoryList)) {
|
||||||
if (category->categoryExpanded() != expand) {
|
if (category->categoryExpanded() != expand) {
|
||||||
category->setExpanded(expand);
|
category->setExpanded(expand);
|
||||||
|
ItemLibraryModel::saveExpandedState(expand, category->categoryName());
|
||||||
emit dataChanged(index(i), index(i), {m_roleNames.key("categoryExpanded")});
|
emit dataChanged(index(i), index(i), {m_roleNames.key("categoryExpanded")});
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
|
@@ -60,7 +60,7 @@ QObject *ItemLibraryCategory::itemModel()
|
|||||||
return &m_itemModel;
|
return &m_itemModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemLibraryCategory::updateItemVisibility(const QString &searchText, bool *changed)
|
bool ItemLibraryCategory::updateItemVisibility(const QString &searchText, bool *changed, bool expand)
|
||||||
{
|
{
|
||||||
bool hasVisibleItems = false;
|
bool hasVisibleItems = false;
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ bool ItemLibraryCategory::updateItemVisibility(const QString &searchText, bool *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// expand category if it has an item matching search criteria
|
// expand category if it has an item matching search criteria
|
||||||
if (hasVisibleItems && !categoryExpanded())
|
if (expand && hasVisibleItems && !categoryExpanded())
|
||||||
setExpanded(true);
|
setExpanded(true);
|
||||||
|
|
||||||
return hasVisibleItems;
|
return hasVisibleItems;
|
||||||
|
@@ -50,7 +50,7 @@ public:
|
|||||||
void addItem(ItemLibraryItem *item);
|
void addItem(ItemLibraryItem *item);
|
||||||
QObject *itemModel();
|
QObject *itemModel();
|
||||||
|
|
||||||
bool updateItemVisibility(const QString &searchText, bool *changed);
|
bool updateItemVisibility(const QString &searchText, bool *changed, bool expand = false);
|
||||||
|
|
||||||
bool setVisible(bool isVisible);
|
bool setVisible(bool isVisible);
|
||||||
bool isVisible() const;
|
bool isVisible() const;
|
||||||
|
@@ -95,14 +95,14 @@ void ItemLibraryImport::expandCategories(bool expand)
|
|||||||
m_categoryModel.expandCategories(expand);
|
m_categoryModel.expandCategories(expand);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemLibraryImport::updateCategoryVisibility(const QString &searchText, bool *changed)
|
bool ItemLibraryImport::updateCategoryVisibility(const QString &searchText, bool *changed, bool expand)
|
||||||
{
|
{
|
||||||
bool hasVisibleCategories = false;
|
bool hasVisibleCategories = false;
|
||||||
*changed = false;
|
*changed = false;
|
||||||
|
|
||||||
for (const auto &category : m_categoryModel.categorySections()) {
|
for (const auto &category : m_categoryModel.categorySections()) {
|
||||||
bool categoryChanged = false;
|
bool categoryChanged = false;
|
||||||
bool hasVisibleItems = category->updateItemVisibility(searchText, &categoryChanged);
|
bool hasVisibleItems = category->updateItemVisibility(searchText, &categoryChanged, expand);
|
||||||
categoryChanged |= category->setVisible(hasVisibleItems);
|
categoryChanged |= category->setVisible(hasVisibleItems);
|
||||||
|
|
||||||
*changed |= categoryChanged;
|
*changed |= categoryChanged;
|
||||||
|
@@ -67,7 +67,7 @@ public:
|
|||||||
|
|
||||||
void addCategory(ItemLibraryCategory *category);
|
void addCategory(ItemLibraryCategory *category);
|
||||||
QObject *categoryModel();
|
QObject *categoryModel();
|
||||||
bool updateCategoryVisibility(const QString &searchText, bool *changed);
|
bool updateCategoryVisibility(const QString &searchText, bool *changed, bool expand = false);
|
||||||
bool setVisible(bool isVisible);
|
bool setVisible(bool isVisible);
|
||||||
void setImportUsed(bool importUsed);
|
void setImportUsed(bool importUsed);
|
||||||
void sortCategorySections();
|
void sortCategorySections();
|
||||||
|
@@ -163,7 +163,7 @@ void ItemLibraryModel::setSearchText(const QString &searchText)
|
|||||||
m_searchText = lowerSearchText;
|
m_searchText = lowerSearchText;
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
updateVisibility(&changed);
|
updateVisibility(&changed, !m_searchText.isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,18 +374,18 @@ void ItemLibraryModel::updateUsedImports(const QList<Import> &usedImports)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryModel::updateVisibility(bool *changed)
|
void ItemLibraryModel::updateVisibility(bool *changed, bool expand)
|
||||||
{
|
{
|
||||||
for (ItemLibraryImport *import : std::as_const(m_importList)) {
|
for (ItemLibraryImport *import : std::as_const(m_importList)) {
|
||||||
bool categoryChanged = false;
|
bool categoryChanged = false;
|
||||||
bool hasVisibleItems = import->updateCategoryVisibility(m_searchText, &categoryChanged);
|
bool hasVisibleItems = import->updateCategoryVisibility(m_searchText, &categoryChanged, expand);
|
||||||
*changed |= categoryChanged;
|
*changed |= categoryChanged;
|
||||||
|
|
||||||
if (import->sectionType() == ItemLibraryImport::SectionType::Unimported)
|
if (import->sectionType() == ItemLibraryImport::SectionType::Unimported)
|
||||||
*changed |= import->setVisible(!m_searchText.isEmpty());
|
*changed |= import->setVisible(!m_searchText.isEmpty());
|
||||||
|
|
||||||
// expand import if it has an item matching search criteria
|
// expand import if it has an item matching search criteria
|
||||||
if (hasVisibleItems && !import->importExpanded())
|
if (expand && hasVisibleItems && !import->importExpanded())
|
||||||
import->setImportExpanded();
|
import->setImportExpanded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -72,7 +72,7 @@ public:
|
|||||||
Import entryToImport(const ItemLibraryEntry &entry);
|
Import entryToImport(const ItemLibraryEntry &entry);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateVisibility(bool *changed);
|
void updateVisibility(bool *changed, bool expand = false);
|
||||||
void addRoleNames();
|
void addRoleNames();
|
||||||
void sortSections();
|
void sortSections();
|
||||||
void clearSections();
|
void clearSections();
|
||||||
|
@@ -141,27 +141,19 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
|||||||
|
|
||||||
// create header widget
|
// create header widget
|
||||||
m_headerWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_headerWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
m_headerWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
|
||||||
Theme::setupTheme(m_headerWidget->engine());
|
Theme::setupTheme(m_headerWidget->engine());
|
||||||
m_headerWidget->setSource(QUrl("qrc:/ItemLibrary/qml/libraryheader.qml"));
|
m_headerWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||||
QObject::connect(m_headerWidget->rootObject(), SIGNAL(tabChanged(int)), this,
|
m_headerWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||||
SLOT(handleTabChanged(int)));
|
m_headerWidget->rootContext()->setContextProperty("rootView", QVariant::fromValue(this));
|
||||||
QObject::connect(m_headerWidget->rootObject(), SIGNAL(filterChanged(QString)), this,
|
|
||||||
SLOT(handleFilterChanged(QString)));
|
|
||||||
QObject::connect(m_headerWidget->rootObject(), SIGNAL(addModuleClicked()), this,
|
|
||||||
SLOT(handleAddModule()));
|
|
||||||
QObject::connect(m_headerWidget->rootObject(), SIGNAL(addAssetClicked()), this,
|
|
||||||
SLOT(handleAddAsset()));
|
|
||||||
|
|
||||||
// create add imports widget
|
// create add imports widget
|
||||||
m_addImportWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_addImportWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
m_addImportWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
m_addImportWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||||
Theme::setupTheme(m_addImportWidget->engine());
|
Theme::setupTheme(m_addImportWidget->engine());
|
||||||
m_addImportWidget->setSource(QUrl("qrc:/ItemLibrary/qml/addimport.qml"));
|
m_addImportWidget->rootContext()->setContextProperties({
|
||||||
m_addImportWidget->rootContext()->setContextProperty(
|
{"addImportModel", QVariant::fromValue(m_itemLibraryAddImportModel.data())},
|
||||||
"addImportModel", QVariant::fromValue(m_itemLibraryAddImportModel.data()));
|
{"rootView", QVariant::fromValue(this)},
|
||||||
QObject::connect(m_addImportWidget->rootObject(), SIGNAL(addImport(int)), this,
|
});
|
||||||
SLOT(handleAddImport(int)));
|
|
||||||
|
|
||||||
// set up Item Library view and model
|
// set up Item Library view and model
|
||||||
m_itemViewQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_itemViewQuickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
@@ -270,7 +262,7 @@ QList<QToolButton *> ItemLibraryWidget::createToolBarWidgets()
|
|||||||
return buttons;
|
return buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::handleFilterChanged(const QString &filterText)
|
void ItemLibraryWidget::handleSearchfilterChanged(const QString &filterText)
|
||||||
{
|
{
|
||||||
m_filterText = filterText;
|
m_filterText = filterText;
|
||||||
|
|
||||||
@@ -339,11 +331,20 @@ void ItemLibraryWidget::clearSearchFilter()
|
|||||||
|
|
||||||
void ItemLibraryWidget::reloadQmlSource()
|
void ItemLibraryWidget::reloadQmlSource()
|
||||||
{
|
{
|
||||||
QString itemLibraryQmlFilePath = qmlSourcesPath() + QStringLiteral("/ItemsView.qml");
|
const QString libraryHeaderQmlPath = qmlSourcesPath() + "/LibraryHeader.qml";
|
||||||
|
QTC_ASSERT(QFileInfo::exists(libraryHeaderQmlPath), return);
|
||||||
|
m_headerWidget->engine()->clearComponentCache();
|
||||||
|
m_headerWidget->setSource(QUrl::fromLocalFile(libraryHeaderQmlPath));
|
||||||
|
|
||||||
QTC_ASSERT(QFileInfo::exists(itemLibraryQmlFilePath), return);
|
const QString addImportQmlPath = qmlSourcesPath() + "/AddImport.qml";
|
||||||
|
QTC_ASSERT(QFileInfo::exists(addImportQmlPath), return);
|
||||||
|
m_addImportWidget->engine()->clearComponentCache();
|
||||||
|
m_addImportWidget->setSource(QUrl::fromLocalFile(addImportQmlPath));
|
||||||
|
|
||||||
|
const QString itemLibraryQmlPath = qmlSourcesPath() + "/ItemsView.qml";
|
||||||
|
QTC_ASSERT(QFileInfo::exists(itemLibraryQmlPath), return);
|
||||||
m_itemViewQuickWidget->engine()->clearComponentCache();
|
m_itemViewQuickWidget->engine()->clearComponentCache();
|
||||||
m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlFilePath));
|
m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemLibraryWidget::updateModel()
|
void ItemLibraryWidget::updateModel()
|
||||||
|
@@ -91,6 +91,11 @@ public:
|
|||||||
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos);
|
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos);
|
||||||
Q_INVOKABLE void removeImport(const QString &importUrl);
|
Q_INVOKABLE void removeImport(const QString &importUrl);
|
||||||
Q_INVOKABLE void addImportForItem(const QVariant &entry);
|
Q_INVOKABLE void addImportForItem(const QVariant &entry);
|
||||||
|
Q_INVOKABLE void handleTabChanged(int index);
|
||||||
|
Q_INVOKABLE void handleAddModule();
|
||||||
|
Q_INVOKABLE void handleAddAsset();
|
||||||
|
Q_INVOKABLE void handleSearchfilterChanged(const QString &filterText);
|
||||||
|
Q_INVOKABLE void handleAddImport(int index);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void itemActivated(const QString& itemName);
|
void itemActivated(const QString& itemName);
|
||||||
@@ -130,13 +135,6 @@ private:
|
|||||||
bool m_updateRetry = false;
|
bool m_updateRetry = false;
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
QPoint m_dragStartPoint;
|
QPoint m_dragStartPoint;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void handleTabChanged(int index);
|
|
||||||
void handleFilterChanged(const QString &filterText);
|
|
||||||
void handleAddModule();
|
|
||||||
void handleAddAsset();
|
|
||||||
void handleAddImport(int index);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace QmlDesigner
|
||||||
|
@@ -132,6 +132,8 @@ RichTextEditor::RichTextEditor(QWidget *parent)
|
|||||||
this, &RichTextEditor::currentCharFormatChanged);
|
this, &RichTextEditor::currentCharFormatChanged);
|
||||||
connect(ui->textEdit, &QTextEdit::cursorPositionChanged,
|
connect(ui->textEdit, &QTextEdit::cursorPositionChanged,
|
||||||
this, &RichTextEditor::cursorPositionChanged);
|
this, &RichTextEditor::cursorPositionChanged);
|
||||||
|
connect(ui->textEdit, &QTextEdit::textChanged,
|
||||||
|
this, &RichTextEditor::onTextChanged);
|
||||||
connect(m_linkDialog, &QDialog::accepted, [this]() {
|
connect(m_linkDialog, &QDialog::accepted, [this]() {
|
||||||
QTextCharFormat oldFormat = ui->textEdit->textCursor().charFormat();
|
QTextCharFormat oldFormat = ui->textEdit->textCursor().charFormat();
|
||||||
|
|
||||||
@@ -223,6 +225,10 @@ void RichTextEditor::cursorPositionChanged()
|
|||||||
tableChanged(ui->textEdit->textCursor());
|
tableChanged(ui->textEdit->textCursor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RichTextEditor::onTextChanged() {
|
||||||
|
emit textChanged(richText());
|
||||||
|
}
|
||||||
|
|
||||||
void RichTextEditor::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
|
void RichTextEditor::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
|
||||||
{
|
{
|
||||||
QTextCursor cursor = ui->textEdit->textCursor();
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
@@ -69,11 +69,12 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void insertingImage(QString &filePath);
|
void insertingImage(QString &filePath);
|
||||||
|
void textChanged(QString text);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void currentCharFormatChanged(const QTextCharFormat &format);
|
void currentCharFormatChanged(const QTextCharFormat &format);
|
||||||
void cursorPositionChanged();
|
void cursorPositionChanged();
|
||||||
|
void onTextChanged();
|
||||||
private:
|
private:
|
||||||
QIcon getIcon(Theme::Icon icon);
|
QIcon getIcon(Theme::Icon icon);
|
||||||
void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
|
void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
|
||||||
|
@@ -76,6 +76,9 @@ void TextEditItem::setFormEditorItem(FormEditorItem *formEditorItem)
|
|||||||
QSize maximumSize = rect.size().toSize();
|
QSize maximumSize = rect.size().toSize();
|
||||||
activateTextEdit(maximumSize);
|
activateTextEdit(maximumSize);
|
||||||
} else {
|
} else {
|
||||||
|
auto lineEdit = TextEditItemWidget::lineEdit();
|
||||||
|
auto node = m_formEditorItem->qmlItemNode();
|
||||||
|
lineEdit->setFont(node.instanceValue("font").value<QFont>());
|
||||||
activateLineEdit();
|
activateLineEdit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include "nodemetainfo.h"
|
#include "nodemetainfo.h"
|
||||||
#include "qmlitemnode.h"
|
#include "qmlitemnode.h"
|
||||||
|
#include "richtexteditordialog.h"
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
|
|
||||||
#include <abstractaction.h>
|
#include <abstractaction.h>
|
||||||
@@ -207,13 +208,22 @@ void TextTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
|
|||||||
}
|
}
|
||||||
if (!itemList.isEmpty()) {
|
if (!itemList.isEmpty()) {
|
||||||
FormEditorItem *formEditorItem = itemList.constFirst();
|
FormEditorItem *formEditorItem = itemList.constFirst();
|
||||||
m_textItem = new TextEditItem(scene());
|
auto text = formEditorItem->qmlItemNode().instanceValue("text").toString();
|
||||||
textItem()->setParentItem(scene()->manipulatorLayerItem());
|
auto format = formEditorItem->qmlItemNode().instanceValue("format").value<int>();
|
||||||
textItem()->setFormEditorItem(formEditorItem);
|
if (format == Qt::RichText || Qt::mightBeRichText(text)) {
|
||||||
connect(textItem(), &TextEditItem::returnPressed, [this] {
|
RichTextEditorDialog* editorDialog = new RichTextEditorDialog(text);
|
||||||
textItem()->writeTextToProperty();
|
editorDialog->setFormEditorItem(formEditorItem);
|
||||||
|
editorDialog->show();
|
||||||
view()->changeToSelectionTool();
|
view()->changeToSelectionTool();
|
||||||
});
|
} else {
|
||||||
|
m_textItem = new TextEditItem(scene());
|
||||||
|
textItem()->setParentItem(scene()->manipulatorLayerItem());
|
||||||
|
textItem()->setFormEditorItem(formEditorItem);
|
||||||
|
connect(textItem(), &TextEditItem::returnPressed, [this] {
|
||||||
|
textItem()->writeTextToProperty();
|
||||||
|
view()->changeToSelectionTool();
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
view()->changeToSelectionTool();
|
view()->changeToSelectionTool();
|
||||||
}
|
}
|
||||||
|
@@ -205,6 +205,7 @@ public:
|
|||||||
virtual void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList);
|
virtual void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList);
|
||||||
virtual void propertiesRemoved(const QList<AbstractProperty>& propertyList);
|
virtual void propertiesRemoved(const QList<AbstractProperty>& propertyList);
|
||||||
virtual void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange);
|
virtual void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange);
|
||||||
|
virtual void bindingPropertiesAboutToBeChanged(const QList<BindingProperty> &propertyList);
|
||||||
virtual void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChange);
|
virtual void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChange);
|
||||||
virtual void signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty>& propertyList, PropertyChangeFlags propertyChange);
|
virtual void signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty>& propertyList, PropertyChangeFlags propertyChange);
|
||||||
virtual void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion);
|
virtual void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion);
|
||||||
|
@@ -94,7 +94,7 @@ public:
|
|||||||
static bool sameContent(const Comment &a, const Comment &b);
|
static bool sameContent(const Comment &a, const Comment &b);
|
||||||
bool operator==(const Comment &comment) const; //everything is similar.
|
bool operator==(const Comment &comment) const; //everything is similar.
|
||||||
|
|
||||||
bool isEmpty();
|
bool isEmpty() const;
|
||||||
|
|
||||||
QString toQString() const;
|
QString toQString() const;
|
||||||
|
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
#include <qmlprojectmanager/qmlmultilanguageaspect.h>
|
#include <qmlprojectmanager/qmlmultilanguageaspect.h>
|
||||||
|
|
||||||
|
#include <qmlprojectmanager/qmlproject.h>
|
||||||
#include <qtsupport/baseqtversion.h>
|
#include <qtsupport/baseqtversion.h>
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
#include <qtsupport/qtsupportconstants.h>
|
#include <qtsupport/qtsupportconstants.h>
|
||||||
@@ -167,6 +168,20 @@ QString PuppetCreator::getStyleConfigFileName() const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PuppetCreator::usesVirtualKeyboard() const
|
||||||
|
{
|
||||||
|
#ifndef QMLDESIGNER_TEST
|
||||||
|
if (m_target) {
|
||||||
|
auto *qmlbuild = qobject_cast<QmlProjectManager::QmlBuildSystem *>(m_target->buildSystem());
|
||||||
|
|
||||||
|
const Utils::EnvironmentItem virtualKeyboard("QT_IM_MODULE", "qtvirtualkeyboard");
|
||||||
|
return qmlbuild && qmlbuild->environment().indexOf(virtualKeyboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PuppetCreator::PuppetCreator(ProjectExplorer::Target *target, const Model *model)
|
PuppetCreator::PuppetCreator(ProjectExplorer::Target *target, const Model *model)
|
||||||
|
|
||||||
: m_target(target)
|
: m_target(target)
|
||||||
@@ -494,6 +509,11 @@ QProcessEnvironment PuppetCreator::processEnvironment() const
|
|||||||
environment.set("QMLDESIGNER_RC_PATHS", m_qrcMapping);
|
environment.set("QMLDESIGNER_RC_PATHS", m_qrcMapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (usesVirtualKeyboard()) {
|
||||||
|
environment.set("QT_IM_MODULE", "qtvirtualkeyboard");
|
||||||
|
environment.set("QT_VIRTUALKEYBOARD_DESKTOP_DISABLE", "1");
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef QMLDESIGNER_TEST
|
#ifndef QMLDESIGNER_TEST
|
||||||
// set env var if QtQuick3D import exists
|
// set env var if QtQuick3D import exists
|
||||||
QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick3D", "1.0");
|
QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick3D", "1.0");
|
||||||
|
@@ -103,6 +103,7 @@ protected:
|
|||||||
|
|
||||||
bool useOnlyFallbackPuppet() const;
|
bool useOnlyFallbackPuppet() const;
|
||||||
QString getStyleConfigFileName() const;
|
QString getStyleConfigFileName() const;
|
||||||
|
bool usesVirtualKeyboard() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QString m_compileLog;
|
mutable QString m_compileLog;
|
||||||
|
@@ -329,6 +329,8 @@ void AbstractView::variantPropertiesChanged(const QList<VariantProperty>& /*prop
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractView::bindingPropertiesAboutToBeChanged(const QList<BindingProperty> &) {}
|
||||||
|
|
||||||
void AbstractView::bindingPropertiesChanged(const QList<BindingProperty>& /*propertyList*/, PropertyChangeFlags /*propertyChange*/)
|
void AbstractView::bindingPropertiesChanged(const QList<BindingProperty>& /*propertyList*/, PropertyChangeFlags /*propertyChange*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@@ -133,7 +133,7 @@ bool Comment::operator==(const Comment &comment) const
|
|||||||
return (sameContent(comment) && (m_timestamp == comment.timestamp()));
|
return (sameContent(comment) && (m_timestamp == comment.timestamp()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Comment::isEmpty()
|
bool Comment::isEmpty() const
|
||||||
{
|
{
|
||||||
return sameContent(Comment());
|
return sameContent(Comment());
|
||||||
}
|
}
|
||||||
|
@@ -767,6 +767,21 @@ void ModelPrivate::notifyNodeIdChanged(const InternalNodePointer &node,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelPrivate::notifyBindingPropertiesAboutToBeChanged(
|
||||||
|
const QList<InternalBindingPropertyPointer> &internalPropertyList)
|
||||||
|
{
|
||||||
|
notifyNodeInstanceViewLast([&](AbstractView *view) {
|
||||||
|
QList<BindingProperty> propertyList;
|
||||||
|
for (const InternalBindingPropertyPointer &bindingProperty : internalPropertyList) {
|
||||||
|
propertyList.append(BindingProperty(bindingProperty->name(),
|
||||||
|
bindingProperty->propertyOwner(),
|
||||||
|
m_model,
|
||||||
|
view));
|
||||||
|
}
|
||||||
|
view->bindingPropertiesAboutToBeChanged(propertyList);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ModelPrivate::notifyBindingPropertiesChanged(
|
void ModelPrivate::notifyBindingPropertiesChanged(
|
||||||
const QList<InternalBindingPropertyPointer> &internalPropertyList,
|
const QList<InternalBindingPropertyPointer> &internalPropertyList,
|
||||||
AbstractView::PropertyChangeFlags propertyChange)
|
AbstractView::PropertyChangeFlags propertyChange)
|
||||||
@@ -1030,6 +1045,7 @@ void ModelPrivate::setBindingProperty(const InternalNodePointer &node, const Pro
|
|||||||
}
|
}
|
||||||
|
|
||||||
InternalBindingPropertyPointer bindingProperty = node->bindingProperty(name);
|
InternalBindingPropertyPointer bindingProperty = node->bindingProperty(name);
|
||||||
|
notifyBindingPropertiesAboutToBeChanged({bindingProperty});
|
||||||
bindingProperty->setExpression(expression);
|
bindingProperty->setExpression(expression);
|
||||||
notifyBindingPropertiesChanged({bindingProperty}, propertyChange);
|
notifyBindingPropertiesChanged({bindingProperty}, propertyChange);
|
||||||
}
|
}
|
||||||
@@ -1087,6 +1103,7 @@ void ModelPrivate::setDynamicBindingProperty(const InternalNodePointer &node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
InternalBindingPropertyPointer bindingProperty = node->bindingProperty(name);
|
InternalBindingPropertyPointer bindingProperty = node->bindingProperty(name);
|
||||||
|
notifyBindingPropertiesAboutToBeChanged({bindingProperty});
|
||||||
bindingProperty->setDynamicExpression(dynamicPropertyType, expression);
|
bindingProperty->setDynamicExpression(dynamicPropertyType, expression);
|
||||||
notifyBindingPropertiesChanged({bindingProperty}, propertyChange);
|
notifyBindingPropertiesChanged({bindingProperty}, propertyChange);
|
||||||
}
|
}
|
||||||
|
@@ -149,6 +149,8 @@ public:
|
|||||||
|
|
||||||
void notifyPropertiesRemoved(const QList<PropertyPair> &propertyList);
|
void notifyPropertiesRemoved(const QList<PropertyPair> &propertyList);
|
||||||
void notifyPropertiesAboutToBeRemoved(const QList<InternalPropertyPointer> &internalPropertyList);
|
void notifyPropertiesAboutToBeRemoved(const QList<InternalPropertyPointer> &internalPropertyList);
|
||||||
|
void notifyBindingPropertiesAboutToBeChanged(
|
||||||
|
const QList<InternalBindingPropertyPointer> &internalPropertyList);
|
||||||
void notifyBindingPropertiesChanged(const QList<InternalBindingPropertyPointer> &internalPropertyList, AbstractView::PropertyChangeFlags propertyChange);
|
void notifyBindingPropertiesChanged(const QList<InternalBindingPropertyPointer> &internalPropertyList, AbstractView::PropertyChangeFlags propertyChange);
|
||||||
void notifySignalHandlerPropertiesChanged(const QVector<InternalSignalHandlerPropertyPointer> &propertyList, AbstractView::PropertyChangeFlags propertyChange);
|
void notifySignalHandlerPropertiesChanged(const QVector<InternalSignalHandlerPropertyPointer> &propertyList, AbstractView::PropertyChangeFlags propertyChange);
|
||||||
void notifyVariantPropertiesChanged(const InternalNodePointer &node, const PropertyNameList &propertyNameList, AbstractView::PropertyChangeFlags propertyChange);
|
void notifyVariantPropertiesChanged(const InternalNodePointer &node, const PropertyNameList &propertyNameList, AbstractView::PropertyChangeFlags propertyChange);
|
||||||
|
@@ -10,7 +10,8 @@ HEADERS += $$PWD/qmldesignerconstants.h \
|
|||||||
$$PWD/documentwarningwidget.h \
|
$$PWD/documentwarningwidget.h \
|
||||||
$$PWD/qmldesignericons.h \
|
$$PWD/qmldesignericons.h \
|
||||||
$$PWD/openuiqmlfiledialog.h \
|
$$PWD/openuiqmlfiledialog.h \
|
||||||
$$PWD/designermcumanager.h
|
$$PWD/designermcumanager.h \
|
||||||
|
$$PWD/richtexteditordialog.h
|
||||||
|
|
||||||
SOURCES += $$PWD/qmldesignerplugin.cpp \
|
SOURCES += $$PWD/qmldesignerplugin.cpp \
|
||||||
$$PWD/shortcutmanager.cpp \
|
$$PWD/shortcutmanager.cpp \
|
||||||
@@ -22,7 +23,8 @@ SOURCES += $$PWD/qmldesignerplugin.cpp \
|
|||||||
$$PWD/documentmanager.cpp \
|
$$PWD/documentmanager.cpp \
|
||||||
$$PWD/documentwarningwidget.cpp \
|
$$PWD/documentwarningwidget.cpp \
|
||||||
$$PWD/openuiqmlfiledialog.cpp \
|
$$PWD/openuiqmlfiledialog.cpp \
|
||||||
$$PWD/designermcumanager.cpp
|
$$PWD/designermcumanager.cpp \
|
||||||
|
$$PWD/richtexteditordialog.cpp
|
||||||
|
|
||||||
FORMS += $$PWD/settingspage.ui \
|
FORMS += $$PWD/settingspage.ui \
|
||||||
$$PWD/openuiqmlfiledialog.ui
|
$$PWD/openuiqmlfiledialog.ui
|
||||||
|
@@ -984,6 +984,8 @@ Project {
|
|||||||
"shortcutmanager.h",
|
"shortcutmanager.h",
|
||||||
"designermcumanager.cpp",
|
"designermcumanager.cpp",
|
||||||
"designermcumanager.h",
|
"designermcumanager.h",
|
||||||
|
"richtexteditordialog.cpp",
|
||||||
|
"richtexteditordialog.h",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
76
src/plugins/qmldesigner/richtexteditordialog.cpp
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "richtexteditordialog.h"
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
RichTextEditorDialog::RichTextEditorDialog(QString text)
|
||||||
|
{
|
||||||
|
m_editor = new RichTextEditor(this);
|
||||||
|
m_editor->setRichText(text);
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
layout->addWidget(m_editor);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
connect(m_editor, &RichTextEditor::textChanged,
|
||||||
|
this, &RichTextEditorDialog::onTextChanged);
|
||||||
|
|
||||||
|
connect(this, &QDialog::finished,
|
||||||
|
this, &RichTextEditorDialog::onFinished);
|
||||||
|
|
||||||
|
setModal(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditorDialog::setFormEditorItem(FormEditorItem* formEditorItem)
|
||||||
|
{
|
||||||
|
m_formEditorItem = formEditorItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditorDialog::onTextChanged(QString text)
|
||||||
|
{
|
||||||
|
Q_UNUSED(text);
|
||||||
|
// TODO: try adding following and make it react faster
|
||||||
|
// setTextToFormEditorItem(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditorDialog::onFinished()
|
||||||
|
{
|
||||||
|
setTextToFormEditorItem(m_editor->richText());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RichTextEditorDialog::setTextToFormEditorItem(QString text)
|
||||||
|
{
|
||||||
|
if (m_formEditorItem) {
|
||||||
|
if (text.isEmpty())
|
||||||
|
m_formEditorItem->qmlItemNode().removeProperty("text");
|
||||||
|
else
|
||||||
|
m_formEditorItem->qmlItemNode().setVariantProperty("text", text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} //namespace QmlDesigner
|
56
src/plugins/qmldesigner/richtexteditordialog.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef RICHTEXTEDITORDIALOG_H
|
||||||
|
#define RICHTEXTEDITORDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "richtexteditor/richtexteditor.h"
|
||||||
|
#include "formeditor/formeditoritem.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
|
||||||
|
class RichTextEditorDialog : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit RichTextEditorDialog(const QString text);
|
||||||
|
void setFormEditorItem(FormEditorItem* formEditorItem);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void textChanged(QString text);
|
||||||
|
private:
|
||||||
|
RichTextEditor* m_editor;
|
||||||
|
FormEditorItem* m_formEditorItem;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onTextChanged(QString text);
|
||||||
|
void onFinished();
|
||||||
|
void setTextToFormEditorItem(QString text);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
||||||
|
|
||||||
|
#endif // RICHTEXTEDITORDIALOG_H
|
@@ -47,7 +47,7 @@ static Utils::FilePath getMultilanguageDatabaseFilePath(ProjectExplorer::Target
|
|||||||
{
|
{
|
||||||
if (target) {
|
if (target) {
|
||||||
auto filePath = target->project()->projectDirectory().pathAppended(
|
auto filePath = target->project()->projectDirectory().pathAppended(
|
||||||
"multilanguage-experimental-v3.db");
|
"multilanguage-experimental-v4.db");
|
||||||
if (filePath.exists())
|
if (filePath.exists())
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|