18#include <QtDesigner/abstractformeditor.h>
19#include <QtDesigner/abstractformwindowmanager.h>
20#include <QtDesigner/qextensionmanager.h>
21#include <QtDesigner/propertysheet.h>
22#include <QtDesigner/abstractwidgetdatabase.h>
23#include <QtDesigner/abstractsettings.h>
25#include <qdesigner_utils_p.h>
26#include <qdesigner_propertycommand_p.h>
27#include <metadatabase_p.h>
28#include <iconloader_p.h>
29#include <widgetfactory_p.h>
31#include <QtWidgets/qlabel.h>
32#include <QtWidgets/qlineedit.h>
33#include <QtWidgets/qmenu.h>
34#include <QtWidgets/qapplication.h>
35#include <QtWidgets/qboxlayout.h>
36#include <QtWidgets/qscrollarea.h>
37#include <QtWidgets/qstackedwidget.h>
38#include <QtWidgets/qtoolbar.h>
39#include <QtWidgets/qtoolbutton.h>
41#include <QtGui/qaction.h>
42#include <QtGui/qactiongroup.h>
43#include <QtGui/qpainter.h>
45#include <QtCore/qdebug.h>
46#include <QtCore/qtextstream.h>
47#include <QtCore/qtimezone.h>
49enum SettingsView { TreeView, ButtonView };
53using namespace Qt::StringLiterals;
74 { setContentsMargins(3, 2, 3, 2); }
96 QSize size = fontMetrics().boundingRect(m_text).size();
97 size += QSize(contentsMargins().left() + contentsMargins().right(),
98 contentsMargins().top() + contentsMargins().bottom());
103 QPainter painter(
this);
104 painter.setPen(QColor(0, 0, 0, 60));
105 painter.setBrush(QColor(255, 255, 255, 40));
106 painter.drawRect(rect().adjusted(0, 0, -1, -1));
107 painter.setPen(palette().windowText().color());
108 painter.drawText(contentsRect(), Qt::AlignLeft,
109 fontMetrics().elidedText(m_text, Qt::ElideRight, width(), 0));
116 m_alignmentProperties{u"alignment"_s,
117 u"layoutLabelAlignment"_s,
118 u"layoutFormAlignment"_s},
119 m_fontProperty(u"font"_s),
120 m_qLayoutWidget(u"QLayoutWidget"_s),
121 m_designerPrefix(u"QDesigner"_s),
122 m_layout(u"Layout"_s),
123 m_validationModeAttribute(u"validationMode"_s),
124 m_fontAttribute(u"font"_s),
125 m_superPaletteAttribute(u"superPalette"_s),
126 m_enumNamesAttribute(u"enumNames"_s),
127 m_resettableAttribute(u"resettable"_s),
128 m_flagsAttribute(u"flags"_s)
136 QObject *o = object();
139 QDesignerMetaDataBaseInterface *db = core()->metaDataBase();
147 const StringPropertyParameters params = textPropertyValidationMode(core(), m_object, property->propertyName(), isMainContainer);
149 const bool hasComment = params.second;
150 property->setAttribute(m_strings.m_validationModeAttribute, params.first);
153 qDeleteAll(property->subProperties());
158 QPalette superPalette = QPalette();
159 QWidget *currentWidget = qobject_cast<QWidget *>(m_object);
161 if (currentWidget->isWindow())
162 superPalette = QApplication::palette(currentWidget);
164 if (currentWidget->parentWidget())
165 superPalette = currentWidget->parentWidget()->palette();
168 m_updatingBrowser =
true;
169 property->setAttribute(m_strings.m_superPaletteAttribute, superPalette);
170 m_updatingBrowser =
false;
182 QDesignerPropertyEditor(parent, flags),
184 m_propertyManager(
new DesignerPropertyManager(m_core,
this)),
185 m_stackedWidget(
new QStackedWidget),
186 m_filterWidget(
new QLineEdit),
187 m_addDynamicAction(
new QAction(createIconSet(
"plus.png"_L1), tr(
"Add Dynamic Property..."),
this)),
188 m_removeDynamicAction(
new QAction(createIconSet(
"minus.png"_L1), tr(
"Remove Dynamic Property"),
this)),
189 m_sortingAction(
new QAction(createIconSet(
"sort.png"_L1), tr(
"Sorting"),
this)),
190 m_coloringAction(
new QAction(createIconSet(
"color.png"_L1), tr(
"Color Groups"),
this)),
191 m_treeAction(
new QAction(tr(
"Tree View"),
this)),
192 m_buttonAction(
new QAction(tr(
"Drop Down Button View"),
this)),
195 const QColor colors[] = {{255, 230, 191}, {255, 255, 191}, {191, 255, 191},
196 {199, 255, 255}, {234, 191, 255}, {255, 191, 239}};
197 const int darknessFactor = 250;
198 m_colors.reserve(std::size(colors));
199 for (
const QColor &c : colors)
200 m_colors.append({c, c.darker(darknessFactor)});
201 QColor dynamicColor(191, 207, 255);
202 QColor layoutColor(255, 191, 191);
203 m_dynamicColor = {dynamicColor, dynamicColor.darker(darknessFactor)};
204 m_layoutColor = {layoutColor, layoutColor.darker(darknessFactor)};
206 updateForegroundBrightness();
208 QActionGroup *actionGroup =
new QActionGroup(
this);
210 m_treeAction->setCheckable(
true);
211 m_treeAction->setIcon(createIconSet(
"widgets/listview.png"_L1));
212 m_buttonAction->setCheckable(
true);
213 m_buttonAction->setIcon(createIconSet(
"dropdownbutton.png"_L1));
215 actionGroup->addAction(m_treeAction);
216 actionGroup->addAction(m_buttonAction);
217 connect(actionGroup, &QActionGroup::triggered,
218 this, &PropertyEditor::slotViewTriggered);
221 QActionGroup *addDynamicActionGroup =
new QActionGroup(
this);
222 connect(addDynamicActionGroup, &QActionGroup::triggered,
223 this, &PropertyEditor::slotAddDynamicProperty);
225 QMenu *addDynamicActionMenu =
new QMenu(
this);
226 m_addDynamicAction->setMenu(addDynamicActionMenu);
227 m_addDynamicAction->setEnabled(
false);
228 QAction *addDynamicAction = addDynamicActionGroup->addAction(tr(
"String..."));
229 addDynamicAction->setData(
static_cast<
int>(QMetaType::QString));
230 addDynamicActionMenu->addAction(addDynamicAction);
231 addDynamicAction = addDynamicActionGroup->addAction(tr(
"Bool..."));
232 addDynamicAction->setData(
static_cast<
int>(QMetaType::Bool));
233 addDynamicActionMenu->addAction(addDynamicAction);
234 addDynamicActionMenu->addSeparator();
235 addDynamicAction = addDynamicActionGroup->addAction(tr(
"Other..."));
236 addDynamicAction->setData(
static_cast<
int>(QMetaType::UnknownType));
237 addDynamicActionMenu->addAction(addDynamicAction);
239 m_removeDynamicAction->setEnabled(
false);
240 connect(m_removeDynamicAction, &QAction::triggered,
this, &PropertyEditor::slotRemoveDynamicProperty);
242 QAction *configureAction =
new QAction(tr(
"Configure Property Editor"),
this);
243 configureAction->setIcon(createIconSet(
"configure.png"_L1));
244 QMenu *configureMenu =
new QMenu(
this);
245 configureAction->setMenu(configureMenu);
247 m_sortingAction->setCheckable(
true);
248 connect(m_sortingAction, &QAction::toggled,
this, &PropertyEditor::slotSorting);
250 m_coloringAction->setCheckable(
true);
251 connect(m_coloringAction, &QAction::toggled,
this, &PropertyEditor::slotColoring);
253 configureMenu->addAction(m_sortingAction);
254 configureMenu->addAction(m_coloringAction);
255 configureMenu->addSeparator();
256 configureMenu->addAction(m_treeAction);
257 configureMenu->addAction(m_buttonAction);
259 QToolBar *toolBar =
new QToolBar;
260 toolBar->addWidget(m_filterWidget);
261 toolBar->addWidget(createDropDownButton(m_addDynamicAction));
262 toolBar->addAction(m_removeDynamicAction);
263 toolBar->addWidget(createDropDownButton(configureAction));
265 QScrollArea *buttonScroll =
new QScrollArea(m_stackedWidget);
267 buttonScroll->setWidgetResizable(
true);
268 buttonScroll->setWidget(m_buttonBrowser);
269 m_buttonIndex = m_stackedWidget->addWidget(buttonScroll);
270 connect(m_buttonBrowser, &QtAbstractPropertyBrowser::currentItemChanged,
271 this, &PropertyEditor::slotCurrentItemChanged);
273 m_treeBrowser =
new QtTreePropertyBrowser(m_stackedWidget);
276 m_treeBrowser->setResizeMode(QtTreePropertyBrowser::Interactive);
277 m_treeIndex = m_stackedWidget->addWidget(m_treeBrowser);
278 connect(m_treeBrowser, &QtAbstractPropertyBrowser::currentItemChanged,
279 this, &PropertyEditor::slotCurrentItemChanged);
280 m_filterWidget->setPlaceholderText(tr(
"Filter"));
281 m_filterWidget->setClearButtonEnabled(
true);
282 connect(m_filterWidget, &QLineEdit::textChanged,
this, &PropertyEditor::setFilter);
284 QVBoxLayout *layout =
new QVBoxLayout(
this);
285 layout->addWidget(toolBar);
286 layout->addWidget(m_classLabel);
287 layout->addSpacerItem(
new QSpacerItem(0,1));
288 layout->addWidget(m_stackedWidget);
289 layout->setContentsMargins(QMargins());
290 layout->setSpacing(0);
292 m_treeFactory =
new DesignerEditorFactory(m_core,
this);
294 m_groupFactory =
new DesignerEditorFactory(m_core,
this);
296 m_buttonBrowser->setFactoryForManager(variantManager, m_groupFactory);
297 m_treeBrowser->setFactoryForManager(variantManager, m_treeFactory);
299 m_stackedWidget->setCurrentIndex(m_treeIndex);
300 m_currentBrowser = m_treeBrowser;
301 m_treeAction->setChecked(
true);
303 connect(m_groupFactory, &DesignerEditorFactory::resetProperty,
304 this, &PropertyEditor::slotResetProperty);
305 connect(m_treeFactory, &DesignerEditorFactory::resetProperty,
306 this, &PropertyEditor::slotResetProperty);
307 connect(m_propertyManager, &DesignerPropertyManager::valueChanged,
308 this, &PropertyEditor::slotValueChanged);
311 QDesignerSettingsInterface *settings = m_core->settingsManager();
312 settings->beginGroup(SettingsGroupC);
313 const SettingsView view = settings->value(ViewKeyC, TreeView).toInt() == TreeView ? TreeView : ButtonView;
315 m_sorting = settings->value(SortedKeyC,
false).toBool();
316 m_coloring = settings->value(ColorKeyC,
true).toBool();
317 const QVariantMap expansionState = settings->value(ExpansionKeyC, QVariantMap()).toMap();
318 const int splitterPosition = settings->value(SplitterPositionKeyC, 150).toInt();
319 settings->endGroup();
321 m_sortingAction->setChecked(m_sorting);
322 m_coloringAction->setChecked(m_coloring);
326 m_currentBrowser = m_treeBrowser;
327 m_stackedWidget->setCurrentIndex(m_treeIndex);
328 m_treeAction->setChecked(
true);
331 m_currentBrowser = m_buttonBrowser;
332 m_stackedWidget->setCurrentIndex(m_buttonIndex);
333 m_buttonAction->setChecked(
true);
337 for (
auto it = expansionState.cbegin(), cend = expansionState.cend(); it != cend; ++it)
338 m_expansionState.insert(it.key(), it.value().toBool());
340 updateActionsState();
348 storeExpansionState();
354 QDesignerSettingsInterface *settings = m_core->settingsManager();
355 settings->beginGroup(SettingsGroupC);
356 settings->setValue(ViewKeyC, QVariant(m_treeAction->isChecked() ? TreeView : ButtonView));
357 settings->setValue(ColorKeyC, QVariant(m_coloring));
358 settings->setValue(SortedKeyC, QVariant(m_sorting));
360 QVariantMap expansionState;
361 for (
auto it = m_expansionState.cbegin(), cend = m_expansionState.cend(); it != cend; ++it)
362 expansionState.insert(it.key(), QVariant(it.value()));
363 settings->setValue(ExpansionKeyC, expansionState);
365 settings->endGroup();
370 if (m_buttonBrowser == m_currentBrowser)
372 else if (m_treeBrowser == m_currentBrowser)
378 if (m_buttonBrowser == m_currentBrowser)
380 if (m_treeBrowser == m_currentBrowser)
387 if (m_currentBrowser == m_treeBrowser) {
390 qWarning(
"** WARNING %s is not implemented for this browser.", Q_FUNC_INFO);
396 return m_currentBrowser == m_treeBrowser ? m_treeBrowser
->isItemVisible(item
) :
true;
400
401
402
404void PropertyEditor::storePropertiesExpansionState(
const QList<QtBrowserItem *> &items)
406 for (QtBrowserItem *propertyItem : items) {
407 if (!propertyItem->children().isEmpty()) {
408 QtProperty *property = propertyItem->property();
409 const QString propertyName = property->propertyName();
410 const auto itGroup = m_propertyToGroup.constFind(property);
411 if (itGroup != m_propertyToGroup.constEnd()) {
412 const QString key = itGroup.value() + u'|' + propertyName;
413 m_expansionState[key] = isExpanded(propertyItem);
421 const auto items = m_currentBrowser->topLevelItems();
423 storePropertiesExpansionState(items);
425 for (QtBrowserItem *item : items) {
426 const QString groupName = item->property()->propertyName();
427 auto propertyItems = item->children();
428 if (!propertyItems.isEmpty())
429 m_expansionState[groupName] = isExpanded(item);
432 storePropertiesExpansionState(propertyItems);
439 const auto items = m_currentBrowser->topLevelItems();
440 for (QtBrowserItem *group : items)
441 setExpanded(group,
false);
444void PropertyEditor::applyPropertiesExpansionState(
const QList<QtBrowserItem *> &items)
446 for (QtBrowserItem *propertyItem : items) {
447 const auto excend = m_expansionState.cend();
448 QtProperty *property = propertyItem->property();
449 const QString propertyName = property->propertyName();
450 const auto itGroup = m_propertyToGroup.constFind(property);
451 if (itGroup != m_propertyToGroup.constEnd()) {
452 const QString key = itGroup.value() + u'|' + propertyName;
453 const auto pit = m_expansionState.constFind(key);
455 setExpanded(propertyItem, pit.value());
457 setExpanded(propertyItem,
false);
464 const auto items = m_currentBrowser->topLevelItems();
466 applyPropertiesExpansionState(items);
468 const auto excend = m_expansionState.cend();
469 for (QtBrowserItem *item : items) {
470 const QString groupName = item->property()->propertyName();
471 const auto git = m_expansionState.constFind(groupName);
473 setExpanded(item, git.value());
475 setExpanded(item,
true);
477 applyPropertiesExpansionState(item->children());
482int PropertyEditor::applyPropertiesFilter(
const QList<QtBrowserItem *> &items)
485 const bool matchAll = m_filterPattern.isEmpty();
486 for (QtBrowserItem *propertyItem : items) {
487 QtProperty *property = propertyItem->property();
488 const QString propertyName = property->propertyName();
489 const bool showProperty = matchAll || propertyName.contains(m_filterPattern, Qt::CaseInsensitive);
490 setItemVisible(propertyItem, showProperty);
499 const auto items = m_currentBrowser->topLevelItems();
501 applyPropertiesFilter(items);
503 for (QtBrowserItem *item : items)
504 setItemVisible(item, applyPropertiesFilter(item->children()));
515 if (event->type() == QEvent::PaletteChange)
516 updateForegroundBrightness();
518 return QDesignerPropertyEditor::event(event);
523 QColor c = palette().color(QPalette::Text);
524 bool newBrightness = qRound(0.3 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF());
526 if (m_brightness == newBrightness)
529 m_brightness = newBrightness;
541 const auto itProp = m_propertyToGroup.constFind(property);
542 if (itProp != m_propertyToGroup.constEnd())
543 groupProperty = m_nameToGroup.value(itProp.value());
545 const int groupIdx = m_groups.indexOf(groupProperty);
546 std::pair<QColor, QColor> pair;
547 if (groupIdx != -1) {
548 if (groupProperty == m_dynamicGroup)
549 pair = m_dynamicColor;
550 else if (isLayoutGroup(groupProperty))
551 pair = m_layoutColor;
553 pair = m_colors[groupIdx % m_colors.size()];
563 for (
auto itProperty = m_nameToProperty.cbegin(), end = m_nameToProperty.cend(); itProperty != end; ++itProperty)
564 m_currentBrowser->addProperty(itProperty.value());
566 for (QtProperty *group : std::as_const(m_groups)) {
567 QtBrowserItem *item = m_currentBrowser->addProperty(group);
568 if (m_currentBrowser == m_treeBrowser)
569 m_treeBrowser->setBackgroundColor(item, propertyColor(group));
570 group->setModified(m_currentBrowser == m_treeBrowser);
577 return group->propertyName() == m_strings.m_layout;
582 m_coloringAction->setEnabled(m_treeAction->isChecked() && !m_sortingAction->isChecked());
610 if (sort == m_sorting)
613 storeExpansionState();
621 applyExpansionState();
624 updateActionsState();
629 if (m_treeBrowser && m_currentBrowser == m_treeBrowser) {
630 const auto items = m_treeBrowser->topLevelItems();
631 for (QtBrowserItem *item : items)
632 m_treeBrowser->setBackgroundColor(item, propertyColor(item->property()));
638 if (coloring == m_coloring)
641 m_coloring = coloring;
693 qDebug() <<
"PropertyEditor::setReadOnly() request";
696void PropertyEditor::setPropertyValue(
const QString &name,
const QVariant &value,
bool changed)
698 const auto it = m_nameToProperty.constFind(name);
699 if (it == m_nameToProperty.constEnd())
702 updateBrowserValue(property, value);
707
710 if (!m_propertySheet)
713 updateToolBarLabel();
715 const int propertyCount = m_propertySheet->count();
716 const auto npcend = m_nameToProperty.cend();
717 for (
int i = 0; i < propertyCount; ++i) {
718 const QString propertyName = m_propertySheet->propertyName(i);
719 const auto it = m_nameToProperty.constFind(propertyName);
721 updateBrowserValue(it.value(), m_propertySheet->property(i));
727 if (o->isWidgetType() && !qstrcmp(o->metaObject()->className(),
"QLayoutWidget"))
728 return static_cast<QWidget*>(o)->layout();
737 if (QLayout *l = layoutOfQLayoutWidget(m_object))
738 objectName = l->objectName();
740 objectName = m_object->objectName();
741 className = realClassName(m_object);
744 m_classLabel->setVisible(!objectName.isEmpty() || !className.isEmpty());
745 m_classLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
747 QString classLabelText;
748 if (!objectName.isEmpty())
749 classLabelText += objectName +
" : "_L1;
750 classLabelText += className;
753 m_classLabel->setToolTip(tr(
"Object: %1\nClass: %2")
754 .arg(objectName, className));
762 const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(v);
763 v = e.metaEnum.keys().indexOf(e.metaEnum.valueToKey(e.value));
765 const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(v);
766 v = QVariant(f.value);
768 const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(v);
769 v = QVariant(f.value);
771 QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));
774 index = sheet->indexOf(property->propertyName());
775 if (sheet && m_propertyToGroup.contains(property)) {
780 if (type == QMetaType::QString && !property->subProperties().isEmpty()) {
781 const int fontIndex = m_propertySheet->indexOf(m_strings.m_fontProperty);
783 property->setAttribute(m_strings.m_fontAttribute, m_propertySheet->property(fontIndex));
786 m_updatingBrowser =
true;
787 property->setValue(v);
788 if (sheet && sheet->isResourceProperty(index))
789 property->setAttribute(u"defaultResource"_s, sheet->defaultResourceProperty(index));
790 m_updatingBrowser =
false;
793int PropertyEditor::toBrowserType(
const QVariant &value,
const QString &propertyName)
const
796 if (m_strings.m_alignmentProperties.contains(propertyName))
803 return value.userType();
811 QString className = QLatin1StringView(object->metaObject()->className());
812 const QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
813 if (QDesignerWidgetDataBaseItemInterface *widgetItem = db->item(db->indexOfObject(object,
true))) {
814 className = widgetItem->name();
816 if (object->isWidgetType() && className == m_strings.m_qLayoutWidget
817 &&
static_cast<QWidget*>(object)->layout()) {
818 className = QLatin1StringView(
static_cast<QWidget*>(object)->layout()->metaObject()->className());
822 if (className.startsWith(m_strings.m_designerPrefix))
823 className.remove(1, m_strings.m_designerPrefix.size() - 1);
830 if (type == qMetaTypeId<PropertySheetStringValue>())
831 type = QMetaType::QString;
832 if (type <
int(QMetaType::User))
833 return QMetaType(type).name();
839 return "QKeySequence";
844 if (type == QMetaType::UnknownType)
846 if (type == QMetaType::User)
848 const auto metaType = QMetaType(type);
849 if (metaType.isValid())
850 return metaType.name();
857 QTextStream str(&rc);
859 str <<
"The property \"" << propertyName <<
"\" of type ("
860 << (typeS ? typeS :
"unknown") <<
") is not supported yet.";
866 QDesignerFormWindowInterface *oldFormWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
868 const bool editNewDynamicProperty = object !=
nullptr && m_object == object && !m_recentlyAddedDynamicProperty.isEmpty();
870 m_propertyManager->setObject(object);
871 QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
873 if (object !=
nullptr && formWindow ==
nullptr) {
874 formWindow = m_core->formWindowManager()->activeFormWindow();
875 if (formWindow ==
nullptr) {
876 qWarning(
"PropertyEditor::setObject(): Unable to find form window for \"%s\".",
877 qPrintable(object->objectName()));
881 FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
882 const bool idIdBasedTranslation = fwb && fwb->useIdBasedTranslations();
888 storeExpansionState();
892 updateToolBarLabel();
894 QMap<QString, QtVariantProperty *> toRemove = m_nameToProperty;
897 qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);
898 const QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));
902 QExtensionManager *m = m_core->extensionManager();
904 m_propertySheet = qobject_cast<QDesignerPropertySheetExtension*>(m->extension(object, Q_TYPEID(QDesignerPropertySheetExtension)));
905 if (m_propertySheet) {
907 const int propertyCount = m_propertySheet->count();
908 for (
int i = 0; i < propertyCount; ++i) {
909 if (!m_propertySheet->isVisible(i))
912 const QString propertyName = m_propertySheet->propertyName(i);
913 if (m_propertySheet->indexOf(propertyName) != i)
915 const QString groupName = m_propertySheet->propertyGroup(i);
916 const auto rit = toRemove.constFind(propertyName);
917 if (rit != toRemove.constEnd()) {
922 if (m_propertyToGroup.value(property) == groupName
923 && (idIdBasedTranslationUnchanged || propertyType != stringTypeId)
924 && toBrowserType(m_propertySheet->property(i), propertyName) == propertyType) {
925 toRemove.remove(propertyName);
931 for (
auto itRemove = toRemove.cbegin(), end = toRemove.cend(); itRemove != end; ++itRemove) {
933 m_nameToProperty.remove(itRemove.key());
934 m_propertyToGroup.remove(property);
938 if (oldFormWindow != formWindow)
941 bool isMainContainer =
false;
943 if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(widget)) {
944 isMainContainer = (fw->mainContainer() == widget);
949 if (m_propertySheet) {
950 const QString className = WidgetFactory::classNameOf(formWindow->core(), m_object);
951 const QDesignerCustomWidgetData customData = formWindow->core()->pluginManager()->customWidgetData(className);
955 const int propertyCount = m_propertySheet->count();
956 for (
int i = 0; i < propertyCount; ++i) {
957 if (!m_propertySheet->isVisible(i))
960 const QString propertyName = m_propertySheet->propertyName(i);
961 if (m_propertySheet->indexOf(propertyName) != i)
963 const QVariant value = m_propertySheet->property(i);
965 const int type = toBrowserType(value, propertyName);
968 bool newProperty = property ==
nullptr;
970 property = m_propertyManager->addProperty(type, propertyName);
974 const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(value);
975 m_updatingBrowser =
true;
976 property->setAttribute(m_strings.m_enumNamesAttribute, e.metaEnum.keys());
977 m_updatingBrowser =
false;
979 const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(value);
980 QList<std::pair<QString, uint>> flags;
981 for (
const QString &name : f.metaFlags.keys()) {
982 const uint val = f.metaFlags.keyToValue(name);
983 flags.append({name, val});
985 m_updatingBrowser =
true;
988 property->setAttribute(m_strings.m_flagsAttribute, v);
989 m_updatingBrowser =
false;
994 if (property !=
nullptr) {
996 || (sheet && sheet->isDefaultDynamicProperty(i));
997 QString descriptionToolTip;
998 if (!dynamicProperty && !customData.isNull())
999 descriptionToolTip = customData.propertyToolTip(propertyName);
1000 if (descriptionToolTip.isEmpty()) {
1002 descriptionToolTip = propertyName +
" ("_L1
1003 + QLatin1StringView(typeS) +
')'_L1;
1006 if (!descriptionToolTip.isEmpty())
1007 property->setDescriptionToolTip(descriptionToolTip);
1009 case QMetaType::QPalette:
1010 setupPaletteProperty(property);
1012 case QMetaType::QKeySequence:
1018 if (type == QMetaType::QString || type == qMetaTypeId<PropertySheetStringValue>())
1019 setupStringProperty(property, isMainContainer);
1020 property->setAttribute(m_strings.m_resettableAttribute, m_propertySheet->hasReset(i));
1022 const QString groupName = m_propertySheet->propertyGroup(i);
1026 auto itPrev = m_nameToProperty.insert(propertyName, property);
1027 m_propertyToGroup[property] = groupName;
1030 if (itPrev != m_nameToProperty.begin())
1031 previous = (--itPrev).value();
1035 const auto gnit = m_nameToGroup.constFind(groupName);
1036 if (gnit != m_nameToGroup.constEnd()) {
1037 groupProperty = gnit.value();
1043 m_nameToGroup[groupName] = groupProperty;
1044 m_groups.append(groupProperty);
1045 if (dynamicProperty)
1046 m_dynamicGroup = groupProperty;
1047 if (m_currentBrowser == m_treeBrowser && item) {
1048 m_treeBrowser->setBackgroundColor(item, propertyColor(groupProperty));
1053
1054
1055
1056
1057
1058 if (lastGroup != groupProperty) {
1059 lastGroup = groupProperty;
1060 lastProperty =
nullptr;
1061 const auto subProperties = lastGroup->subProperties();
1062 if (!subProperties.isEmpty())
1063 lastProperty = subProperties.constLast();
1064 lastGroup = groupProperty;
1066 if (!m_groups.contains(groupProperty))
1067 m_groups.append(groupProperty);
1071 lastProperty = property;
1073 updateBrowserValue(property, value);
1076 if (propertyName ==
"geometry"_L1 && type == QMetaType::QRect) {
1077 const auto &subProperties = property->subProperties();
1078 for (QtProperty *subProperty : subProperties) {
1079 const QString subPropertyName = subProperty->propertyName();
1080 if (subPropertyName ==
"X"_L1 || subPropertyName ==
"Y"_L1)
1081 subProperty->setEnabled(!isMainContainer);
1086 const int typeId = value.typeId();
1087 if (typeId != qMetaTypeId<QTimeZone>())
1088 qWarning(
"%s", qPrintable(msgUnsupportedType(propertyName, type)));
1092 QMap<QString, QtVariantProperty *> groups = m_nameToGroup;
1093 for (
auto itGroup = groups.cbegin(), end = groups.cend(); itGroup != end; ++itGroup) {
1095 if (groupProperty->subProperties().isEmpty()) {
1096 if (groupProperty == m_dynamicGroup)
1097 m_dynamicGroup =
nullptr;
1098 delete groupProperty;
1099 m_nameToGroup.remove(itGroup.key());
1103 m_addDynamicAction->setEnabled(addEnabled);
1104 m_removeDynamicAction->setEnabled(
false);
1105 applyExpansionState();
1108 if (editNewDynamicProperty) {
1111 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1112 editProperty(m_recentlyAddedDynamicProperty);
1114 m_recentlyAddedDynamicProperty.clear();
1115 m_filterWidget->setEnabled(object);
1120 m_updatingBrowser =
true;
1122 m_updatingBrowser =
false;
1129 const auto topLevelItems = m_currentBrowser->topLevelItems();
1141 if (
QtBrowserItem *topLevelItem = nonFakePropertyBrowserItem(browserItem)) {
1149 QDesignerFormWindowInterface *form = m_core->formWindowManager()->activeFormWindow();
1162 if (!m_propertyToGroup.contains(property))
1165 emit resetProperty(property->propertyName());
1170 if (m_updatingBrowser)
1173 if (!m_propertySheet)
1181 if (!m_propertyToGroup.contains(property))
1185 PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(m_propertySheet->property(m_propertySheet->indexOf(property->propertyName())));
1186 const int val = value.toInt();
1187 const QString valName = varProp->attributeValue(m_strings.m_enumNamesAttribute).toStringList().at(val);
1189 e.value = e.metaEnum.parseEnum(valName, &ok);
1193 emitPropertyValueChanged(property->propertyName(), v,
true);
1197 emitPropertyValueChanged(property->propertyName(), value, enableSubPropertyHandling);
1206 qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);
1211 return m_propertyToGroup.contains(item->property())
1212 && dynamicSheet->isDynamicProperty(m_propertySheet->indexOf(item->property()->propertyName()));
1220 const auto items = m_currentBrowser->items(property);
1221 if (items.size() == 1)
1222 browserItem = items.constFirst();
1224 if (browserItem ==
nullptr)
1226 m_currentBrowser->setFocus(Qt::OtherFocusReason);
1227 if (m_currentBrowser == m_treeBrowser) {
1236 m_removeDynamicAction->setEnabled(isDynamicProperty(item));
1243 if (isDynamicProperty(item))
1244 emit removeDynamicProperty(item->property()->propertyName());
1249 m_filterPattern = pattern;
virtual bool dynamicPropertiesAllowed() const =0
virtual bool isDynamicProperty(int index) const =0
QtBrowserItem * currentItem() const
Returns the current item in the property browser.
QtBrowserItem * insertProperty(QtProperty *property, QtProperty *afterProperty)
Inserts the given property (and its subproperties) after the specified afterProperty in the browser's...
void setCurrentItem(QtBrowserItem *)
Sets the current item in the property browser to item.
void clear()
Removes all the properties from the editor, but does not delete them since they can still be used in ...
The QtBrowserItem class represents a property in a property browser instance.
QtProperty * property() const
Returns the property which is accosiated with this item.
QtBrowserItem * parent() const
Returns the parent item of this item.
The QtProperty class encapsulates an instance of a property.
void setModified(bool modified)
Sets the property's modified state according to the passed modified value.
void setEnabled(bool enable)
Enables or disables the property according to the passed enable value.
void insertSubProperty(QtProperty *property, QtProperty *afterProperty)
Inserts the given property after the specified precedingProperty into this property's list of subprop...
void setRootIsDecorated(bool show)
bool isExpanded(QtBrowserItem *item) const
Returns true if the item is expanded; otherwise returns false.
void editItem(QtBrowserItem *item)
Sets the current item to item and opens the relevant editor for it.
void setItemVisible(QtBrowserItem *item, bool visible)
Sets the item to be visible, depending on the value of visible.
void setExpanded(QtBrowserItem *item, bool expanded)
Sets the item to either collapse or expanded, depending on the value of expanded.
int splitterPosition() const
bool isItemVisible(QtBrowserItem *item) const
Returns true if the item is visible; otherwise returns false.
void setSplitterPosition(int position)
void setPropertiesWithoutValueMarked(bool mark)
The QtVariantPropertyManager class provides and manages QVariant based properties.
static int groupTypeId()
Returns the type id for a group property.
static int enumTypeId()
Returns the type id for an enum property.
QtVariantProperty * variantProperty(const QtProperty *property) const
Returns the given property converted into a QtVariantProperty.
The QtVariantProperty class is a convenience class handling QVariant based properties.
int propertyType() const
Returns this property's type.
void setSpacing(int spacing)
void setFormWindowBase(FormWindowBase *fwb)
static void setUseIdBasedTranslations(bool v)
bool resetFontSubProperty(QtProperty *property)
static int designerAlignmentTypeId()
void reloadResourceProperties()
static int designerFlagTypeId()
static bool useIdBasedTranslations()
bool resetIconSubProperty(QtProperty *subProperty)
bool resetTextAlignmentProperty(QtProperty *property)
QSize sizeHint() const override
void setElidemode(Qt::TextElideMode mode)
void paintEvent(QPaintEvent *e) override
This event handler can be reimplemented in a subclass to receive paint events passed in event.
void setText(const QString &text)
ElidingLabel(const QString &text=QString(), QWidget *parent=nullptr)
void reloadResourceProperties() override
QString currentPropertyName() const override
Returns the name of the currently selected property in the property editor.
bool event(QEvent *event) override
This virtual function receives events to an object and should return true if the event e was recogniz...
~PropertyEditor() override
QDesignerFormEditorInterface * core() const override
Returns a pointer to \QD's current QDesignerFormEditorInterface object.
void setObject(QObject *object) override
Changes the currently selected object in \QD's workspace, to object.
void setReadOnly(bool readOnly) override
If readOnly is true, the property editor is made write protected; otherwise the write protection is r...
bool isReadOnly() const override
Returns true if the property editor is write protected; otherwise false.
void updatePropertySheet() override
Auxiliary methods to store/retrieve settings.
static const char * typeName(int type)
static QToolButton * createDropDownButton(QAction *defaultAction, QWidget *parent=nullptr)
static QLayout * layoutOfQLayoutWidget(QObject *o)
static QString msgUnsupportedType(const QString &propertyName, int type)
static constexpr auto SplitterPositionKeyC
static constexpr auto SettingsGroupC
static constexpr auto ViewKeyC
static constexpr auto ColorKeyC
static constexpr auto ExpansionKeyC
static constexpr auto SortedKeyC