19#include <QtDesigner/abstractformeditor.h>
20#include <QtDesigner/abstractformwindowmanager.h>
21#include <QtDesigner/qextensionmanager.h>
22#include <QtDesigner/propertysheet.h>
23#include <QtDesigner/abstractwidgetdatabase.h>
24#include <QtDesigner/abstractsettings.h>
26#include <qdesigner_utils_p.h>
27#include <qdesigner_propertycommand_p.h>
28#include <metadatabase_p.h>
29#include <iconloader_p.h>
30#include <widgetfactory_p.h>
32#include <QtWidgets/qlabel.h>
33#include <QtWidgets/qlineedit.h>
34#include <QtWidgets/qmenu.h>
35#include <QtWidgets/qapplication.h>
36#include <QtWidgets/qboxlayout.h>
37#include <QtWidgets/qscrollarea.h>
38#include <QtWidgets/qstackedwidget.h>
39#include <QtWidgets/qtoolbar.h>
40#include <QtWidgets/qtoolbutton.h>
42#include <QtGui/qaction.h>
43#include <QtGui/qactiongroup.h>
44#include <QtGui/qpainter.h>
46#include <QtCore/qdebug.h>
47#include <QtCore/qtextstream.h>
48#include <QtCore/qtimezone.h>
50enum SettingsView { TreeView, ButtonView };
54using namespace Qt::StringLiterals;
75 { setContentsMargins(3, 2, 3, 2); }
97 QSize size = fontMetrics().boundingRect(m_text).size();
98 size += QSize(contentsMargins().left() + contentsMargins().right(),
99 contentsMargins().top() + contentsMargins().bottom());
104 QPainter painter(
this);
105 painter.setPen(QColor(0, 0, 0, 60));
106 painter.setBrush(QColor(255, 255, 255, 40));
107 painter.drawRect(rect().adjusted(0, 0, -1, -1));
108 painter.setPen(palette().windowText().color());
109 painter.drawText(contentsRect(), Qt::AlignLeft,
110 fontMetrics().elidedText(m_text, Qt::ElideRight, width(), 0));
117 m_alignmentProperties{u"alignment"_s,
118 u"layoutLabelAlignment"_s,
119 u"layoutFormAlignment"_s},
120 m_fontProperty(u"font"_s),
121 m_qLayoutWidget(u"QLayoutWidget"_s),
122 m_designerPrefix(u"QDesigner"_s),
123 m_layout(u"Layout"_s),
124 m_validationModeAttribute(u"validationMode"_s),
125 m_fontAttribute(u"font"_s),
126 m_superPaletteAttribute(u"superPalette"_s),
127 m_enumNamesAttribute(u"enumNames"_s),
128 m_resettableAttribute(u"resettable"_s),
129 m_flagsAttribute(u"flags"_s)
137 QObject *o = object();
140 QDesignerMetaDataBaseInterface *db = core()->metaDataBase();
148 const StringPropertyParameters params = textPropertyValidationMode(core(), m_object, property->propertyName(), isMainContainer);
150 const bool hasComment = params.second;
151 property->setAttribute(m_strings.m_validationModeAttribute, params.first);
154 qDeleteAll(property->subProperties());
159 QPalette superPalette = QPalette();
162 if (currentWidget->isWindow())
163 superPalette = QApplication::palette(currentWidget);
165 if (currentWidget->parentWidget())
166 superPalette = currentWidget->parentWidget()->palette();
169 m_updatingBrowser =
true;
170 property->setAttribute(m_strings.m_superPaletteAttribute, superPalette);
171 m_updatingBrowser =
false;
183 QDesignerPropertyEditor(parent, flags),
185 m_propertyManager(
new DesignerPropertyManager(m_core,
this)),
186 m_stackedWidget(
new QStackedWidget),
187 m_filterWidget(
new QLineEdit),
188 m_addDynamicAction(
new QAction(createIconSet(
"plus.png"_L1), tr(
"Add Dynamic Property..."),
this)),
189 m_removeDynamicAction(
new QAction(createIconSet(
"minus.png"_L1), tr(
"Remove Dynamic Property"),
this)),
190 m_sortingAction(
new QAction(createIconSet(
"sort.png"_L1), tr(
"Sorting"),
this)),
191 m_coloringAction(
new QAction(createIconSet(
"color.png"_L1), tr(
"Color Groups"),
this)),
192 m_treeAction(
new QAction(tr(
"Tree View"),
this)),
193 m_buttonAction(
new QAction(tr(
"Drop Down Button View"),
this)),
196 const QColor colors[] = {{255, 230, 191}, {255, 255, 191}, {191, 255, 191},
197 {199, 255, 255}, {234, 191, 255}, {255, 191, 239}};
198 const int darknessFactor = 250;
199 m_colors.reserve(std::size(colors));
200 for (
const QColor &c : colors)
201 m_colors.append({c, c.darker(darknessFactor)});
202 QColor dynamicColor(191, 207, 255);
203 QColor layoutColor(255, 191, 191);
204 m_dynamicColor = {dynamicColor, dynamicColor.darker(darknessFactor)};
205 m_layoutColor = {layoutColor, layoutColor.darker(darknessFactor)};
207 updateForegroundBrightness();
209 QActionGroup *actionGroup =
new QActionGroup(
this);
211 m_treeAction->setCheckable(
true);
212 m_treeAction->setIcon(createIconSet(
"widgets/listview.png"_L1));
213 m_buttonAction->setCheckable(
true);
214 m_buttonAction->setIcon(createIconSet(
"dropdownbutton.png"_L1));
216 actionGroup->addAction(m_treeAction);
217 actionGroup->addAction(m_buttonAction);
218 connect(actionGroup, &QActionGroup::triggered,
219 this, &PropertyEditor::slotViewTriggered);
222 QActionGroup *addDynamicActionGroup =
new QActionGroup(
this);
223 connect(addDynamicActionGroup, &QActionGroup::triggered,
224 this, &PropertyEditor::slotAddDynamicProperty);
226 QMenu *addDynamicActionMenu =
new QMenu(
this);
227 m_addDynamicAction->setMenu(addDynamicActionMenu);
228 m_addDynamicAction->setEnabled(
false);
229 QAction *addDynamicAction = addDynamicActionGroup->addAction(tr(
"String..."));
230 addDynamicAction->setData(
static_cast<
int>(QMetaType::QString));
231 addDynamicActionMenu->addAction(addDynamicAction);
232 addDynamicAction = addDynamicActionGroup->addAction(tr(
"Bool..."));
233 addDynamicAction->setData(
static_cast<
int>(QMetaType::Bool));
234 addDynamicActionMenu->addAction(addDynamicAction);
235 addDynamicActionMenu->addSeparator();
236 addDynamicAction = addDynamicActionGroup->addAction(tr(
"Other..."));
237 addDynamicAction->setData(
static_cast<
int>(QMetaType::UnknownType));
238 addDynamicActionMenu->addAction(addDynamicAction);
240 m_removeDynamicAction->setEnabled(
false);
241 connect(m_removeDynamicAction, &QAction::triggered,
this, &
PropertyEditor::slotRemoveDynamicProperty);
243 QAction *configureAction =
new QAction(tr(
"Configure Property Editor"),
this);
244 configureAction->setIcon(createIconSet(
"configure.png"_L1));
245 QMenu *configureMenu =
new QMenu(
this);
246 configureAction->setMenu(configureMenu);
248 m_sortingAction->setCheckable(
true);
249 connect(m_sortingAction, &QAction::toggled,
this, &
PropertyEditor::slotSorting);
251 m_coloringAction->setCheckable(
true);
252 connect(m_coloringAction, &QAction::toggled,
this, &
PropertyEditor::slotColoring);
254 configureMenu->addAction(m_sortingAction);
255 configureMenu->addAction(m_coloringAction);
256 configureMenu->addSeparator();
257 configureMenu->addAction(m_treeAction);
258 configureMenu->addAction(m_buttonAction);
260 QToolBar *toolBar =
new QToolBar;
261 toolBar->addWidget(m_filterWidget);
262 toolBar->addWidget(createDropDownButton(m_addDynamicAction));
263 toolBar->addAction(m_removeDynamicAction);
264 toolBar->addWidget(createDropDownButton(configureAction));
266 QScrollArea *buttonScroll =
new QScrollArea(m_stackedWidget);
268 buttonScroll->setWidgetResizable(
true);
269 buttonScroll->setWidget(m_buttonBrowser);
270 m_buttonIndex = m_stackedWidget->addWidget(buttonScroll);
271 connect(m_buttonBrowser, &QtAbstractPropertyBrowser::currentItemChanged,
274 m_treeBrowser =
new QtTreePropertyBrowser(m_stackedWidget);
277 m_treeBrowser->setResizeMode(QtTreePropertyBrowser::Interactive);
278 m_treeIndex = m_stackedWidget->addWidget(m_treeBrowser);
279 connect(m_treeBrowser, &QtAbstractPropertyBrowser::currentItemChanged,
281 m_filterWidget->setPlaceholderText(tr(
"Filter"));
282 m_filterWidget->setClearButtonEnabled(
true);
283 connect(m_filterWidget, &QLineEdit::textChanged,
this, &PropertyEditor::setFilter);
285 QVBoxLayout *layout =
new QVBoxLayout(
this);
286 layout->addWidget(toolBar);
287 layout->addWidget(m_classLabel);
288 layout->addSpacerItem(
new QSpacerItem(0,1));
289 layout->addWidget(m_stackedWidget);
290 layout->setContentsMargins(QMargins());
291 layout->setSpacing(0);
293 m_treeFactory =
new DesignerEditorFactory(m_core,
this);
295 m_groupFactory =
new DesignerEditorFactory(m_core,
this);
297 m_buttonBrowser->setFactoryForManager(variantManager, m_groupFactory);
298 m_treeBrowser->setFactoryForManager(variantManager, m_treeFactory);
300 m_stackedWidget->setCurrentIndex(m_treeIndex);
301 m_currentBrowser = m_treeBrowser;
302 m_treeAction->setChecked(
true);
304 connect(m_groupFactory, &DesignerEditorFactory::resetProperty,
305 this, &PropertyEditor::slotResetProperty);
306 connect(m_treeFactory, &DesignerEditorFactory::resetProperty,
307 this, &PropertyEditor::slotResetProperty);
308 connect(m_propertyManager, &DesignerPropertyManager::valueChanged2,
309 this, &PropertyEditor::slotValueChanged);
312 QDesignerSettingsInterface *settings = m_core->settingsManager();
313 settings->beginGroup(SettingsGroupC);
314 const SettingsView view = settings->value(ViewKeyC, TreeView).toInt() == TreeView ? TreeView : ButtonView;
316 m_sorting = settings->value(SortedKeyC,
false).toBool();
317 m_coloring = settings->value(ColorKeyC,
true).toBool();
318 const QVariantMap expansionState = settings->value(ExpansionKeyC, QVariantMap()).toMap();
319 const int splitterPosition = settings->value(SplitterPositionKeyC, 150).toInt();
320 settings->endGroup();
322 m_sortingAction->setChecked(m_sorting);
323 m_coloringAction->setChecked(m_coloring);
327 m_currentBrowser = m_treeBrowser;
328 m_stackedWidget->setCurrentIndex(m_treeIndex);
329 m_treeAction->setChecked(
true);
332 m_currentBrowser = m_buttonBrowser;
333 m_stackedWidget->setCurrentIndex(m_buttonIndex);
334 m_buttonAction->setChecked(
true);
338 for (
auto it = expansionState.cbegin(), cend = expansionState.cend(); it != cend; ++it)
339 m_expansionState.insert(it.key(), it.value().toBool());
341 updateActionsState();
349 storeExpansionState();
355 QDesignerSettingsInterface *settings = m_core->settingsManager();
356 settings->beginGroup(SettingsGroupC);
357 settings->setValue(ViewKeyC, QVariant(m_treeAction->isChecked() ? TreeView : ButtonView));
358 settings->setValue(ColorKeyC, QVariant(m_coloring));
359 settings->setValue(SortedKeyC, QVariant(m_sorting));
361 QVariantMap expansionState;
362 for (
auto it = m_expansionState.cbegin(), cend = m_expansionState.cend(); it != cend; ++it)
363 expansionState.insert(it.key(), QVariant(it.value()));
364 settings->setValue(ExpansionKeyC, expansionState);
366 settings->endGroup();
371 if (m_buttonBrowser == m_currentBrowser)
373 else if (m_treeBrowser == m_currentBrowser)
379 if (m_buttonBrowser == m_currentBrowser)
381 if (m_treeBrowser == m_currentBrowser)
388 if (m_currentBrowser == m_treeBrowser) {
391 qWarning(
"** WARNING %s is not implemented for this browser.", Q_FUNC_INFO);
397 return m_currentBrowser == m_treeBrowser ? m_treeBrowser
->isItemVisible(item
) :
true;
401
402
403
405void PropertyEditor::storePropertiesExpansionState(
const QList<QtBrowserItem *> &items)
407 for (QtBrowserItem *propertyItem : items) {
408 if (!propertyItem->children().isEmpty()) {
409 QtProperty *property = propertyItem->property();
410 const QString propertyName = property->propertyName();
411 const auto itGroup = m_propertyToGroup.constFind(property);
412 if (itGroup != m_propertyToGroup.constEnd()) {
413 const QString key = itGroup.value() + u'|' + propertyName;
414 m_expansionState[key] = isExpanded(propertyItem);
422 const auto items = m_currentBrowser->topLevelItems();
424 storePropertiesExpansionState(items);
426 for (QtBrowserItem *item : items) {
427 const QString groupName = item->property()->propertyName();
428 auto propertyItems = item->children();
429 if (!propertyItems.isEmpty())
430 m_expansionState[groupName] = isExpanded(item);
433 storePropertiesExpansionState(propertyItems);
440 const auto items = m_currentBrowser->topLevelItems();
441 for (QtBrowserItem *group : items)
442 setExpanded(group,
false);
445void PropertyEditor::applyPropertiesExpansionState(
const QList<QtBrowserItem *> &items)
447 for (QtBrowserItem *propertyItem : items) {
448 const auto excend = m_expansionState.cend();
449 QtProperty *property = propertyItem->property();
450 const QString propertyName = property->propertyName();
451 const auto itGroup = m_propertyToGroup.constFind(property);
452 if (itGroup != m_propertyToGroup.constEnd()) {
453 const QString key = itGroup.value() + u'|' + propertyName;
454 const auto pit = m_expansionState.constFind(key);
456 setExpanded(propertyItem, pit.value());
458 setExpanded(propertyItem,
false);
465 const auto items = m_currentBrowser->topLevelItems();
467 applyPropertiesExpansionState(items);
469 const auto excend = m_expansionState.cend();
470 for (QtBrowserItem *item : items) {
471 const QString groupName = item->property()->propertyName();
472 const auto git = m_expansionState.constFind(groupName);
474 setExpanded(item, git.value());
476 setExpanded(item,
true);
478 applyPropertiesExpansionState(item->children());
483int PropertyEditor::applyPropertiesFilter(
const QList<QtBrowserItem *> &items)
486 const bool matchAll = m_filterPattern.isEmpty();
487 for (QtBrowserItem *propertyItem : items) {
488 QtProperty *property = propertyItem->property();
489 const QString propertyName = property->propertyName();
490 const bool showProperty = matchAll || propertyName.contains(m_filterPattern, Qt::CaseInsensitive);
491 setItemVisible(propertyItem, showProperty);
500 const auto items = m_currentBrowser->topLevelItems();
502 applyPropertiesFilter(items);
504 for (QtBrowserItem *item : items)
505 setItemVisible(item, applyPropertiesFilter(item->children()));
516 if (event->type() == QEvent::PaletteChange)
517 updateForegroundBrightness();
519 return QDesignerPropertyEditor::event(event);
524 QColor c = palette().color(QPalette::Text);
525 bool newBrightness = qRound(0.3 * c.redF() + 0.59 * c.greenF() + 0.11 * c.blueF());
527 if (m_brightness == newBrightness)
530 m_brightness = newBrightness;
542 const auto itProp = m_propertyToGroup.constFind(property);
543 if (itProp != m_propertyToGroup.constEnd())
544 groupProperty = m_nameToGroup.value(itProp.value());
546 const int groupIdx = m_groups.indexOf(groupProperty);
547 std::pair<QColor, QColor> pair;
548 if (groupIdx != -1) {
549 if (groupProperty == m_dynamicGroup)
550 pair = m_dynamicColor;
551 else if (isLayoutGroup(groupProperty))
552 pair = m_layoutColor;
554 pair = m_colors[groupIdx % m_colors.size()];
564 for (
auto itProperty = m_nameToProperty.cbegin(), end = m_nameToProperty.cend(); itProperty != end; ++itProperty)
565 m_currentBrowser->addProperty(itProperty.value());
567 for (QtProperty *group : std::as_const(m_groups)) {
568 QtBrowserItem *item = m_currentBrowser->addProperty(group);
569 if (m_currentBrowser == m_treeBrowser)
570 m_treeBrowser->setBackgroundColor(item, propertyColor(group));
571 group->setModified(m_currentBrowser == m_treeBrowser);
578 return group->propertyName() == m_strings.m_layout;
583 m_coloringAction->setEnabled(m_treeAction->isChecked() && !m_sortingAction->isChecked());
611 if (sort == m_sorting)
614 storeExpansionState();
622 applyExpansionState();
625 updateActionsState();
630 if (m_treeBrowser && m_currentBrowser == m_treeBrowser) {
631 const auto items = m_treeBrowser->topLevelItems();
632 for (QtBrowserItem *item : items)
633 m_treeBrowser->setBackgroundColor(item, propertyColor(item->property()));
639 if (coloring == m_coloring)
642 m_coloring = coloring;
694 qDebug() <<
"PropertyEditor::setReadOnly() request";
697void PropertyEditor::setPropertyValue(
const QString &name,
const QVariant &value,
bool changed)
699 const auto it = m_nameToProperty.constFind(name);
700 if (it == m_nameToProperty.constEnd())
703 updateBrowserValue(property, value);
708
711 if (!m_propertySheet)
714 updateToolBarLabel();
716 const int propertyCount = m_propertySheet->count();
717 const auto npcend = m_nameToProperty.cend();
718 for (
int i = 0; i < propertyCount; ++i) {
719 const QString propertyName = m_propertySheet->propertyName(i);
720 const auto it = m_nameToProperty.constFind(propertyName);
722 updateBrowserValue(it.value(), m_propertySheet->property(i));
728 if (o->isWidgetType() && !qstrcmp(o->metaObject()->className(),
"QLayoutWidget"))
729 return static_cast<QWidget*>(o)->layout();
738 if (QLayout *l = layoutOfQLayoutWidget(m_object))
739 objectName = l->objectName();
741 objectName = m_object->objectName();
742 className = realClassName(m_object);
745 m_classLabel->setVisible(!objectName.isEmpty() || !className.isEmpty());
746 m_classLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
748 QString classLabelText;
749 if (!objectName.isEmpty())
750 classLabelText += objectName +
" : "_L1;
751 classLabelText += className;
754 m_classLabel->setToolTip(tr(
"Object: %1\nClass: %2")
755 .arg(objectName, className));
764 v = e.metaEnum.keys().indexOf(e.metaEnum.valueToKey(e.value));
767 v = QVariant(f.value);
770 v = QVariant(f.value);
772 QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));
775 index = sheet->indexOf(property->propertyName());
776 if (sheet && m_propertyToGroup.contains(property)) {
781 if (type == QMetaType::QString && !property->subProperties().isEmpty()) {
782 const int fontIndex = m_propertySheet->indexOf(m_strings.m_fontProperty);
784 property->setAttribute(m_strings.m_fontAttribute, m_propertySheet->property(fontIndex));
787 m_updatingBrowser =
true;
788 property->setValue(v);
789 if (sheet && sheet->isResourceProperty(index))
790 property->setAttribute(u"defaultResource"_s, sheet->defaultResourceProperty(index));
791 m_updatingBrowser =
false;
794int PropertyEditor::toBrowserType(
const QVariant &value,
const QString &propertyName)
const
797 if (m_strings.m_alignmentProperties.contains(propertyName))
804 return value.userType();
812 QString className = QLatin1StringView(object->metaObject()->className());
813 const QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
814 if (QDesignerWidgetDataBaseItemInterface *widgetItem = db->item(db->indexOfObject(object,
true))) {
815 className = widgetItem->name();
817 if (object->isWidgetType() && className == m_strings.m_qLayoutWidget
818 &&
static_cast<QWidget*>(object)->layout()) {
819 className = QLatin1StringView(
static_cast<QWidget*>(object)->layout()->metaObject()->className());
823 if (className.startsWith(m_strings.m_designerPrefix))
824 className.remove(1, m_strings.m_designerPrefix.size() - 1);
831 if (type == qMetaTypeId<PropertySheetStringValue>())
832 type = QMetaType::QString;
833 if (type <
int(QMetaType::User))
834 return QMetaType(type).name();
840 return "QKeySequence";
845 if (type == QMetaType::UnknownType)
847 if (type == QMetaType::User)
849 const auto metaType = QMetaType(type);
850 if (metaType.isValid())
851 return metaType.name();
858 QTextStream str(&rc);
860 str <<
"The property \"" << propertyName <<
"\" of type ("
861 << (typeS ? typeS :
"unknown") <<
") is not supported yet.";
866 const QString &baseTip)
868 return PropertyEditor::tr(
"Deprecated since Qt %1: %2").arg(version, baseTip);
874 if (
const char *typeS = typeName(type))
875 result = propertyName +
" ("_L1 + QLatin1StringView(typeS) + u')';
880 const QString &className,
881 const QString &propertyName,
int type)
883 const QDesignerCustomWidgetData customData = core->pluginManager()->customWidgetData(className);
884 if (!customData.isNull()) {
885 if (QString customToolTip = customData.propertyToolTip(propertyName); !customToolTip.isEmpty())
886 return customToolTip;
888 const QString base = basePropertyToolTip(propertyName, type);
890 if (type == QtVariantPropertyManager::enumTypeId() && propertyName ==
"timeSpec"_L1)
891 return msgDeprecatedProperty(
"6.9"_L1, base);
897 QDesignerFormWindowInterface *oldFormWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
899 const bool editNewDynamicProperty = object !=
nullptr && m_object == object && !m_recentlyAddedDynamicProperty.isEmpty();
901 m_propertyManager->setObject(object);
902 QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
904 if (object !=
nullptr && formWindow ==
nullptr) {
905 formWindow = m_core->formWindowManager()->activeFormWindow();
906 if (formWindow ==
nullptr) {
907 qWarning(
"PropertyEditor::setObject(): Unable to find form window for \"%s\".",
908 qPrintable(object->objectName()));
912 FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
913 const bool idIdBasedTranslation = fwb && fwb->useIdBasedTranslations();
919 storeExpansionState();
923 updateToolBarLabel();
925 QMap<QString, QtVariantProperty *> toRemove = m_nameToProperty;
929 const QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));
933 QExtensionManager *m = m_core->extensionManager();
936 if (m_propertySheet) {
938 const int propertyCount = m_propertySheet->count();
939 for (
int i = 0; i < propertyCount; ++i) {
940 if (!m_propertySheet->isVisible(i))
943 const QString propertyName = m_propertySheet->propertyName(i);
944 if (m_propertySheet->indexOf(propertyName) != i)
946 const QString groupName = m_propertySheet->propertyGroup(i);
947 const auto rit = toRemove.constFind(propertyName);
948 if (rit != toRemove.constEnd()) {
953 if (m_propertyToGroup.value(property) == groupName
954 && (idIdBasedTranslationUnchanged || propertyType != stringTypeId)
955 && toBrowserType(m_propertySheet->property(i), propertyName) == propertyType) {
956 toRemove.remove(propertyName);
962 for (
auto itRemove = toRemove.cbegin(), end = toRemove.cend(); itRemove != end; ++itRemove) {
964 m_nameToProperty.remove(itRemove.key());
965 m_propertyToGroup.remove(property);
969 if (oldFormWindow != formWindow)
972 bool isMainContainer =
false;
974 if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(widget)) {
975 isMainContainer = (fw->mainContainer() == widget);
980 if (m_propertySheet) {
981 const QString className = WidgetFactory::classNameOf(formWindow->core(), m_object);
985 const int propertyCount = m_propertySheet->count();
986 for (
int i = 0; i < propertyCount; ++i) {
987 if (!m_propertySheet->isVisible(i))
990 const QString propertyName = m_propertySheet->propertyName(i);
991 if (m_propertySheet->indexOf(propertyName) != i)
993 const QVariant value = m_propertySheet->property(i);
995 const int type = toBrowserType(value, propertyName);
998 bool newProperty = property ==
nullptr;
1000 property = m_propertyManager->addProperty(type, propertyName);
1005 m_updatingBrowser =
true;
1006 property->setAttribute(m_strings.m_enumNamesAttribute, e.metaEnum.keys());
1007 m_updatingBrowser =
false;
1010 QList<std::pair<QString, uint>> flags;
1011 for (
const QString &name : f.metaFlags.keys()) {
1012 const uint val = f.metaFlags.keyToValue(name);
1013 flags.append({name, val});
1015 m_updatingBrowser =
true;
1018 property->setAttribute(m_strings.m_flagsAttribute, v);
1019 m_updatingBrowser =
false;
1024 if (property !=
nullptr) {
1026 || (sheet && sheet->isDefaultDynamicProperty(i));
1027 QString descriptionToolTip = dynamicProperty
1028 ? basePropertyToolTip(propertyName, type)
1029 : propertyToolTip(formWindow->core(), className, propertyName, type);
1030 if (!descriptionToolTip.isEmpty())
1031 property->setDescriptionToolTip(descriptionToolTip);
1033 case QMetaType::QPalette:
1034 setupPaletteProperty(property);
1036 case QMetaType::QKeySequence:
1042 if (type == QMetaType::QString || type == qMetaTypeId<PropertySheetStringValue>())
1043 setupStringProperty(property, isMainContainer);
1044 property->setAttribute(m_strings.m_resettableAttribute, m_propertySheet->hasReset(i));
1046 const QString groupName = m_propertySheet->propertyGroup(i);
1050 auto itPrev = m_nameToProperty.insert(propertyName, property);
1051 m_propertyToGroup[property] = groupName;
1054 if (itPrev != m_nameToProperty.begin())
1055 previous = (--itPrev).value();
1059 const auto gnit = m_nameToGroup.constFind(groupName);
1060 if (gnit != m_nameToGroup.constEnd()) {
1061 groupProperty = gnit.value();
1067 m_nameToGroup[groupName] = groupProperty;
1068 m_groups.append(groupProperty);
1069 if (dynamicProperty)
1070 m_dynamicGroup = groupProperty;
1071 if (m_currentBrowser == m_treeBrowser && item) {
1072 m_treeBrowser->setBackgroundColor(item, propertyColor(groupProperty));
1077
1078
1079
1080
1081
1082 if (lastGroup != groupProperty) {
1083 lastGroup = groupProperty;
1084 lastProperty =
nullptr;
1085 const auto subProperties = lastGroup->subProperties();
1086 if (!subProperties.isEmpty())
1087 lastProperty = subProperties.constLast();
1088 lastGroup = groupProperty;
1090 if (!m_groups.contains(groupProperty))
1091 m_groups.append(groupProperty);
1095 lastProperty = property;
1097 updateBrowserValue(property, value);
1100 if (propertyName ==
"geometry"_L1 && type == QMetaType::QRect) {
1101 const auto &subProperties = property->subProperties();
1102 for (QtProperty *subProperty : subProperties) {
1103 const QString subPropertyName = subProperty->propertyName();
1104 if (subPropertyName ==
"X"_L1 || subPropertyName ==
"Y"_L1)
1105 subProperty->setEnabled(!isMainContainer);
1110 const int typeId = value.typeId();
1111 if (typeId != qMetaTypeId<QTimeZone>())
1112 qWarning(
"%s", qPrintable(msgUnsupportedType(propertyName, type)));
1116 QMap<QString, QtVariantProperty *> groups = m_nameToGroup;
1117 for (
auto itGroup = groups.cbegin(), end = groups.cend(); itGroup != end; ++itGroup) {
1119 if (groupProperty->subProperties().isEmpty()) {
1120 if (groupProperty == m_dynamicGroup)
1121 m_dynamicGroup =
nullptr;
1122 delete groupProperty;
1123 m_nameToGroup.remove(itGroup.key());
1127 m_addDynamicAction->setEnabled(addEnabled);
1128 m_removeDynamicAction->setEnabled(
false);
1129 applyExpansionState();
1132 if (editNewDynamicProperty) {
1135 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1136 editProperty(m_recentlyAddedDynamicProperty);
1138 m_recentlyAddedDynamicProperty.clear();
1139 m_filterWidget->setEnabled(object);
1144 m_updatingBrowser =
true;
1146 m_updatingBrowser =
false;
1153 const auto topLevelItems = m_currentBrowser->topLevelItems();
1165 if (
QtBrowserItem *topLevelItem = nonFakePropertyBrowserItem(browserItem)) {
1173 QDesignerFormWindowInterface *form = m_core->formWindowManager()->activeFormWindow();
1186 if (!m_propertyToGroup.contains(property))
1189 emit resetProperty(property->propertyName());
1194 if (m_updatingBrowser)
1197 if (!m_propertySheet)
1205 if (!m_propertyToGroup.contains(property))
1209 PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(m_propertySheet->property(m_propertySheet->indexOf(property->propertyName())));
1210 const int val = value.toInt();
1211 const QString valName = varProp->attributeValue(m_strings.m_enumNamesAttribute).toStringList().at(val);
1213 e.value = e.metaEnum.parseEnum(valName, &ok);
1217 emitPropertyValueChanged(property->propertyName(), v,
true);
1221 emitPropertyValueChanged(property->propertyName(), value, enableSubPropertyHandling);
1235 return m_propertyToGroup.contains(item->property())
1236 && dynamicSheet->isDynamicProperty(m_propertySheet->indexOf(item->property()->propertyName()));
1244 const auto items = m_currentBrowser->items(property);
1245 if (items.size() == 1)
1246 browserItem = items.constFirst();
1248 if (browserItem ==
nullptr)
1250 m_currentBrowser->setFocus(Qt::OtherFocusReason);
1251 if (m_currentBrowser == m_treeBrowser) {
1260 m_removeDynamicAction->setEnabled(isDynamicProperty(item));
1267 if (isDynamicProperty(item))
1268 emit removeDynamicProperty(item
->property()->propertyName());
1273 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 QString basePropertyToolTip(const QString &propertyName, int type)
static const char * typeName(int type)
static QString propertyToolTip(const QDesignerFormEditorInterface *core, const QString &className, const QString &propertyName, int type)
static QString msgDeprecatedProperty(const QLatin1StringView version, const QString &baseTip)
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