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));
763 v = e.metaEnum.keys().indexOf(e.metaEnum.valueToKey(e.value));
766 v = QVariant(f.value);
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.";
865 const QString &baseTip)
867 return PropertyEditor::tr(
"Deprecated since Qt %1: %2").arg(version, baseTip);
873 if (
const char *typeS = typeName(type))
874 result = propertyName +
" ("_L1 + QLatin1StringView(typeS) + u')';
879 const QString &className,
880 const QString &propertyName,
int type)
882 const QDesignerCustomWidgetData customData = core->pluginManager()->customWidgetData(className);
883 if (!customData.isNull()) {
884 if (QString customToolTip = customData.propertyToolTip(propertyName); !customToolTip.isEmpty())
885 return customToolTip;
887 const QString base = basePropertyToolTip(propertyName, type);
889 if (type == QtVariantPropertyManager::enumTypeId() && propertyName ==
"timeSpec"_L1)
890 return msgDeprecatedProperty(
"6.9"_L1, base);
896 QDesignerFormWindowInterface *oldFormWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
898 const bool editNewDynamicProperty = object !=
nullptr && m_object == object && !m_recentlyAddedDynamicProperty.isEmpty();
900 m_propertyManager->setObject(object);
901 QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(m_object);
903 if (object !=
nullptr && formWindow ==
nullptr) {
904 formWindow = m_core->formWindowManager()->activeFormWindow();
905 if (formWindow ==
nullptr) {
906 qWarning(
"PropertyEditor::setObject(): Unable to find form window for \"%s\".",
907 qPrintable(object->objectName()));
911 FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
912 const bool idIdBasedTranslation = fwb && fwb->useIdBasedTranslations();
918 storeExpansionState();
922 updateToolBarLabel();
924 QMap<QString, QtVariantProperty *> toRemove = m_nameToProperty;
927 qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);
928 const QDesignerPropertySheet *sheet = qobject_cast<QDesignerPropertySheet*>(m_core->extensionManager()->extension(m_object, Q_TYPEID(QDesignerPropertySheetExtension)));
932 QExtensionManager *m = m_core->extensionManager();
934 m_propertySheet = qobject_cast<QDesignerPropertySheetExtension*>(m->extension(object, Q_TYPEID(QDesignerPropertySheetExtension)));
935 if (m_propertySheet) {
937 const int propertyCount = m_propertySheet->count();
938 for (
int i = 0; i < propertyCount; ++i) {
939 if (!m_propertySheet->isVisible(i))
942 const QString propertyName = m_propertySheet->propertyName(i);
943 if (m_propertySheet->indexOf(propertyName) != i)
945 const QString groupName = m_propertySheet->propertyGroup(i);
946 const auto rit = toRemove.constFind(propertyName);
947 if (rit != toRemove.constEnd()) {
952 if (m_propertyToGroup.value(property) == groupName
953 && (idIdBasedTranslationUnchanged || propertyType != stringTypeId)
954 && toBrowserType(m_propertySheet->property(i), propertyName) == propertyType) {
955 toRemove.remove(propertyName);
961 for (
auto itRemove = toRemove.cbegin(), end = toRemove.cend(); itRemove != end; ++itRemove) {
963 m_nameToProperty.remove(itRemove.key());
964 m_propertyToGroup.remove(property);
968 if (oldFormWindow != formWindow)
971 bool isMainContainer =
false;
973 if (QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(widget)) {
974 isMainContainer = (fw->mainContainer() == widget);
979 if (m_propertySheet) {
980 const QString className = WidgetFactory::classNameOf(formWindow->core(), m_object);
984 const int propertyCount = m_propertySheet->count();
985 for (
int i = 0; i < propertyCount; ++i) {
986 if (!m_propertySheet->isVisible(i))
989 const QString propertyName = m_propertySheet->propertyName(i);
990 if (m_propertySheet->indexOf(propertyName) != i)
992 const QVariant value = m_propertySheet->property(i);
994 const int type = toBrowserType(value, propertyName);
997 bool newProperty = property ==
nullptr;
999 property = m_propertyManager->addProperty(type, propertyName);
1004 m_updatingBrowser =
true;
1005 property->setAttribute(m_strings.m_enumNamesAttribute, e.metaEnum.keys());
1006 m_updatingBrowser =
false;
1009 QList<std::pair<QString, uint>> flags;
1010 for (
const QString &name : f.metaFlags.keys()) {
1011 const uint val = f.metaFlags.keyToValue(name);
1012 flags.append({name, val});
1014 m_updatingBrowser =
true;
1017 property->setAttribute(m_strings.m_flagsAttribute, v);
1018 m_updatingBrowser =
false;
1023 if (property !=
nullptr) {
1025 || (sheet && sheet->isDefaultDynamicProperty(i));
1026 QString descriptionToolTip = dynamicProperty
1027 ? basePropertyToolTip(propertyName, type)
1028 : propertyToolTip(formWindow->core(), className, propertyName, type);
1029 if (!descriptionToolTip.isEmpty())
1030 property->setDescriptionToolTip(descriptionToolTip);
1032 case QMetaType::QPalette:
1033 setupPaletteProperty(property);
1035 case QMetaType::QKeySequence:
1041 if (type == QMetaType::QString || type == qMetaTypeId<PropertySheetStringValue>())
1042 setupStringProperty(property, isMainContainer);
1043 property->setAttribute(m_strings.m_resettableAttribute, m_propertySheet->hasReset(i));
1045 const QString groupName = m_propertySheet->propertyGroup(i);
1049 auto itPrev = m_nameToProperty.insert(propertyName, property);
1050 m_propertyToGroup[property] = groupName;
1053 if (itPrev != m_nameToProperty.begin())
1054 previous = (--itPrev).value();
1058 const auto gnit = m_nameToGroup.constFind(groupName);
1059 if (gnit != m_nameToGroup.constEnd()) {
1060 groupProperty = gnit.value();
1066 m_nameToGroup[groupName] = groupProperty;
1067 m_groups.append(groupProperty);
1068 if (dynamicProperty)
1069 m_dynamicGroup = groupProperty;
1070 if (m_currentBrowser == m_treeBrowser && item) {
1071 m_treeBrowser->setBackgroundColor(item, propertyColor(groupProperty));
1076
1077
1078
1079
1080
1081 if (lastGroup != groupProperty) {
1082 lastGroup = groupProperty;
1083 lastProperty =
nullptr;
1084 const auto subProperties = lastGroup->subProperties();
1085 if (!subProperties.isEmpty())
1086 lastProperty = subProperties.constLast();
1087 lastGroup = groupProperty;
1089 if (!m_groups.contains(groupProperty))
1090 m_groups.append(groupProperty);
1094 lastProperty = property;
1096 updateBrowserValue(property, value);
1099 if (propertyName ==
"geometry"_L1 && type == QMetaType::QRect) {
1100 const auto &subProperties = property->subProperties();
1101 for (QtProperty *subProperty : subProperties) {
1102 const QString subPropertyName = subProperty->propertyName();
1103 if (subPropertyName ==
"X"_L1 || subPropertyName ==
"Y"_L1)
1104 subProperty->setEnabled(!isMainContainer);
1109 const int typeId = value.typeId();
1110 if (typeId != qMetaTypeId<QTimeZone>())
1111 qWarning(
"%s", qPrintable(msgUnsupportedType(propertyName, type)));
1115 QMap<QString, QtVariantProperty *> groups = m_nameToGroup;
1116 for (
auto itGroup = groups.cbegin(), end = groups.cend(); itGroup != end; ++itGroup) {
1118 if (groupProperty->subProperties().isEmpty()) {
1119 if (groupProperty == m_dynamicGroup)
1120 m_dynamicGroup =
nullptr;
1121 delete groupProperty;
1122 m_nameToGroup.remove(itGroup.key());
1126 m_addDynamicAction->setEnabled(addEnabled);
1127 m_removeDynamicAction->setEnabled(
false);
1128 applyExpansionState();
1131 if (editNewDynamicProperty) {
1134 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
1135 editProperty(m_recentlyAddedDynamicProperty);
1137 m_recentlyAddedDynamicProperty.clear();
1138 m_filterWidget->setEnabled(object);
1143 m_updatingBrowser =
true;
1145 m_updatingBrowser =
false;
1152 const auto topLevelItems = m_currentBrowser->topLevelItems();
1164 if (
QtBrowserItem *topLevelItem = nonFakePropertyBrowserItem(browserItem)) {
1172 QDesignerFormWindowInterface *form = m_core->formWindowManager()->activeFormWindow();
1185 if (!m_propertyToGroup.contains(property))
1188 emit resetProperty(property->propertyName());
1193 if (m_updatingBrowser)
1196 if (!m_propertySheet)
1204 if (!m_propertyToGroup.contains(property))
1208 PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(m_propertySheet->property(m_propertySheet->indexOf(property->propertyName())));
1209 const int val = value.toInt();
1210 const QString valName = varProp->attributeValue(m_strings.m_enumNamesAttribute).toStringList().at(val);
1212 e.value = e.metaEnum.parseEnum(valName, &ok);
1216 emitPropertyValueChanged(property->propertyName(), v,
true);
1220 emitPropertyValueChanged(property->propertyName(), value, enableSubPropertyHandling);
1229 qt_extension<QDesignerDynamicPropertySheetExtension*>(m_core->extensionManager(), m_object);
1234 return m_propertyToGroup.contains(item->property())
1235 && dynamicSheet->isDynamicProperty(m_propertySheet->indexOf(item->property()->propertyName()));
1243 const auto items = m_currentBrowser->items(property);
1244 if (items.size() == 1)
1245 browserItem = items.constFirst();
1247 if (browserItem ==
nullptr)
1249 m_currentBrowser->setFocus(Qt::OtherFocusReason);
1250 if (m_currentBrowser == m_treeBrowser) {
1259 m_removeDynamicAction->setEnabled(isDynamicProperty(item));
1266 if (isDynamicProperty(item))
1267 emit removeDynamicProperty(item
->property()->propertyName());
1272 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