Merge remote-tracking branch 'origin/4.15'

Change-Id: Ia0cf8d72871437386bf8ad16a8e101bd9d97cc73
This commit is contained in:
Eike Ziller
2021-03-09 13:17:52 +01:00
54 changed files with 574 additions and 291 deletions

View File

@@ -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

View File

@@ -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
} }
} }

View File

@@ -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

View File

@@ -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
bottomPadding: 4
contentItem: Item {
implicitHeight: plusButton.height
Text { // TabButton text
text: modelData.title text: modelData.title
font.pixelSize: 13 font.pixelSize: 13
font.bold: true font.bold: true
color: tabBar.currentIndex === index ? "#0094ce" : "#dadada" color: tabBar.currentIndex === index ? "#0094ce" : "#dadada"
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: plusButton.left
anchors.bottomMargin: 2 anchors.bottomMargin: 2
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
elide: Text.ElideRight elide: Text.ElideRight
} }
background: Item { // TabButton background
Rectangle { // + button Rectangle { // + button
id: plusButton
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.top: parent.top
anchors.rightMargin: 2 anchors.topMargin: 1
anchors.bottomMargin: 2 width: 24
width: img.width + 10 height: 24
height: img.height + 10
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 = ""
} }

View File

@@ -716,7 +716,7 @@ StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
break; break;
} }
return StringType{"", 0}; return {};
} }
} // namespace } // namespace

View File

@@ -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)
{ {

View File

@@ -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

View File

@@ -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();

View File

@@ -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;

View File

@@ -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)

View File

@@ -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

View File

@@ -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,19 +924,38 @@ 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;
process.setEnvironment(environment);
process.setWorkingDirectory(workingDirectory);
process.start(cmd.executable().toString(), cmd.splitArguments(), QIODevice::ReadOnly);
if (!process.waitForStarted(1000) || !process.waitForFinished(1000)) {
if (process.state() == QProcess::NotRunning)
return;
process.terminate();
if (process.waitForFinished(1000))
return;
process.kill();
process.waitForFinished(1000);
return;
}
if (process.exitCode() || process.exitStatus() != QProcess::NormalExit)
return;
futureInterface.reportResult(process.readAllStandardOutput());
});
Utils::onFinished(future, this, [this](const QFuture<QByteArray> &future) {
if (future.resultCount()) {
const QJsonDocument json = QJsonDocument::fromJson(future.result());
if (!json.isEmpty() && json.isObject()) { if (!json.isEmpty() && json.isObject()) {
const QJsonObject jsonObj = json.object(); const QJsonObject jsonObj = json.object();
const QJsonObject btGraph = jsonObj.value("backtraceGraph").toObject(); const QJsonObject btGraph = jsonObj.value("backtraceGraph").toObject();
@@ -949,14 +971,15 @@ void CMakeBuildSystem::runCTest()
int file = btRef.value("file").toInt(-1); int file = btRef.value("file").toInt(-1);
int line = btRef.value("line").toInt(-1); int line = btRef.value("line").toInt(-1);
QTC_ASSERT(file != -1 && line != -1, continue); QTC_ASSERT(file != -1 && line != -1, continue);
m_testNames.append({test.value("name").toString(), m_testNames.append({ test.value("name").toString(),
FilePath::fromString(cmakelists.at(file).toString()), FilePath::fromString(cmakelists.at(file).toString()), line });
line
});
} }
} }
} }
emit testInformationUpdated(); emit testInformationUpdated();
});
m_futureSynchronizer.addFuture(future);
} }
CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const CMakeBuildConfiguration *CMakeBuildSystem::cmakeBuildConfiguration() const

View File

@@ -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

View File

@@ -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
@@ -4921,7 +4902,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.
} }

View File

@@ -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();

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 B

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();

View File

@@ -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();
} }

View File

@@ -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();

View File

@@ -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()

View File

@@ -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

View File

@@ -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();

View File

@@ -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);

View File

@@ -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();
} }

View File

@@ -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,6 +208,14 @@ void TextTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
} }
if (!itemList.isEmpty()) { if (!itemList.isEmpty()) {
FormEditorItem *formEditorItem = itemList.constFirst(); FormEditorItem *formEditorItem = itemList.constFirst();
auto text = formEditorItem->qmlItemNode().instanceValue("text").toString();
auto format = formEditorItem->qmlItemNode().instanceValue("format").value<int>();
if (format == Qt::RichText || Qt::mightBeRichText(text)) {
RichTextEditorDialog* editorDialog = new RichTextEditorDialog(text);
editorDialog->setFormEditorItem(formEditorItem);
editorDialog->show();
view()->changeToSelectionTool();
} else {
m_textItem = new TextEditItem(scene()); m_textItem = new TextEditItem(scene());
textItem()->setParentItem(scene()->manipulatorLayerItem()); textItem()->setParentItem(scene()->manipulatorLayerItem());
textItem()->setFormEditorItem(formEditorItem); textItem()->setFormEditorItem(formEditorItem);
@@ -214,6 +223,7 @@ void TextTool::selectedItemsChanged(const QList<FormEditorItem*> &itemList)
textItem()->writeTextToProperty(); textItem()->writeTextToProperty();
view()->changeToSelectionTool(); view()->changeToSelectionTool();
}); });
}
} else { } else {
view()->changeToSelectionTool(); view()->changeToSelectionTool();
} }

View File

@@ -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);

View File

@@ -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;

View File

@@ -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");

View File

@@ -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;

View File

@@ -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*/)
{ {
} }

View File

@@ -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());
} }

View File

@@ -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);
} }

View File

@@ -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);

View File

@@ -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

View File

@@ -984,6 +984,8 @@ Project {
"shortcutmanager.h", "shortcutmanager.h",
"designermcumanager.cpp", "designermcumanager.cpp",
"designermcumanager.h", "designermcumanager.h",
"richtexteditordialog.cpp",
"richtexteditordialog.h",
] ]
} }
} }

View 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

View 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

View File

@@ -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;
} }