Merge remote-tracking branch 'origin/4.14'

Change-Id: I62523c4733e617c46131048f5f62a2ca9be47d80
This commit is contained in:
Eike Ziller
2021-01-06 08:42:15 +01:00
19 changed files with 425 additions and 156 deletions

View File

@@ -16,7 +16,7 @@ https://doc.qt.io/qtcreator/creator-overview.html
The standalone binary packages support the following platforms: The standalone binary packages support the following platforms:
* Windows 7 or later * Windows 7 (64-bit) or later
* (K)Ubuntu Linux 18.04 (64-bit) or later * (K)Ubuntu Linux 18.04 (64-bit) or later
* macOS 10.13 or later * macOS 10.13 or later

View File

@@ -74,7 +74,7 @@
\section1 Windows \section1 Windows
Windows 7 or later is supported. Windows 7 (64-bit) or later is supported.
\note Some \QC plugins rely on Direct3D (part of DirectX). You might \note Some \QC plugins rely on Direct3D (part of DirectX). You might
have to manually enable support for it if you are running Windows in a have to manually enable support for it if you are running Windows in a

View File

@@ -3060,6 +3060,9 @@ class DumperBase():
def extractPointer(self): def extractPointer(self):
return self.split('p')[0] return self.split('p')[0]
def hasMember(self, name):
return self.findMemberByName(name) is not None
def findMemberByName(self, name): def findMemberByName(self, name):
self.check() self.check()
if self.type.code == TypeCode.Typedef: if self.type.code == TypeCode.Typedef:

View File

@@ -76,12 +76,26 @@ def qdump__std____1__complex(d, value):
def qdump__std__deque(d, value): def qdump__std__deque(d, value):
if d.isQnxTarget(): if d.isQnxTarget():
qdump__std__deque__QNX(d, value) qdumpHelper__std__deque__qnx(d, value)
return elif d.isMsvcTarget():
if d.isMsvcTarget(): qdumpHelper__std__deque__msvc(d, value)
qdump__std__deque__MSVC(d, value) elif value.hasMember("_M_impl"):
return qdumpHelper__std__deque__libstdcxx(d, value)
elif value.hasMember("__start_"):
qdumpHelper__std__deque__libcxx(d, value)
elif value.type.size() == 10 * d.ptrSize():
qdumpHelper__std__deque__libstdcxx(d, value)
elif value.type.size() == 6 * d.ptrSize():
qdumpHelper__std__deque__libcxx(d, value)
else:
qdumpHelper__std__deque__libstdcxx(d, value)
def qdump__std____1__deque(d, value):
qdumpHelper__std__deque__libcxx(d, value)
def qdumpHelper__std__deque__libstdcxx(d, value):
innerType = value.type[0] innerType = value.type[0]
innerSize = innerType.size() innerSize = innerType.size()
bufsize = 1 bufsize = 1
@@ -113,7 +127,7 @@ def qdump__std__deque(d, value):
pnode = newnode pnode = newnode
def qdump__std____1__deque(d, value): def qdumpHelper__std__deque__libcxx(d, value):
mptr, mfirst, mbegin, mend, start, size = value.split("pppptt") mptr, mfirst, mbegin, mend, start, size = value.split("pppptt")
d.check(0 <= size and size <= 1000 * 1000 * 1000) d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size) d.putItemCount(size)
@@ -129,7 +143,7 @@ def qdump__std____1__deque(d, value):
d.putSubItem(i, d.createValue(base + j * innerSize, innerType)) d.putSubItem(i, d.createValue(base + j * innerSize, innerType))
def qdump__std__deque__QNX(d, value): def qdumpHelper__std__deque__qnx(d, value):
innerType = value.type[0] innerType = value.type[0]
innerSize = innerType.size() innerSize = innerType.size()
if innerSize <= 1: if innerSize <= 1:
@@ -166,7 +180,7 @@ def qdump__std__deque__QNX(d, value):
myoff += 1 myoff += 1
def qdump__std__deque__MSVC(d, value): def qdumpHelper__std__deque__msvc(d, value):
innerType = value.type[0] innerType = value.type[0]
innerSize = innerType.size() innerSize = innerType.size()
if innerSize <= 1: if innerSize <= 1:
@@ -1048,95 +1062,88 @@ def qedit__std__vector(d, value, data):
def qdump__std__vector(d, value): def qdump__std__vector(d, value):
if d.isQnxTarget() or d.isMsvcTarget(): if d.isQnxTarget() or d.isMsvcTarget():
qdumpHelper__std__vector__QNX(d, value) qdumpHelper__std__vector__msvc(d, value)
elif value.hasMember("_M_impl"):
qdumpHelper__std__vector__libstdcxx(d, value)
elif value.hasMember("__begin_"):
qdumpHelper__std__vector__libcxx(d, value)
else: else:
qdumpHelper__std__vector(d, value, False) qdumpHelper__std__vector__libstdcxx(d, value)
def qdumpHelper__std__vector(d, value, isLibCpp): def qdumpHelper__std__vector__nonbool(d, start, finish, alloc, inner_type):
innerType = value.type[0] size = int((finish - start) / inner_type.size())
isBool = innerType.name == 'bool' d.check(finish <= alloc)
if isBool:
if isLibCpp:
start = value["__begin_"].pointer()
size = value["__size_"].integer()
alloc = size
else:
start = value["_M_start"]["_M_p"].pointer()
soffset = value["_M_start"]["_M_offset"].integer()
finish = value["_M_finish"]["_M_p"].pointer()
foffset = value["_M_finish"]["_M_offset"].integer()
alloc = value["_M_end_of_storage"].pointer()
size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT.
else:
if isLibCpp:
start = value["__begin_"].pointer()
finish = value["__end_"].pointer()
alloc = value["__end_cap_"].pointer()
else:
start = value["_M_start"].pointer()
finish = value["_M_finish"].pointer()
alloc = value["_M_end_of_storage"].pointer()
size = int((finish - start) / innerType.size())
d.check(finish <= alloc)
if size > 0:
d.checkPointer(start)
d.checkPointer(finish)
d.checkPointer(alloc)
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size)
if isBool:
if d.isExpanded():
with Children(d, size, maxNumChild=10000, childType=innerType):
for i in d.childRange():
q = start + int(i / 8)
with SubItem(d, i):
d.putValue((int(d.extractPointer(q)) >> (i % 8)) & 1)
d.putType("bool")
else:
d.putPlotData(start, size, innerType)
def qdumpHelper__std__vector__QNX(d, value):
innerType = value.type[0]
isBool = innerType.name == 'bool'
if isBool:
(proxy1, proxy2, start, last, end, size) = value.split("pppppi")
else:
(proxy, start, last, end) = value.split("pppp")
size = (last - start) // innerType.size()
try:
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.check(last <= end)
except RuntimeError:
if isBool:
(start, last, end, size) = value.split("pppi")
else:
(start, last, end) = value.split("ppp")
size = (last - start) // innerType.size()
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.check(last <= end)
if size > 0: if size > 0:
d.checkPointer(start) d.checkPointer(start)
d.checkPointer(last) d.checkPointer(finish)
d.checkPointer(end) d.checkPointer(alloc)
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size)
d.putPlotData(start, size, inner_type)
def qdumpHelper__std__vector__bool(d, start, size, inner_type):
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size) d.putItemCount(size)
if d.isExpanded(): if d.isExpanded():
if isBool: with Children(d, size, maxNumChild=10000, childType=inner_type):
with Children(d, size, maxNumChild=10000, childType=innerType): for i in d.childRange():
for i in d.childRange(): q = start + int(i / 8)
q = start + int(i / 8) with SubItem(d, i):
with SubItem(d, i): d.putValue((int(d.extractPointer(q)) >> (i % 8)) & 1)
d.putValue((d.extractPointer(q) >> (i % 8)) & 1) d.putType("bool")
d.putType("bool")
else:
d.putPlotData(start, size, innerType) def qdumpHelper__std__vector__libstdcxx(d, value):
inner_type = value.type[0]
if inner_type.name == "bool":
start = value["_M_start"]["_M_p"].pointer()
soffset = value["_M_start"]["_M_offset"].integer()
finish = value["_M_finish"]["_M_p"].pointer()
foffset = value["_M_finish"]["_M_offset"].integer()
alloc = value["_M_end_of_storage"].pointer()
size = (finish - start) * 8 + foffset - soffset # 8 is CHAR_BIT.
qdumpHelper__std__vector__bool(d, start, size, inner_type)
else:
start = value["_M_start"].pointer()
finish = value["_M_finish"].pointer()
alloc = value["_M_end_of_storage"].pointer()
qdumpHelper__std__vector__nonbool(d, start, finish, alloc, inner_type)
def qdumpHelper__std__vector__libcxx(d, value):
inner_type = value.type[0]
if inner_type.name == "bool":
start = value["__begin_"].pointer()
size = value["__size_"].integer()
qdumpHelper__std__vector__bool(d, start, size, inner_type)
else:
start = value["__begin_"].pointer()
finish = value["__end_"].pointer()
alloc = value["__end_cap_"].pointer()
qdumpHelper__std__vector__nonbool(d, start, finish, alloc, inner_type)
def qdumpHelper__std__vector__msvc(d, value):
inner_type = value.type[0]
if inner_type.name == "bool":
proxy1, proxy2, start, finish, alloc, size = value.split("pppppi")
try:
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.check(finish <= alloc)
except RuntimeError:
start, finish, alloc, size = value.split("pppi")
qdumpHelper__std__vector__bool(d, start, size, inner_type)
else:
proxy, start, finish, alloc = value.split("pppp")
size = (finish - start) // inner_type.size()
try:
d.check(0 <= size and size <= 1000 * 1000 * 1000)
d.check(finish <= alloc)
except RuntimeError:
start, finish, alloc = value.split("ppp")
qdumpHelper__std__vector__nonbool(d, start, finish, alloc, inner_type)
def qform__std____1__vector(): def qform__std____1__vector():
@@ -1144,7 +1151,7 @@ def qform__std____1__vector():
def qdump__std____1__vector(d, value): def qdump__std____1__vector(d, value):
qdumpHelper__std__vector(d, value, True) qdumpHelper__std__vector__libcxx(d, value)
def qform__std____debug__vector(): def qform__std____debug__vector():

View File

@@ -40,6 +40,7 @@
#include <QFormLayout> #include <QFormLayout>
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
#include <QListWidget>
#include <QPointer> #include <QPointer>
#include <QRadioButton> #include <QRadioButton>
#include <QSpinBox> #include <QSpinBox>
@@ -292,6 +293,23 @@ public:
QString m_tooltip; QString m_tooltip;
}; };
class MultiSelectionAspectPrivate
{
public:
QStringList m_value;
QStringList m_allValues;
MultiSelectionAspect::DisplayStyle m_displayStyle
= MultiSelectionAspect::DisplayStyle::ListView;
QString m_labelText;
// These are all owned by the configuration widget.
QPointer<QListWidget> m_listView;
QPointer<QLabel> m_label;
void updateListView();
bool setValueSelectedHelper(const QString &value, bool on);
};
class StringAspectPrivate class StringAspectPrivate
{ {
public: public:
@@ -1145,6 +1163,129 @@ void SelectionAspect::addOption(const QString &displayName, const QString &toolT
d->m_options.append({displayName, toolTip}); d->m_options.append({displayName, toolTip});
} }
/*!
\class Utils::MultiSelectionAspect
\inmodule QtCreator
\brief A multi-selection aspect represents one or more choices out of
several.
The multi-selection aspect is displayed using a QListWidget with
checkable items.
*/
MultiSelectionAspect::MultiSelectionAspect()
: d(new Internal::MultiSelectionAspectPrivate)
{}
/*!
\reimp
*/
MultiSelectionAspect::~MultiSelectionAspect() = default;
/*!
\reimp
*/
void MultiSelectionAspect::addToLayout(LayoutBuilder &builder)
{
QTC_CHECK(d->m_listView == nullptr);
if (d->m_allValues.isEmpty())
return;
switch (d->m_displayStyle) {
case DisplayStyle::ListView:
d->m_label = new QLabel(d->m_labelText);
d->m_listView = new QListWidget;
for (const QString &value : qAsConst(d->m_allValues)) {
auto item = new QListWidgetItem(value, d->m_listView);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(d->m_value.contains(item->text()) ? Qt::Checked : Qt::Unchecked);
}
connect(d->m_listView, &QListWidget::itemChanged, this,
[this](QListWidgetItem *item) {
if (d->setValueSelectedHelper(item->text(), item->checkState() & Qt::Checked))
emit changed();
});
builder.addItems({d->m_label.data(), d->m_listView.data()});
}
}
bool Internal::MultiSelectionAspectPrivate::setValueSelectedHelper(const QString &value, bool on)
{
if (on && !m_value.contains(value)) {
m_value.append(value);
return true;
}
if (!on && m_value.contains(value)) {
m_value.removeOne(value);
return true;
}
return false;
}
QStringList MultiSelectionAspect::allValues() const
{
return d->m_allValues;
}
void MultiSelectionAspect::setAllValues(const QStringList &val)
{
d->m_allValues = val;
}
void MultiSelectionAspect::setLabelText(const QString &labelText)
{
d->m_labelText = labelText;
}
void Internal::MultiSelectionAspectPrivate::updateListView()
{
if (!m_listView)
return;
const int n = m_listView->count();
QTC_CHECK(n == m_allValues.size());
for (int i = 0; i != n; ++i) {
auto item = m_listView->item(i);
item->setCheckState(m_value.contains(item->text()) ? Qt::Checked : Qt::Unchecked);
}
}
/*!
\reimp
*/
void MultiSelectionAspect::fromMap(const QVariantMap &map)
{
d->m_value = map.value(settingsKey(), QStringList()).toStringList();
}
/*!
\reimp
*/
void MultiSelectionAspect::toMap(QVariantMap &data) const
{
saveToMap(data, d->m_value, QStringList());
}
void MultiSelectionAspect::setDisplayStyle(MultiSelectionAspect::DisplayStyle style)
{
d->m_displayStyle = style;
}
QStringList MultiSelectionAspect::value() const
{
return d->m_value;
}
void MultiSelectionAspect::setValue(const QStringList &value)
{
if (d->m_value == value)
return;
d->m_value = value;
d->updateListView();
emit changed();
}
/*! /*!
\class Utils::IntegerAspect \class Utils::IntegerAspect
\inmodule QtCreator \inmodule QtCreator

View File

@@ -45,6 +45,7 @@ class AspectContainerPrivate;
class BaseAspectPrivate; class BaseAspectPrivate;
class BoolAspectPrivate; class BoolAspectPrivate;
class IntegerAspectPrivate; class IntegerAspectPrivate;
class MultiSelectionAspectPrivate;
class SelectionAspectPrivate; class SelectionAspectPrivate;
class StringAspectPrivate; class StringAspectPrivate;
class StringListAspectPrivate; class StringListAspectPrivate;
@@ -96,7 +97,6 @@ private:
class QTCREATOR_UTILS_EXPORT BaseAspects class QTCREATOR_UTILS_EXPORT BaseAspects
{ {
BaseAspects(const BaseAspects &) = delete; BaseAspects(const BaseAspects &) = delete;
BaseAspects &operator=(const BaseAspects &) = delete; BaseAspects &operator=(const BaseAspects &) = delete;
@@ -201,6 +201,34 @@ private:
std::unique_ptr<Internal::SelectionAspectPrivate> d; std::unique_ptr<Internal::SelectionAspectPrivate> d;
}; };
class QTCREATOR_UTILS_EXPORT MultiSelectionAspect : public BaseAspect
{
Q_OBJECT
public:
MultiSelectionAspect();
~MultiSelectionAspect() override;
void addToLayout(LayoutBuilder &builder) override;
enum class DisplayStyle { ListView };
void setDisplayStyle(DisplayStyle style);
QStringList value() const;
void setValue(const QStringList &val);
QStringList allValues() const;
void setAllValues(const QStringList &val);
void setLabelText(const QString &labelText);
void fromMap(const QVariantMap &map) override;
void toMap(QVariantMap &map) const override;
private:
std::unique_ptr<Internal::MultiSelectionAspectPrivate> d;
};
class QTCREATOR_UTILS_EXPORT StringAspect : public BaseAspect class QTCREATOR_UTILS_EXPORT StringAspect : public BaseAspect
{ {
Q_OBJECT Q_OBJECT

View File

@@ -49,10 +49,10 @@ MakeStep::MakeStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id)
{ {
setAvailableBuildTargets({"all", "clean"}); setAvailableBuildTargets({"all", "clean"});
if (bsl->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) { if (bsl->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
setBuildTarget("clean", true); setSelectedBuildTarget("clean");
setIgnoreReturnValue(true); setIgnoreReturnValue(true);
} else { } else {
setBuildTarget("all", true); setSelectedBuildTarget("all");
} }
} }

View File

@@ -51,7 +51,7 @@ void HeaderPathFilter::process()
for (const HeaderPath &headerPath : headerPaths) for (const HeaderPath &headerPath : headerPaths)
filterHeaderPath(headerPath); filterHeaderPath(headerPath);
if (useTweakedHeaderPaths == UseTweakedHeaderPaths::Yes) if (useTweakedHeaderPaths != UseTweakedHeaderPaths::No)
tweakHeaderPaths(); tweakHeaderPaths();
} }

View File

@@ -43,13 +43,13 @@ public:
GenericMakeStep::GenericMakeStep(BuildStepList *parent, Utils::Id id) GenericMakeStep::GenericMakeStep(BuildStepList *parent, Utils::Id id)
: MakeStep(parent, id) : MakeStep(parent, id)
{ {
setAvailableBuildTargets({"all", "clean"});
if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_BUILD) { if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_BUILD) {
setBuildTarget("all"); setSelectedBuildTarget("all");
} else if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) { } else if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) {
setBuildTarget("clean"); setSelectedBuildTarget("clean");
setIgnoreReturnValue(true); setIgnoreReturnValue(true);
} }
setAvailableBuildTargets({"all", "clean"});
} }
GenericMakeStepFactory::GenericMakeStepFactory() GenericMakeStepFactory::GenericMakeStepFactory()

View File

@@ -49,8 +49,6 @@
#include <QFormLayout> #include <QFormLayout>
#include <QLabel> #include <QLabel>
#include <QLineEdit> #include <QLineEdit>
#include <QListWidget>
#include <QSpinBox>
#include <QThread> #include <QThread>
using namespace Core; using namespace Core;
@@ -105,8 +103,9 @@ MakeStep::MakeStep(BuildStepList *parent, Id id)
.arg(text) + "</p></body></html>"); .arg(text) + "</p></body></html>");
m_nonOverrideWarning->setIconType(InfoLabel::Warning); m_nonOverrideWarning->setIconType(InfoLabel::Warning);
m_buildTargetsAspect = addAspect<StringListAspect>(); m_buildTargetsAspect = addAspect<MultiSelectionAspect>();
m_buildTargetsAspect->setSettingsKey(id.withSuffix(BUILD_TARGETS_SUFFIX).toString()); m_buildTargetsAspect->setSettingsKey(id.withSuffix(BUILD_TARGETS_SUFFIX).toString());
m_buildTargetsAspect->setLabelText(tr("Targets:"));
const auto updateMakeLabel = [this] { const auto updateMakeLabel = [this] {
const QString defaultMake = defaultMakeCommand().toString(); const QString defaultMake = defaultMakeCommand().toString();
@@ -121,15 +120,14 @@ MakeStep::MakeStep(BuildStepList *parent, Id id)
connect(m_makeCommandAspect, &StringAspect::changed, this, updateMakeLabel); connect(m_makeCommandAspect, &StringAspect::changed, this, updateMakeLabel);
} }
void MakeStep::setBuildTarget(const QString &buildTarget) void MakeStep::setSelectedBuildTarget(const QString &buildTarget)
{ {
if (!buildTarget.isEmpty()) m_buildTargetsAspect->setValue({buildTarget});
setBuildTarget(buildTarget, true);
} }
void MakeStep::setAvailableBuildTargets(const QStringList &buildTargets) void MakeStep::setAvailableBuildTargets(const QStringList &buildTargets)
{ {
m_availableTargets = buildTargets; m_buildTargetsAspect->setAllValues(buildTargets);
} }
bool MakeStep::init() bool MakeStep::init()
@@ -342,11 +340,6 @@ QWidget *MakeStep::createConfigWidget()
{ {
auto widget = new QWidget; auto widget = new QWidget;
auto targetsLabel = new QLabel(widget);
targetsLabel->setText(tr("Targets:"));
auto targetsList = new QListWidget(widget);
auto disableInSubDirsLabel = new QLabel(tr("Disable in subdirectories:"), widget); auto disableInSubDirsLabel = new QLabel(tr("Disable in subdirectories:"), widget);
auto disableInSubDirsCheckBox = new QCheckBox(widget); auto disableInSubDirsCheckBox = new QCheckBox(widget);
disableInSubDirsCheckBox->setToolTip(tr("Runs this step only for a top-level build.")); disableInSubDirsCheckBox->setToolTip(tr("Runs this step only for a top-level build."));
@@ -356,7 +349,7 @@ QWidget *MakeStep::createConfigWidget()
builder.addRow(m_userArgumentsAspect); builder.addRow(m_userArgumentsAspect);
builder.addRow(m_jobCountContainer); builder.addRow(m_jobCountContainer);
builder.addRow({disableInSubDirsLabel, disableInSubDirsCheckBox}); builder.addRow({disableInSubDirsLabel, disableInSubDirsCheckBox});
builder.addRow({targetsLabel, targetsList}); builder.addRow(m_buildTargetsAspect);
if (!m_disablingForSubDirsSupported) { if (!m_disablingForSubDirsSupported) {
disableInSubDirsLabel->hide(); disableInSubDirsLabel->hide();
@@ -367,16 +360,6 @@ QWidget *MakeStep::createConfigWidget()
}); });
} }
for (const QString &target : qAsConst(m_availableTargets)) {
auto item = new QListWidgetItem(target, targetsList);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
item->setCheckState(buildsTarget(item->text()) ? Qt::Checked : Qt::Unchecked);
}
if (m_availableTargets.isEmpty()) {
targetsLabel->hide();
targetsList->hide();
}
VariableChooser::addSupportForChildWidgets(widget, macroExpander()); VariableChooser::addSupportForChildWidgets(widget, macroExpander());
setSummaryUpdater([this] { setSummaryUpdater([this] {
@@ -420,12 +403,7 @@ QWidget *MakeStep::createConfigWidget()
connect(m_userArgumentsAspect, &StringAspect::changed, widget, updateDetails); connect(m_userArgumentsAspect, &StringAspect::changed, widget, updateDetails);
connect(m_userJobCountAspect, &IntegerAspect::changed, widget, updateDetails); connect(m_userJobCountAspect, &IntegerAspect::changed, widget, updateDetails);
connect(m_overrideMakeflagsAspect, &BoolAspect::changed, widget, updateDetails); connect(m_overrideMakeflagsAspect, &BoolAspect::changed, widget, updateDetails);
connect(m_buildTargetsAspect, &BaseAspect::changed, widget, updateDetails);
connect(targetsList, &QListWidget::itemChanged, this,
[this, updateDetails](QListWidgetItem *item) {
setBuildTarget(item->text(), item->checkState() & Qt::Checked);
updateDetails();
});
connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged, connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged,
widget, updateDetails); widget, updateDetails);
@@ -439,25 +417,9 @@ QWidget *MakeStep::createConfigWidget()
return widget; return widget;
} }
bool MakeStep::buildsTarget(const QString &target) const
{
return m_buildTargetsAspect->value().contains(target);
}
void MakeStep::setBuildTarget(const QString &target, bool on)
{
QStringList old = m_buildTargetsAspect->value();
if (on && !old.contains(target))
old << target;
else if (!on && old.contains(target))
old.removeOne(target);
m_buildTargetsAspect->setValue(old);
}
QStringList MakeStep::availableTargets() const QStringList MakeStep::availableTargets() const
{ {
return m_availableTargets; return m_buildTargetsAspect->allValues();
} }
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -45,14 +45,13 @@ public:
}; };
explicit MakeStep(ProjectExplorer::BuildStepList *parent, Utils::Id id); explicit MakeStep(ProjectExplorer::BuildStepList *parent, Utils::Id id);
void setBuildTarget(const QString &buildTarget);
void setAvailableBuildTargets(const QStringList &buildTargets); void setAvailableBuildTargets(const QStringList &buildTargets);
void setSelectedBuildTarget(const QString &buildTarget);
bool init() override; bool init() override;
void setupOutputFormatter(Utils::OutputFormatter *formatter) override; void setupOutputFormatter(Utils::OutputFormatter *formatter) override;
QWidget *createConfigWidget() override; QWidget *createConfigWidget() override;
bool buildsTarget(const QString &target) const;
void setBuildTarget(const QString &target, bool on);
QStringList availableTargets() const; QStringList availableTargets() const;
QString userArguments() const; QString userArguments() const;
void setUserArguments(const QString &args); void setUserArguments(const QString &args);
@@ -87,8 +86,7 @@ private:
static int defaultJobCount(); static int defaultJobCount();
QStringList jobArguments() const; QStringList jobArguments() const;
Utils::StringListAspect *m_buildTargetsAspect = nullptr; Utils::MultiSelectionAspect *m_buildTargetsAspect = nullptr;
QStringList m_availableTargets;
Utils::StringAspect *m_makeCommandAspect = nullptr; Utils::StringAspect *m_makeCommandAspect = nullptr;
Utils::StringAspect *m_userArgumentsAspect = nullptr; Utils::StringAspect *m_userArgumentsAspect = nullptr;
Utils::AspectContainer *m_jobCountContainer = nullptr; Utils::AspectContainer *m_jobCountContainer = nullptr;

View File

@@ -206,10 +206,13 @@ QList<QMakeAssignment> MakeFileParse::parseAssignments(const QList<QMakeAssignme
else else
foundForceDebugInfo = false; foundForceDebugInfo = false;
} else if (value == QLatin1String("separate_debug_info")) { } else if (value == QLatin1String("separate_debug_info")) {
if (qa.op == QLatin1String("+=")) if (qa.op == QLatin1String("+=")) {
foundSeparateDebugInfo = true; foundSeparateDebugInfo = true;
else m_config.separateDebugInfo = TriState::Enabled;
} else {
foundSeparateDebugInfo = false; foundSeparateDebugInfo = false;
m_config.separateDebugInfo = TriState::Disabled;
}
} else { } else {
newValues.append(value); newValues.append(value);
} }

View File

@@ -28,8 +28,14 @@
#include "richtexteditor/richtexteditor.h" #include "richtexteditor/richtexteditor.h"
#include <QCryptographicHash>
#include "QStringListModel" #include "QStringListModel"
#include "projectexplorer/session.h"
#include "projectexplorer/target.h"
#include "qmldesignerplugin.h"
#include "qmlprojectmanager/qmlproject.h"
namespace QmlDesigner { namespace QmlDesigner {
AnnotationCommentTab::AnnotationCommentTab(QWidget *parent) AnnotationCommentTab::AnnotationCommentTab(QWidget *parent)
@@ -38,7 +44,17 @@ AnnotationCommentTab::AnnotationCommentTab(QWidget *parent)
{ {
ui->setupUi(this); ui->setupUi(this);
m_editor = new RichTextEditor; m_editor = new RichTextEditor{this};
connect(m_editor, &RichTextEditor::insertingImage, this, [this](QString &filePath) {
filePath = backupFile(filePath);
});
Utils::FilePath projPath = ProjectExplorer::SessionManager::startupProject()->projectFilePath();
m_editor->setDocumentBaseUrl(QUrl::fromLocalFile(projPath.toString()));
m_editor->setImageActionVisible(true);
ui->formLayout->setWidget(3, QFormLayout::FieldRole, m_editor); ui->formLayout->setWidget(3, QFormLayout::FieldRole, m_editor);
ui->titleEdit->setModel(new QStringListModel{QStringList{"Description", ui->titleEdit->setModel(new QStringListModel{QStringList{"Description",
@@ -113,4 +129,64 @@ void AnnotationCommentTab::commentTitleChanged(const QString &text)
emit titleChanged(text, this); emit titleChanged(text, this);
} }
QString AnnotationCommentTab::backupFile(const QString &filePath)
{
const QDir projDir(
ProjectExplorer::SessionManager::startupProject()->projectDirectory().toString());
const QString imageSubDir(".AnnotationImages");
const QDir imgDir(projDir.absolutePath() + QDir::separator() + imageSubDir);
ensureDir(imgDir);
const QFileInfo oldFile(filePath);
QFileInfo newFile(imgDir, oldFile.fileName());
QString newName = newFile.baseName() + "_%1." + newFile.completeSuffix();
for (size_t i = 1; true; ++i) {
if (!newFile.exists()) {
QFile(oldFile.absoluteFilePath()).copy(newFile.absoluteFilePath());
break;
} else if (compareFileChecksum(oldFile.absoluteFilePath(),
newFile.absoluteFilePath()) == 0) {
break;
}
newFile.setFile(imgDir, newName.arg(i));
}
return projDir.relativeFilePath(newFile.absoluteFilePath());
}
void AnnotationCommentTab::ensureDir(const QDir &dir)
{
if (!dir.exists()) {
dir.mkdir(".");
}
}
int AnnotationCommentTab::compareFileChecksum(const QString &firstFile, const QString &secondFile)
{
QCryptographicHash sum1(QCryptographicHash::Md5);
{
QFile f1(firstFile);
if (f1.open(QFile::ReadOnly)) {
sum1.addData(&f1);
}
}
QCryptographicHash sum2(QCryptographicHash::Md5);
{
QFile f2(secondFile);
if (f2.open(QFile::ReadOnly)) {
sum2.addData(&f2);
}
}
return sum1.result().compare(sum2.result());
}
} //namespace QmlDesigner } //namespace QmlDesigner

View File

@@ -29,6 +29,8 @@
#include "annotation.h" #include "annotation.h"
class QDir;
namespace QmlDesigner { namespace QmlDesigner {
namespace Ui { namespace Ui {
@@ -64,6 +66,10 @@ private:
RichTextEditor *m_editor; RichTextEditor *m_editor;
Comment m_comment; Comment m_comment;
QString backupFile(const QString &filePath);
void ensureDir(const QDir &dir);
int compareFileChecksum(const QString &firstFile, const QString &secondFile);
}; };
} //namespace QmlDesigner } //namespace QmlDesigner

View File

@@ -1087,7 +1087,7 @@ static int counterClockWise(const std::vector<QPointF> &points)
}; };
const int m = findLR(points); const int m = findLR(points);
const int n = points.size(); const int n = static_cast<int>(points.size());
// Determine previous and next point to m (the lowest, rightmost point). // Determine previous and next point to m (the lowest, rightmost point).
const QPointF a = points[(m + (n - 1)) % n]; const QPointF a = points[(m + (n - 1)) % n];

View File

@@ -89,7 +89,7 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
if (m_qmlPuppetProcesses.empty()) { if (m_qmlPuppetProcesses.empty()) {
finalizeQuick3DImport(); finalizeQuick3DImport();
} else { } else {
m_qmlPuppetCount = m_qmlPuppetProcesses.size(); m_qmlPuppetCount = static_cast<int>(m_qmlPuppetProcesses.size());
const QString progressTitle = tr("Generating icons."); const QString progressTitle = tr("Generating icons.");
addInfo(progressTitle); addInfo(progressTitle);
notifyProgress(0, progressTitle); notifyProgress(0, progressTitle);

View File

@@ -32,6 +32,7 @@
#include <QAction> #include <QAction>
#include <QActionGroup> #include <QActionGroup>
#include <QColorDialog> #include <QColorDialog>
#include <QFileDialog>
#include <QPainter> #include <QPainter>
#include <QPointer> #include <QPointer>
#include <QScopeGuard> #include <QScopeGuard>
@@ -120,6 +121,7 @@ RichTextEditor::RichTextEditor(QWidget *parent)
setupEditActions(); setupEditActions();
setupTextActions(); setupTextActions();
setupImageActions();
setupHyperlinkActions(); setupHyperlinkActions();
setupAlignActions(); setupAlignActions();
setupListActions(); setupListActions();
@@ -184,6 +186,16 @@ void RichTextEditor::setTabChangesFocus(bool change)
ui->textEdit->setTabChangesFocus(change); ui->textEdit->setTabChangesFocus(change);
} }
void RichTextEditor::setImageActionVisible(bool change)
{
m_actionImage->setVisible(change);
}
void RichTextEditor::setDocumentBaseUrl(const QUrl& url)
{
ui->textEdit->document()->setBaseUrl(url);
}
QIcon RichTextEditor::getIcon(Theme::Icon icon) QIcon RichTextEditor::getIcon(Theme::Icon icon)
{ {
const QString fontName = "qtds_propertyIconFont.ttf"; const QString fontName = "qtds_propertyIconFont.ttf";
@@ -363,6 +375,30 @@ void RichTextEditor::setupTextActions()
ui->toolBar->addSeparator(); ui->toolBar->addSeparator();
} }
void RichTextEditor::setupImageActions()
{
auto insertImage = [this]() {
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setWindowTitle(tr("Select Image"));
dialog.setNameFilters({tr("Image files (*.png *.jpg)")});
if (dialog.exec()) {
QStringList files = dialog.selectedFiles();
for (QString& filePath : files) {
emit insertingImage(filePath);
ui->textEdit->insertHtml("<img src=\"" + filePath + "\" />");
}
}
};
m_actionImage = ui->toolBar
->addAction(getIcon(Theme::Icon::addFile), tr("Insert &Image"), insertImage);
setImageActionVisible(false);
}
void RichTextEditor::setupHyperlinkActions() void RichTextEditor::setupHyperlinkActions()
{ {
const QIcon bulletIcon(getIcon(Theme::Icon::actionIconBinding)); const QIcon bulletIcon(getIcon(Theme::Icon::actionIconBinding));

View File

@@ -63,6 +63,13 @@ public:
void setTabChangesFocus(bool change); void setTabChangesFocus(bool change);
void setImageActionVisible(bool change);
void setDocumentBaseUrl(const QUrl &url);
signals:
void insertingImage(QString &filePath);
private slots: private slots:
void currentCharFormatChanged(const QTextCharFormat &format); void currentCharFormatChanged(const QTextCharFormat &format);
void cursorPositionChanged(); void cursorPositionChanged();
@@ -79,6 +86,7 @@ private:
void setupEditActions(); void setupEditActions();
void setupTextActions(); void setupTextActions();
void setupImageActions();
void setupHyperlinkActions(); void setupHyperlinkActions();
void setupAlignActions(); void setupAlignActions();
void setupListActions(); void setupListActions();
@@ -97,6 +105,7 @@ private:
QAction *m_actionTextItalic; QAction *m_actionTextItalic;
QAction *m_actionTextUnderline; QAction *m_actionTextUnderline;
QAction *m_actionImage;
QAction *m_actionHyperlink; QAction *m_actionHyperlink;
QAction *m_actionAlignLeft; QAction *m_actionAlignLeft;

View File

@@ -768,7 +768,7 @@ FontSettings SyntaxHighlighter::fontSettings() const
return d->fontSettings; return d->fontSettings;
} }
/*! /*!
The syntax highlighter is not anymore reacting to the text document if \a noAutmatic is The syntax highlighter is not anymore reacting to the text document if \a noAutomatic is
\c true. \c true.
*/ */
void SyntaxHighlighter::setNoAutomaticHighlighting(bool noAutomatic) void SyntaxHighlighter::setNoAutomaticHighlighting(bool noAutomatic)