11#include <QtDesigner/abstractformeditor.h>
12#include <QtDesigner/abstractintegration.h>
13#include <QtDesigner/abstractformwindow.h>
14#include <QtDesigner/abstractformwindowcursor.h>
15#include <QtDesigner/dynamicpropertysheet.h>
16#include <QtDesigner/propertysheet.h>
17#include <QtDesigner/abstractpropertyeditor.h>
18#include <QtDesigner/abstractobjectinspector.h>
19#include <QtDesigner/abstractintegration.h>
20#include <QtDesigner/abstractwidgetdatabase.h>
21#include <QtDesigner/qextensionmanager.h>
23#include <QtWidgets/qwidget.h>
24#include <QtWidgets/qapplication.h>
25#include <QtWidgets/qdialog.h>
26#include <QtWidgets/qpushbutton.h>
27#include <QtWidgets/qlayout.h>
29#include <QtGui/qaction.h>
31#include <QtCore/qdebug.h>
32#include <QtCore/qsize.h>
33#include <QtCore/qtextstream.h>
37using namespace Qt::StringLiterals;
40enum { debugPropertyCommands = 0 };
42const unsigned QFontFamiliesResolved = (QFont::FamilyResolved | QFont::FamiliesResolved);
45QString fontMask(
unsigned m)
48 if (m & QFontFamiliesResolved)
50 if (m & QFont::SizeResolved)
52 if (m & QFont::WeightResolved)
54 if (m & QFont::StyleResolved)
56 if (m & QFont::UnderlineResolved)
57 rc +=
"Underline "_L1;
58 if (m & QFont::StrikeOutResolved)
59 rc +=
"StrikeOut "_L1;
60 if (m & QFont::KerningResolved)
62 if (m & QFont::StyleStrategyResolved)
63 rc +=
"StyleStrategy"_L1;
68QString fontString(
const QFont &f)
72 str <<
"QFont(\"" << f.family() <<
',' << f.pointSize();
76 str <<
',' <<
"italic";
78 str <<
',' <<
"underline";
80 str <<
',' <<
"strikeOut";
82 str <<
',' <<
"kerning";
83 str <<
',' << f.styleStrategy() <<
" resolve: "
84 << fontMask(f.resolveMask()) <<
')';
88QSize checkSize(
const QSize &size)
90 return size.boundedTo(QSize(0xFFFFFF, 0xFFFFFF));
93QSize diffSize(QDesignerFormWindowInterface *fw)
95 const QWidget *container = fw->core()->integration()->containerWindow(fw);
99 const QSize diff = container->size() - fw->size();
103void checkSizes(QDesignerFormWindowInterface *fw,
const QSize &size, QSize *formSize, QSize *containerSize)
105 const QWidget *container = fw->core()->integration()->containerWindow(fw);
109 const QSize diff = diffSize(fw);
111 QSize newFormSize = checkSize(size).expandedTo(fw->mainContainer()->minimumSizeHint());
112 QSize newContainerSize = newFormSize + diff;
114 newContainerSize = newContainerSize.expandedTo(container->minimumSizeHint());
115 newContainerSize = newContainerSize.expandedTo(container->minimumSize());
117 newFormSize = newContainerSize - diff;
119 newContainerSize = checkSize(newContainerSize);
122 *formSize = newFormSize;
124 *containerSize = newContainerSize;
128
129
130
131
132
133
135enum RectSubPropertyMask { SubPropertyX=1, SubPropertyY = 2, SubPropertyWidth = 4, SubPropertyHeight = 8 };
136enum SizePolicySubPropertyMask { SubPropertyHSizePolicy = 1, SubPropertyHStretch = 2, SubPropertyVSizePolicy = 4, SubPropertyVStretch = 8 };
137enum AlignmentSubPropertyMask { SubPropertyHorizontalAlignment = 1, SubPropertyVerticalAlignment = 2 };
138enum StringSubPropertyMask { SubPropertyStringValue = 1, SubPropertyStringComment = 2,
139 SubPropertyStringTranslatable = 4, SubPropertyStringDisambiguation = 8,
140 SubPropertyStringId = 16 };
141enum StringListSubPropertyMask { SubPropertyStringListValue = 1, SubPropertyStringListComment = 2,
142 SubPropertyStringListTranslatable = 4, SubPropertyStringListDisambiguation = 8,
143 SubPropertyStringListId = 16 };
144enum KeySequenceSubPropertyMask { SubPropertyKeySequenceValue = 1, SubPropertyKeySequenceComment = 2,
145 SubPropertyKeySequenceTranslatable = 4, SubPropertyKeySequenceDisambiguation = 8,
146 SubPropertyKeySequenceId = 16 };
148enum CommonSubPropertyMask : quint64 { SubPropertyAll = quint64(-1) };
151#define COMPARE_SUBPROPERTY(object1, object2, getter, mask, maskFlag)
152 if (object1.getter() != object2.getter()) (mask) |= (maskFlag);
155quint64 compareSubProperties(
const QRect & r1,
const QRect & r2)
166quint64 compareSubProperties(
const QSize & r1,
const QSize & r2)
174quint64 compareSubProperties(
const QSizePolicy & sp1,
const QSizePolicy & sp2)
184quint64 compareSubProperties(
const qdesigner_internal::PropertySheetStringValue & str1,
const qdesigner_internal::PropertySheetStringValue & str2)
195quint64 compareSubProperties(
const qdesigner_internal::PropertySheetStringListValue & str1,
const qdesigner_internal::PropertySheetStringListValue & str2)
206quint64 compareSubProperties(
const qdesigner_internal::PropertySheetKeySequenceValue & str1,
const qdesigner_internal::PropertySheetKeySequenceValue & str2)
219template <
class Property>
220void compareFontSubProperty(
const QFont & f1,
222 Property (QFont::*getter) ()
const,
226 const bool f1Changed = f1.resolveMask() & maskBit;
227 const bool f2Changed = f2.resolveMask() & maskBit;
229 if (f1Changed != f2Changed) {
233 if (f1Changed && f2Changed && (f1.*getter)() != (f2.*getter)())
238quint64 compareSubProperties(
const QFont & f1,
const QFont & f2)
241 compareFontSubProperty(f1, f2, &QFont::family, QFontFamiliesResolved, rc);
242 compareFontSubProperty(f1, f2, &QFont::pointSize, QFont::SizeResolved, rc);
243 compareFontSubProperty(f1, f2, &QFont::weight, QFont::WeightResolved, rc);
244 compareFontSubProperty(f1, f2, &QFont::italic, QFont::StyleResolved, rc);
245 compareFontSubProperty(f1, f2, &QFont::underline, QFont::UnderlineResolved, rc);
246 compareFontSubProperty(f1, f2, &QFont::strikeOut, QFont::StrikeOutResolved, rc);
247 compareFontSubProperty(f1, f2, &QFont::kerning, QFont::KerningResolved, rc);
248 compareFontSubProperty(f1, f2, &QFont::styleStrategy, QFont::StyleStrategyResolved, rc);
249 compareFontSubProperty(f1, f2, &QFont::hintingPreference, QFont::HintingPreferenceResolved, rc);
250 if (debugPropertyCommands)
251 qDebug() <<
"compareSubProperties " << fontString(f1) << fontString(f2) <<
"\n\treturns " << fontMask(rc);
256quint64 compareSubProperties(
const QPalette & p1,
const QPalette & p2)
260 const auto p1Changed = p1.resolveMask();
261 const auto p2Changed = p2.resolveMask();
263 for (
int r = 0; r <
static_cast<
int>(QPalette::NColorRoles); ++r) {
264 for (
int g = 0; g <
static_cast<
int>(QPalette::NColorGroups); ++g) {
265 const auto role =
static_cast<QPalette::ColorRole>(r);
266 const auto group =
static_cast<QPalette::ColorGroup>(g);
267 const auto maskBit = qdesigner_internal::paletteResolveMask(group, role);
268 const bool p1RoleChanged = p1Changed & maskBit;
269 const bool p2RoleChanged = p2Changed & maskBit;
270 if (p1RoleChanged != p2RoleChanged
272 || (p1RoleChanged && p2RoleChanged
273 && p1.brush(group, role).color() != p2.brush(group, role).color())) {
284quint64 compareSubProperties(Qt::Alignment a1, Qt::Alignment a2)
287 if ((a1 & Qt::AlignHorizontal_Mask) != (a2 & Qt::AlignHorizontal_Mask))
288 rc |= SubPropertyHorizontalAlignment;
289 if ((a1 & Qt::AlignVertical_Mask) != (a2 & Qt::AlignVertical_Mask))
290 rc |= SubPropertyVerticalAlignment;
294Qt::Alignment variantToAlignment(
const QVariant & q)
296 return Qt::Alignment(qdesigner_internal::Utils::valueOf(q));
303 const int t1 = q1.metaType().id();
304 const int t2 = q2.metaType().id();
306 return SubPropertyAll;
308 case QMetaType::QRect:
309 return compareSubProperties(q1.toRect(), q2.toRect());
310 case QMetaType::QSize:
311 return compareSubProperties(q1.toSize(), q2.toSize());
312 case QMetaType::QSizePolicy:
313 return compareSubProperties(qvariant_cast<QSizePolicy>(q1), qvariant_cast<QSizePolicy>(q2));
314 case QMetaType::QFont:
315 return compareSubProperties(qvariant_cast<QFont>(q1), qvariant_cast<QFont>(q2));
316 case QMetaType::QPalette:
317 return compareSubProperties(qvariant_cast<QPalette>(q1), qvariant_cast<QPalette>(q2));
321 else if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetStringValue>())
322 return compareSubProperties(qvariant_cast<qdesigner_internal::PropertySheetStringValue>(q1), qvariant_cast<qdesigner_internal::PropertySheetStringValue>(q2));
323 else if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetStringListValue>())
324 return compareSubProperties(qvariant_cast<qdesigner_internal::PropertySheetStringListValue>(q1), qvariant_cast<qdesigner_internal::PropertySheetStringListValue>(q2));
325 else if (q1.userType() == qMetaTypeId<qdesigner_internal::PropertySheetKeySequenceValue>())
326 return compareSubProperties(qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(q1), qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(q2));
328 switch (specialProperty) {
329 case qdesigner_internal::SP_Alignment:
330 return compareSubProperties(variantToAlignment(q1), variantToAlignment(q2));
336 return SubPropertyAll;
340#define SET_SUBPROPERTY(rc, newValue, getter, setter, mask, maskFlag)
341 if ((mask) & (maskFlag)) rc.setter((newValue).getter());
344QRect applyRectSubProperty(
const QRect &oldValue,
const QRect &newValue,
unsigned mask)
350 SET_SUBPROPERTY(rc, newValue, height, setHeight, mask, SubPropertyHeight)
356QSize applySizeSubProperty(
const QSize &oldValue,
const QSize &newValue,
unsigned mask)
360 SET_SUBPROPERTY(rc, newValue, height, setHeight, mask, SubPropertyHeight)
366QSizePolicy applySizePolicySubProperty(
const QSizePolicy &oldValue,
const QSizePolicy &newValue,
unsigned mask)
368 QSizePolicy rc = oldValue;
369 SET_SUBPROPERTY(rc, newValue, horizontalPolicy, setHorizontalPolicy, mask, SubPropertyHSizePolicy)
370 SET_SUBPROPERTY(rc, newValue, horizontalStretch, setHorizontalStretch, mask, SubPropertyHStretch)
371 SET_SUBPROPERTY(rc, newValue, verticalPolicy, setVerticalPolicy, mask, SubPropertyVSizePolicy)
372 SET_SUBPROPERTY(rc, newValue, verticalStretch, setVerticalStretch, mask, SubPropertyVStretch)
377qdesigner_internal::PropertySheetStringValue applyStringSubProperty(
const qdesigner_internal::PropertySheetStringValue &oldValue,
378 const qdesigner_internal::PropertySheetStringValue &newValue,
unsigned mask)
381 SET_SUBPROPERTY(rc, newValue, value, setValue, mask, SubPropertyStringValue)
382 SET_SUBPROPERTY(rc, newValue, comment, setComment, mask, SubPropertyStringComment)
383 SET_SUBPROPERTY(rc, newValue, translatable, setTranslatable, mask, SubPropertyStringTranslatable)
384 SET_SUBPROPERTY(rc, newValue, disambiguation, setDisambiguation, mask, SubPropertyStringDisambiguation)
390qdesigner_internal::PropertySheetStringListValue applyStringListSubProperty(
const qdesigner_internal::PropertySheetStringListValue &oldValue,
391 const qdesigner_internal::PropertySheetStringListValue &newValue,
unsigned mask)
394 SET_SUBPROPERTY(rc, newValue, value, setValue, mask, SubPropertyStringListValue)
395 SET_SUBPROPERTY(rc, newValue, comment, setComment, mask, SubPropertyStringListComment)
396 SET_SUBPROPERTY(rc, newValue, translatable, setTranslatable, mask, SubPropertyStringListTranslatable)
397 SET_SUBPROPERTY(rc, newValue, disambiguation, setDisambiguation, mask, SubPropertyStringListDisambiguation)
398 SET_SUBPROPERTY(rc, newValue, id, setId, mask, SubPropertyStringListId)
403qdesigner_internal::PropertySheetKeySequenceValue applyKeySequenceSubProperty(
const qdesigner_internal::PropertySheetKeySequenceValue &oldValue,
404 const qdesigner_internal::PropertySheetKeySequenceValue &newValue,
unsigned mask)
407 SET_SUBPROPERTY(rc, newValue, value, setValue, mask, SubPropertyKeySequenceValue)
408 SET_SUBPROPERTY(rc, newValue, comment, setComment, mask, SubPropertyKeySequenceComment)
409 SET_SUBPROPERTY(rc, newValue, translatable, setTranslatable, mask, SubPropertyKeySequenceTranslatable)
410 SET_SUBPROPERTY(rc, newValue, disambiguation, setDisambiguation, mask, SubPropertyKeySequenceDisambiguation)
411 SET_SUBPROPERTY(rc, newValue, id, setId, mask, SubPropertyKeySequenceId)
417template <
class PropertyReturnType,
class PropertySetterType>
418inline void setFontSubProperty(
unsigned mask,
419 const QFont &newValue,
421 PropertyReturnType (QFont::*getter) ()
const,
422 void (QFont::*setter) (PropertySetterType),
425 if (mask & maskBit) {
426 (value.*setter)((newValue.*getter)());
428 uint r = value.resolveMask();
429 const bool origFlag = newValue.resolveMask() & maskBit;
434 value.setResolveMask(r);
435 if (debugPropertyCommands)
436 qDebug() <<
"setFontSubProperty " << fontMask(maskBit) <<
" resolve=" << origFlag;
440QFont applyFontSubProperty(
const QFont &oldValue,
const QFont &newValue,
unsigned mask)
443 setFontSubProperty(mask, newValue, QFontFamiliesResolved, &QFont::family, &QFont::setFamily, rc);
444 setFontSubProperty(mask, newValue, QFont::SizeResolved, &QFont::pointSize, &QFont::setPointSize, rc);
445 setFontSubProperty(mask, newValue, QFont::WeightResolved, &QFont::weight, &QFont::setWeight, rc);
446 setFontSubProperty(mask, newValue, QFont::StyleResolved, &QFont::italic, &QFont::setItalic, rc);
447 setFontSubProperty(mask, newValue, QFont::UnderlineResolved, &QFont::underline, &QFont::setUnderline, rc);
448 setFontSubProperty(mask, newValue, QFont::StrikeOutResolved, &QFont::strikeOut, &QFont::setStrikeOut, rc);
449 setFontSubProperty(mask, newValue, QFont::KerningResolved, &QFont::kerning, &QFont::setKerning, rc);
450 setFontSubProperty(mask, newValue, QFont::StyleStrategyResolved, &QFont::styleStrategy, &QFont::setStyleStrategy, rc);
451 setFontSubProperty(mask, newValue, QFont::HintingPreferenceResolved, &QFont::hintingPreference, &QFont::setHintingPreference, rc);
452 if (debugPropertyCommands)
453 qDebug() <<
"applyFontSubProperty old " << fontMask(oldValue.resolveMask()) <<
" new " << fontMask(newValue.resolveMask()) <<
" return: " << fontMask(rc.resolveMask());
458QPalette applyPaletteSubProperty(
const QPalette &oldValue,
const QPalette &newValue,
461 QPalette rc = oldValue;
463 for (
int r = 0; r <
static_cast<
int>(QPalette::NColorRoles); ++r) {
464 for (
int g = 0; g <
static_cast<
int>(QPalette::NColorGroups); ++g) {
465 const auto role =
static_cast<QPalette::ColorRole>(r);
466 const auto group =
static_cast<QPalette::ColorGroup>(g);
467 const auto maskBit = qdesigner_internal::paletteResolveMask(group, role);
468 if (mask & maskBit) {
469 rc.setColor(group, role, newValue.color(group, role));
471 auto resolveMask = rc.resolveMask();
472 const bool origFlag = newValue.resolveMask() & maskBit;
474 resolveMask |= maskBit;
476 resolveMask &= ~maskBit;
477 rc.setResolveMask(resolveMask);
485Qt::Alignment applyAlignmentSubProperty(Qt::Alignment oldValue, Qt::Alignment newValue,
unsigned mask)
488 if (mask == (SubPropertyHorizontalAlignment|SubPropertyVerticalAlignment))
491 const Qt::Alignment changeMask = (mask & SubPropertyHorizontalAlignment) ? Qt::AlignHorizontal_Mask : Qt::AlignVertical_Mask;
492 const Qt::Alignment takeOverMask = (mask & SubPropertyHorizontalAlignment) ? Qt::AlignVertical_Mask : Qt::AlignHorizontal_Mask;
493 return (oldValue & takeOverMask) | (newValue & changeMask);
503 quint64 mask,
bool changed)
505 if (mask == SubPropertyAll)
506 return PropertyHelper::Value(newValue, changed);
508 switch (oldValue.metaType().id()) {
509 case QMetaType::QRect:
510 return PropertyHelper::Value(applyRectSubProperty(oldValue.toRect(), newValue.toRect(), mask), changed);
511 case QMetaType::QSize:
512 return PropertyHelper::Value(applySizeSubProperty(oldValue.toSize(), newValue.toSize(), mask), changed);
513 case QMetaType::QSizePolicy:
514 return PropertyHelper::Value(QVariant::fromValue(applySizePolicySubProperty(qvariant_cast<QSizePolicy>(oldValue), qvariant_cast<QSizePolicy>(newValue), mask)), changed);
515 case QMetaType::QFont: {
532 QFont font = applyFontSubProperty(qvariant_cast<QFont>(oldValue), qvariant_cast<QFont>(newValue), mask);
533 return PropertyHelper::Value(QVariant::fromValue(font), font.resolveMask());
535 case QMetaType::QPalette: {
536 QPalette palette = applyPaletteSubProperty(qvariant_cast<QPalette>(oldValue), qvariant_cast<QPalette>(newValue), mask);
537 return PropertyHelper::Value(QVariant::fromValue(palette), palette.resolveMask());
542 icon.assign(qvariant_cast<qdesigner_internal::PropertySheetIconValue>(newValue), mask);
543 return PropertyHelper::Value(QVariant::fromValue(icon), icon.mask());
546 qvariant_cast<qdesigner_internal::PropertySheetStringValue>(oldValue),
547 qvariant_cast<qdesigner_internal::PropertySheetStringValue>(newValue), mask);
548 return PropertyHelper::Value(QVariant::fromValue(str), changed);
551 qvariant_cast<qdesigner_internal::PropertySheetStringListValue>(oldValue),
552 qvariant_cast<qdesigner_internal::PropertySheetStringListValue>(newValue), mask);
553 return PropertyHelper::Value(QVariant::fromValue(str), changed);
556 qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(oldValue),
557 qvariant_cast<qdesigner_internal::PropertySheetKeySequenceValue>(newValue), mask);
558 return PropertyHelper::Value(QVariant::fromValue(key), changed);
561 switch (specialProperty) {
564 f.value = applyAlignmentSubProperty(variantToAlignment(oldValue), variantToAlignment(newValue), mask);
567 return PropertyHelper::Value(v, changed);
574 return PropertyHelper::Value(newValue, changed);
580 if (propertyName ==
"objectName"_L1)
582 if (propertyName ==
"layoutName"_L1)
584 if (propertyName ==
"spacerName"_L1)
586 if (propertyName ==
"icon"_L1)
588 if (propertyName ==
"currentTabName"_L1)
590 if (propertyName ==
"currentItemName"_L1)
592 if (propertyName ==
"currentPageName"_L1)
594 if (propertyName ==
"geometry"_L1)
596 if (propertyName ==
"windowTitle"_L1)
598 if (propertyName ==
"minimumSize"_L1)
600 if (propertyName ==
"maximumSize"_L1)
602 if (propertyName ==
"alignment"_L1)
604 if (propertyName ==
"autoDefault"_L1)
606 if (propertyName ==
"shortcut"_L1)
608 if (propertyName ==
"orientation"_L1)
1033 SetValueFunction(QDesignerFormWindowInterface *formWindow,
const PropertyHelper::Value &newValue,
1034 quint64 subPropertyMask);
1038 QDesignerFormWindowInterface *m_formWindow;
1040 const quint64 m_subPropertyMask;
1045 const PropertyHelper::Value &newValue,
1046 quint64 subPropertyMask) :
1047 m_formWindow(formWindow),
1054 return ph.setValue(m_formWindow, m_newValue.first, m_newValue.second, m_subPropertyMask);
1079template <
class PropertyListIterator,
class Function>
1081 const QString &propertyName,
1082 PropertyListIterator begin,
1083 PropertyListIterator end,
1086 unsigned updateMask = 0;
1087 QDesignerPropertyEditorInterface *propertyEditor = core->propertyEditor();
1088 bool updatedPropertyEditor =
false;
1090 for (
auto it = begin; it != end; ++it) {
1091 PropertyHelper *ph = it->get();
1092 if (QObject* object = ph->object()) {
1093 const PropertyHelper::Value newValue = function( *ph );
1094 updateMask |= ph->updateMask();
1096 if (!updatedPropertyEditor && propertyEditor && object == propertyEditor->object()) {
1097 propertyEditor->setPropertyValue(propertyName, newValue.first, newValue.second);
1098 updatedPropertyEditor =
true;
1102 if (!updatedPropertyEditor) updateMask |= PropertyHelper::UpdatePropertyEditor;
1111 qDebug() <<
"PropertyListCommand::setValue(" <<
value
1123 qDebug() <<
"PropertyListCommand::restoreOldValue()";
1133 qDebug() <<
"PropertyListCommand::restoreDefaultValue()";
1515 "Remove dynamic property '%1' from '%2'")
1520 "Remove dynamic property '%1' from %n objects",
"",
count)
RestoreDefaultFunction(QDesignerFormWindowInterface *formWindow)
SetValueFunction(QDesignerFormWindowInterface *formWindow, const PropertyHelper::Value &newValue, quint64 subPropertyMask)
UndoSetValueFunction(QDesignerFormWindowInterface *formWindow)
Auxiliary methods to store/retrieve settings.
PropertyHelper::Value applySubProperty(const QVariant &oldValue, const QVariant &newValue, qdesigner_internal::SpecialProperty specialProperty, quint64 mask, bool changed)
unsigned changePropertyList(QDesignerFormEditorInterface *core, const QString &propertyName, PropertyListIterator begin, PropertyListIterator end, Function function)
#define SET_SUBPROPERTY(rc, newValue, getter, setter, mask, maskFlag)
#define COMPARE_SUBPROPERTY(object1, object2, getter, mask, maskFlag)