5#include <abstractformbuilder.h>
6#include <iconloader_p.h>
7#include <formwindowbase_p.h>
8#include <designerpropertymanager.h>
10#include <QtDesigner/abstractformwindow.h>
12#include <qttreepropertybrowser_p.h>
14#include <QtWidgets/qsplitter.h>
15#include <QtCore/qcoreapplication.h>
19using namespace Qt::StringLiterals;
28 setResizeMode(Interactive);
30 const QString widthSampleString = QCoreApplication::translate(
"ItemPropertyBrowser",
"XX Icon Selected off");
31 m_width = fontMetrics().horizontalAdvance(widthSampleString);
33 m_width += fontMetrics().horizontalAdvance(u"/this/is/some/random/path"_s);
38 return QSize(m_width, 1);
48 m_iconCache(qobject_cast<FormWindowBase *>(form)->iconCache())
54 m_propertyBrowser->setFactoryForManager(
static_cast<QtVariantPropertyManager *>(m_propertyManager),
57 connect(m_editorFactory, &DesignerEditorFactory::resetProperty,
58 this, &AbstractItemEditor::resetProperty);
59 connect(m_propertyManager, &DesignerPropertyManager::valueChanged,
60 this, &AbstractItemEditor::propertyChanged);
61 connect(iconCache(), &DesignerIconCache::reloaded,
this, &AbstractItemEditor::cacheReloaded);
70 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"Selectable"),
71 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"Editable"),
72 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"DragEnabled"),
73 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"DropEnabled"),
74 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"UserCheckable"),
75 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"Enabled"),
76 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"Tristate"),
81 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"Unchecked"),
82 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"PartiallyChecked"),
83 QT_TRANSLATE_NOOP(
"AbstractItemEditor",
"Checked"),
90 for (
int i = 0; in[i]; i++)
91 out << AbstractItemEditor::tr(in[i]);
96 Qt::Alignment alignDefault)
98 for (
int i = 0; propList[i]
.name; i++) {
100 int role = propList[i]
.role;
102 if (role == Qt::TextAlignmentRole) {
104 QVariant(uint(alignDefault)));
107 if (role == Qt::ToolTipPropertyRole || role == Qt::WhatsThisPropertyRole)
108 prop->setAttribute(u"validationMode"_s, ValidationRichText);
109 else if (role == Qt::DisplayPropertyRole)
110 prop->setAttribute(u"validationMode"_s, ValidationMultiLine);
111 else if (role == Qt::StatusTipPropertyRole)
112 prop->setAttribute(u"validationMode"_s, ValidationSingleLine);
113 else if (role == ItemFlagsShadowRole)
114 prop->setAttribute(u"flagNames"_s, c2qStringList(itemFlagNames));
115 else if (role == Qt::CheckStateRole)
116 prop->setAttribute(u"enumNames"_s, c2qStringList(checkStateNames));
117 prop->setAttribute(u"resettable"_s,
true);
118 m_properties.append(prop);
119 m_rootProperties.append(prop);
120 m_propertyToRole.insert(prop, role);
127 QDesignerFormWindowInterface *formWindow = QDesignerFormWindowInterface::findFormWindow(object);
128 FormWindowBase *fwb = qobject_cast<FormWindowBase *>(formWindow);
134 Qt::Alignment alignDefault)
136 setupProperties(propList, alignDefault);
149 if ((role = m_propertyToRole.value(prop, -1)) == -1)
153 if ((role == ItemFlagsShadowRole && prop->value().toInt() == defaultItemFlags())
154 || (role == Qt::DecorationPropertyRole && !qvariant_cast<PropertySheetIconValue>(prop->value()).mask())
155 || (role == Qt::FontRole && !qvariant_cast<QFont>(prop->value()).resolveMask())) {
157 setItemData(role, QVariant());
160 setItemData(role, prop->value());
164 case Qt::DecorationPropertyRole:
165 setItemData(Qt::DecorationRole, QVariant::fromValue(iconCache()->icon(qvariant_cast<PropertySheetIconValue>(prop->value()))));
167 case Qt::DisplayPropertyRole:
168 setItemData(Qt::EditRole, QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(prop->value()).value()));
170 case Qt::ToolTipPropertyRole:
171 setItemData(Qt::ToolTipRole, QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(prop->value()).value()));
173 case Qt::StatusTipPropertyRole:
174 setItemData(Qt::StatusTipRole, QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(prop->value()).value()));
176 case Qt::WhatsThisPropertyRole:
177 setItemData(Qt::WhatsThisRole, QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(prop->value()).value()));
183 prop->setValue(getItemData(role));
200 int role = m_propertyToRole.value(prop);
202 prop->setValue(QVariant::fromValue(defaultItemFlags()));
204 prop->setValue(QVariant(QMetaType(prop
->valueType()),
nullptr));
207 setItemData(role, QVariant());
208 if (role == Qt::DecorationPropertyRole)
209 setItemData(Qt::DecorationRole, QVariant::fromValue(QIcon()));
210 if (role == Qt::DisplayPropertyRole)
211 setItemData(Qt::EditRole, QVariant::fromValue(QString()));
212 if (role == Qt::ToolTipPropertyRole)
213 setItemData(Qt::ToolTipRole, QVariant::fromValue(QString()));
214 if (role == Qt::StatusTipPropertyRole)
215 setItemData(Qt::StatusTipRole, QVariant::fromValue(QString()));
216 if (role == Qt::WhatsThisPropertyRole)
217 setItemData(Qt::WhatsThisRole, QVariant::fromValue(QString()));
229 for (QtVariantProperty *prop : std::as_const(m_properties)) {
230 int role = m_propertyToRole.value(prop);
231 QVariant val = getItemData(role);
233 bool modified =
false;
234 if (!val.isValid()) {
235 if (role == ItemFlagsShadowRole)
236 val = QVariant::fromValue(defaultItemFlags());
238 val = QVariant(QMetaType(prop->value().userType()),
nullptr);
240 modified = role != Qt::TextAlignmentRole
241 || val.toUInt() != DesignerPropertyManager::alignDefault(prop);
243 prop->setModified(modified);
248 for (QtVariantProperty *prop : std::as_const(m_rootProperties))
249 m_propertyBrowser->addProperty(prop);
256 m_propertySplitter =
new QSplitter;
271 injectPropertyBrowser(
this, ui.widget);
272 connect(ui.showPropertiesButton, &QAbstractButton::clicked,
273 this, &ItemListEditor::togglePropertyBrowser);
275 connect(ui.newListItemButton, &QAbstractButton::clicked,
276 this, &ItemListEditor::newListItemButtonClicked);
277 connect(ui.deleteListItemButton, &QAbstractButton::clicked,
278 this, &ItemListEditor::deleteListItemButtonClicked);
279 connect(ui.moveListItemUpButton, &QAbstractButton::clicked,
280 this, &ItemListEditor::moveListItemUpButtonClicked);
281 connect(ui.moveListItemDownButton, &QAbstractButton::clicked,
282 this, &ItemListEditor::moveListItemDownButtonClicked);
283 connect(ui.listWidget, &QListWidget::currentRowChanged,
284 this, &ItemListEditor::listWidgetCurrentRowChanged);
285 connect(ui.listWidget, &QListWidget::itemChanged,
286 this, &ItemListEditor::listWidgetItemChanged);
288 setPropertyBrowserVisible(
false);
290 QIcon upIcon = createIconSet(
"up.png"_L1);
291 QIcon downIcon = createIconSet(
"down.png"_L1);
292 QIcon minusIcon = createIconSet(
"minus.png"_L1);
293 QIcon plusIcon = createIconSet(
"plus.png"_L1);
294 ui.moveListItemUpButton->setIcon(upIcon);
295 ui.moveListItemDownButton->setIcon(downIcon);
296 ui.newListItemButton->setIcon(plusIcon);
297 ui.deleteListItemButton->setIcon(minusIcon);
299 connect(iconCache(), &DesignerIconCache::reloaded,
this, &AbstractItemEditor::cacheReloaded);
304 Qt::Alignment alignDefault)
306 AbstractItemEditor::setupEditor(object, propList, alignDefault);
308 if (ui.listWidget->count() > 0)
309 ui.listWidget->setCurrentRow(0);
317 ui.listWidget->setCurrentRow(idx);
323 int row = ui.listWidget->currentRow() + 1;
325 QListWidgetItem *item =
new QListWidgetItem(m_newItemText);
326 item->setData(Qt::DisplayPropertyRole, QVariant::fromValue(PropertySheetStringValue(m_newItemText)));
327 if (m_alignDefault != 0)
328 item->setTextAlignment(Qt::Alignment(m_alignDefault));
329 item->setFlags(item->flags() | Qt::ItemIsEditable);
330 if (row < ui.listWidget->count())
331 ui.listWidget->insertItem(row, item);
333 ui.listWidget->addItem(item);
334 emit itemInserted(row);
336 ui.listWidget->setCurrentItem(item);
337 ui.listWidget->editItem(item);
342 int row = ui.listWidget->currentRow();
345 delete ui.listWidget->takeItem(row);
346 emit itemDeleted(row);
349 if (row == ui.listWidget->count())
354 ui.listWidget->setCurrentRow(row);
359 int row = ui.listWidget->currentRow();
363 ui.listWidget->insertItem(row - 1, ui.listWidget->takeItem(row));
364 ui.listWidget->setCurrentRow(row - 1);
365 emit itemMovedUp(row);
370 int row = ui.listWidget->currentRow();
371 if (row == -1 || row == ui.listWidget->count() - 1)
374 ui.listWidget->insertItem(row + 1, ui.listWidget->takeItem(row));
375 ui.listWidget->setCurrentRow(row + 1);
376 emit itemMovedDown(row);
383 emit indexChanged(ui.listWidget->currentRow());
392 val.setValue(item->text());
394 item->setData(Qt::DisplayPropertyRole, QVariant::fromValue(val));
398 emit itemChanged(ui.listWidget->currentRow(), Qt::DisplayPropertyRole,
399 QVariant::fromValue(val));
410 ui.showPropertiesButton->setText(v ? tr(
"Properties &>>") : tr(
"Properties &<<"));
416 QListWidgetItem *item = ui.listWidget->currentItem();
417 bool reLayout =
false;
418 if ((role == Qt::EditRole
419 && (v.toString().count(u'\n') != item->data(role).toString().count(u'\n')))
420 || role == Qt::FontRole) {
423 QVariant newValue = v;
424 if (role == Qt::FontRole && newValue.metaType().id() == QMetaType::QFont) {
425 QFont oldFont = ui.listWidget->font();
426 QFont newFont = qvariant_cast<QFont>(newValue).resolve(oldFont);
427 newValue = QVariant::fromValue(newFont);
428 item->setData(role, QVariant());
430 item->setData(role, newValue);
432 ui.listWidget->doItemsLayout();
433 emit itemChanged(ui.listWidget->currentRow(), role, newValue);
438 return ui.listWidget->currentItem()->data(role);
443 static const int flags = QListWidgetItem().flags();
449 reloadIconResources(iconCache(), ui.listWidget);
454 bool currentItemEnabled =
false;
456 bool moveRowUpEnabled =
false;
457 bool moveRowDownEnabled =
false;
459 QListWidgetItem *item = ui.listWidget->currentItem();
461 currentItemEnabled =
true;
462 int currentRow = ui.listWidget->currentRow();
464 moveRowUpEnabled =
true;
465 if (currentRow < ui.listWidget->count() - 1)
466 moveRowDownEnabled =
true;
469 ui.moveListItemUpButton->setEnabled(moveRowUpEnabled);
470 ui.moveListItemDownButton->setEnabled(moveRowDownEnabled);
471 ui.deleteListItemButton->setEnabled(currentItemEnabled);
481 return m_alignDefault;
486 m_alignDefault = newAlignDefault;
void unsetFactoryForManager(QtAbstractPropertyManager *manager)
Removes the association between the given manager and the factory bound to it, automatically calling ...
void clear()
Removes all the properties from the editor, but does not delete them since they can still be used in ...
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.
The QtTreePropertyBrowser class provides QTreeWidget based property browser.
void setSplitterPosition(int position)
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 valueType() const
Returns the type of this property's value.
QtTreePropertyBrowser * m_propertyBrowser
DesignerPropertyManager * m_propertyManager
DesignerIconCache * m_iconCache
DesignerEditorFactory * m_editorFactory
QSplitter * m_propertySplitter
void setupProperties(const PropertyDefinition *propList, Qt::Alignment alignDefault=Qt::AlignLeading|Qt::AlignVCenter)
BoolBlocker(bool &b) noexcept
void setSpacing(int spacing)
void setFormWindowBase(FormWindowBase *fwb)
bool resetFontSubProperty(QtProperty *property)
void reloadResourceProperties()
bool resetIconSubProperty(QtProperty *subProperty)
static QString alignDefaultAttribute()
bool resetTextAlignmentProperty(QtProperty *property)
int defaultItemFlags() const override
QVariant getItemData(int role) const override
uint alignDefault() const
void setCurrentIndex(int idx)
void setAlignDefault(uint newAlignDefault)
QSize sizeHint() const override
Auxiliary methods to store/retrieve settings.
static const char *const checkStateNames[]
static QStringList c2qStringList(const char *const in[])
static const char *const itemFlagNames[]