1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "abstractintegration.h"
30#include "abstractformwindow.h"
31#include "abstractformwindowmanager.h"
32#include "abstractformwindowcursor.h"
33#include "abstractformeditor.h"
34#include "abstractactioneditor.h"
35#include "abstractwidgetbox.h"
36#include "abstractresourcebrowser.h"
37#include "propertysheet.h"
38#include "abstractpropertyeditor.h"
39#include "qextensionmanager.h"
40
41#include <qtresourcemodel_p.h>
42
43#include <qdesigner_propertycommand_p.h>
44#include <qdesigner_propertyeditor_p.h>
45#include <qdesigner_objectinspector_p.h>
46#include <widgetdatabase_p.h>
47#include <pluginmanager_p.h>
48#include <widgetfactory_p.h>
49#include <qdesigner_widgetbox_p.h>
50#include <qtgradientmanager.h>
51#include <qtgradientutils.h>
52#include <qtresourcemodel_p.h>
53
54#include <QtCore/qvariant.h>
55#include <QtCore/qfile.h>
56#include <QtCore/qdir.h>
57
58#include <QtCore/qdebug.h>
59
60QT_BEGIN_NAMESPACE
61
62/*!
63 \class QDesignerIntegrationInterface
64
65 \brief The QDesignerIntegrationInterface glues together parts of \QD
66 and allows for overwriting functionality for IDE integration.
67
68 \internal
69
70 \inmodule QtDesigner
71
72 \sa QDesignerFormEditorInterface
73*/
74
75/*!
76 \enum QDesignerIntegrationInterface::ResourceFileWatcherBehaviour
77
78 \internal
79
80 This enum describes if and how resource files are watched.
81
82 \value NoResourceFileWatcher Do not watch for changes
83 \value ReloadResourceFileSilently Reload files silently.
84 \value PromptToReloadResourceFile Prompt the user to reload.
85*/
86
87/*!
88 \enum QDesignerIntegrationInterface::FeatureFlag
89
90 \internal
91
92 This enum describes the features that are available and can be
93 controlled by the integration.
94
95 \value ResourceEditorFeature The resource editor is enabled.
96 \value SlotNavigationFeature Provide context menu entry offering 'Go to slot'.
97 \value DefaultWidgetActionFeature Trigger the preferred action of
98 QDesignerTaskMenuExtension when widget is activated.
99 \value DefaultFeature Default for \QD
100
101 \sa hasFeature(), features()
102*/
103
104/*!
105 \property QDesignerIntegrationInterface::headerSuffix
106
107 Returns the suffix of the header of promoted widgets.
108*/
109
110/*!
111 \property QDesignerIntegrationInterface::headerLowercase
112
113 Returns whether headers of promoted widgets should be lower-cased (as the user types the class name).
114*/
115
116/*!
117 \fn virtual void QDesignerIntegrationInterface::updateSelection()
118
119 \brief Sets the selected widget of the form window in various components.
120
121 \internal
122
123 In IDE integrations, the method can be overwritten to move the selection handles
124 of the form's main window, should it be selected.
125*/
126
127/*!
128 \fn virtual QWidget *QDesignerIntegrationInterface::containerWindow(QWidget *widget) const
129
130 \brief Returns the outer window containing a form for applying main container geometries.
131
132 \internal
133
134 Should be implemented by IDE integrations.
135*/
136
137/*!
138 \fn virtual QDesignerResourceBrowserInterface *QDesignerIntegrationInterface::createResourceBrowser(QWidget *parent = 0)
139
140 \brief Creates a resource browser depending on IDE integration.
141
142 \internal
143
144 \note Language integration takes precedence.
145*/
146
147/*!
148 \fn virtual void QDesignerIntegrationInterface::updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling)
149
150 \brief Triggered by the property editor to update a property value.
151
152 \internal
153
154 If a different property editor is used, it should invoke this function.
155*/
156
157/*!
158 \fn virtual void QDesignerIntegrationInterface::updateProperty(const QString &name, const QVariant &value)
159
160 \brief Triggered by the property editor to update a property value without subproperty handling.
161
162 \internal
163
164 If a different property editor is used, it should invoke this function.
165*/
166
167/*!
168 \fn virtual void QDesignerIntegrationInterface::resetProperty(const QString &name)
169
170 \brief Triggered by the property editor to reset a property value.
171
172 \internal
173
174 If a different property editor is used, it should invoke this function.
175*/
176
177/*!
178 \fn virtual void QDesignerIntegrationInterface::addDynamicProperty(const QString &name, const QVariant &value)
179
180 \brief Triggered by the property editor to add a dynamic property value.
181
182 \internal
183
184 If a different property editor is used, it should invoke this function.
185*/
186
187/*!
188 \fn virtual void QDesignerIntegrationInterface::removeDynamicProperty(const QString &name)
189
190 \brief Triggered by the property editor to remove a dynamic property.
191
192 \internal
193
194 If a different property editor is used, it should invoke this function.
195*/
196
197/*!
198 \fn virtual void QDesignerIntegrationInterface::updateActiveFormWindow(QDesignerFormWindowInterface *formWindow)
199
200 \brief Sets up the active form window.
201
202 \internal
203*/
204
205/*!
206 \fn virtual void QDesignerIntegrationInterface::setupFormWindow(QDesignerFormWindowInterface *formWindow)
207
208 \brief Sets up the new form window.
209
210 \internal
211*/
212
213/*!
214 \fn virtual void QDesignerIntegrationInterface::updateCustomWidgetPlugins()
215
216 \brief Triggers a reload of the custom widget plugins.
217
218 \internal
219*/
220
221class QDesignerIntegrationInterfacePrivate
222{
223public:
224 QDesignerIntegrationInterfacePrivate(QDesignerFormEditorInterface *core) :
225 m_core(core) {}
226
227 QDesignerFormEditorInterface *m_core;
228};
229
230QDesignerIntegrationInterface::QDesignerIntegrationInterface(QDesignerFormEditorInterface *core, QObject *parent)
231 : QObject(parent), d(new QDesignerIntegrationInterfacePrivate(core))
232{
233 core->setIntegration(this);
234}
235
236QDesignerIntegrationInterface::~QDesignerIntegrationInterface() = default;
237
238QDesignerFormEditorInterface *QDesignerIntegrationInterface::core() const
239{
240 return d->m_core;
241}
242
243bool QDesignerIntegrationInterface::hasFeature(Feature f) const
244{
245 return (features() & f) != 0;
246}
247
248void QDesignerIntegrationInterface::emitObjectNameChanged(QDesignerFormWindowInterface *formWindow, QObject *object, const QString &newName, const QString &oldName)
249{
250 emit objectNameChanged(formWindow, object, newName, oldName);
251}
252
253void QDesignerIntegrationInterface::emitNavigateToSlot(const QString &objectName,
254 const QString &signalSignature,
255 const QStringList &parameterNames)
256{
257 emit navigateToSlot(objectName, signalSignature, parameterNames);
258}
259
260void QDesignerIntegrationInterface::emitNavigateToSlot(const QString &slotSignature)
261{
262 emit navigateToSlot(slotSignature);
263}
264
265void QDesignerIntegrationInterface::emitHelpRequested(const QString &manual, const QString &document)
266{
267 emit helpRequested(manual, document);
268}
269
270/*!
271 \class QDesignerIntegration
272
273 \brief The QDesignerIntegration class is \QD's implementation of
274 QDesignerIntegrationInterface.
275
276 \internal
277
278 \inmodule QtDesigner
279
280 IDE integrations should register classes derived from QDesignerIntegration
281 with QDesignerFormEditorInterface.
282*/
283
284namespace qdesigner_internal {
285
286class QDesignerIntegrationPrivate {
287public:
288 explicit QDesignerIntegrationPrivate(QDesignerIntegration *qq);
289
290 QWidget *containerWindow(QWidget *widget) const;
291
292 // Load plugins into widget database and factory.
293 static void initializePlugins(QDesignerFormEditorInterface *formEditor);
294
295 QString contextHelpId() const;
296
297 void updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling);
298 void resetProperty(const QString &name);
299 void addDynamicProperty(const QString &name, const QVariant &value);
300 void removeDynamicProperty(const QString &name);
301
302 void setupFormWindow(QDesignerFormWindowInterface *formWindow);
303 void updateSelection();
304 void updateCustomWidgetPlugins();
305
306 void updatePropertyPrivate(const QString &name, const QVariant &value);
307
308 void initialize();
309 void getSelection(qdesigner_internal::Selection &s);
310 QObject *propertyEditorObject();
311
312 QDesignerIntegration *q;
313 QString headerSuffix;
314 bool headerLowercase;
315 QDesignerIntegrationInterface::Feature m_features;
316 QDesignerIntegrationInterface::ResourceFileWatcherBehaviour m_resourceFileWatcherBehaviour;
317 QString m_gradientsPath;
318 QtGradientManager *m_gradientManager;
319};
320
321QDesignerIntegrationPrivate::QDesignerIntegrationPrivate(QDesignerIntegration *qq) :
322 q(qq),
323 headerSuffix(QStringLiteral(".h")),
324 headerLowercase(true),
325 m_features(QDesignerIntegrationInterface::DefaultFeature),
326 m_resourceFileWatcherBehaviour(QDesignerIntegrationInterface::PromptToReloadResourceFile),
327 m_gradientManager(nullptr)
328{
329}
330
331void QDesignerIntegrationPrivate::initialize()
332{
333 //
334 // integrate the `Form Editor component'
335 //
336
337 // Extensions
338 QDesignerFormEditorInterface *core = q->core();
339 if (QDesignerPropertyEditor *designerPropertyEditor= qobject_cast<QDesignerPropertyEditor *>(object: core->propertyEditor())) {
340 QObject::connect(sender: designerPropertyEditor, signal: &QDesignerPropertyEditor::propertyValueChanged,
341 receiver: q, slot: QOverload<const QString &, const QVariant &, bool>::of(ptr: &QDesignerIntegration::updateProperty));
342 QObject::connect(sender: designerPropertyEditor, signal: &QDesignerPropertyEditor::resetProperty,
343 receiver: q, slot: &QDesignerIntegration::resetProperty);
344 QObject::connect(sender: designerPropertyEditor, signal: &QDesignerPropertyEditor::addDynamicProperty,
345 receiver: q, slot: &QDesignerIntegration::addDynamicProperty);
346 QObject::connect(sender: designerPropertyEditor, signal: &QDesignerPropertyEditor::removeDynamicProperty,
347 receiver: q, slot: &QDesignerIntegration::removeDynamicProperty);
348 } else {
349 QObject::connect(sender: core->propertyEditor(), SIGNAL(propertyChanged(QString,QVariant)),
350 receiver: q, SLOT(updatePropertyPrivate(QString,QVariant))); // ### fixme: VS Integration leftover?
351 }
352
353 QObject::connect(sender: core->formWindowManager(), signal: &QDesignerFormWindowManagerInterface::formWindowAdded,
354 receiver: q, slot: &QDesignerIntegrationInterface::setupFormWindow);
355
356 QObject::connect(sender: core->formWindowManager(), signal: &QDesignerFormWindowManagerInterface::activeFormWindowChanged,
357 receiver: q, slot: &QDesignerIntegrationInterface::updateActiveFormWindow);
358
359 m_gradientManager = new QtGradientManager(q);
360 core->setGradientManager(m_gradientManager);
361
362 QString designerFolder = QDir::homePath();
363 designerFolder += QDir::separator();
364 designerFolder += QStringLiteral(".designer");
365 m_gradientsPath = designerFolder;
366 m_gradientsPath += QDir::separator();
367 m_gradientsPath += QStringLiteral("gradients.xml");
368
369 QFile f(m_gradientsPath);
370 if (f.open(flags: QIODevice::ReadOnly)) {
371 QtGradientUtils::restoreState(manager: m_gradientManager, state: QString::fromLatin1(str: f.readAll()));
372 f.close();
373 } else {
374 QFile defaultGradients(QStringLiteral(":/qt-project.org/designer/defaultgradients.xml"));
375 if (defaultGradients.open(flags: QIODevice::ReadOnly)) {
376 QtGradientUtils::restoreState(manager: m_gradientManager, state: QString::fromLatin1(str: defaultGradients.readAll()));
377 defaultGradients.close();
378 }
379 }
380
381 if (WidgetDataBase *widgetDataBase = qobject_cast<WidgetDataBase*>(object: core->widgetDataBase()))
382 widgetDataBase->grabStandardWidgetBoxIcons();
383}
384
385void QDesignerIntegrationPrivate::updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling)
386{
387 QDesignerFormWindowInterface *formWindow = q->core()->formWindowManager()->activeFormWindow();
388 if (!formWindow)
389 return;
390
391 Selection selection;
392 getSelection(s&: selection);
393 if (selection.empty())
394 return;
395
396 SetPropertyCommand *cmd = new SetPropertyCommand(formWindow);
397 // find a reference object to compare to and to find the right group
398 if (cmd->init(list: selection.selection(), propertyName: name, newValue: value, referenceObject: propertyEditorObject(), enableSubPropertyHandling)) {
399 formWindow->commandHistory()->push(cmd);
400 } else {
401 delete cmd;
402 qDebug() << "Unable to set property " << name << '.';
403 }
404}
405
406void QDesignerIntegrationPrivate::resetProperty(const QString &name)
407{
408 QDesignerFormWindowInterface *formWindow = q->core()->formWindowManager()->activeFormWindow();
409 if (!formWindow)
410 return;
411
412 Selection selection;
413 getSelection(s&: selection);
414 if (selection.empty())
415 return;
416
417 ResetPropertyCommand *cmd = new ResetPropertyCommand(formWindow);
418 // find a reference object to find the right group
419 if (cmd->init(list: selection.selection(), propertyName: name, referenceObject: propertyEditorObject())) {
420 formWindow->commandHistory()->push(cmd);
421 } else {
422 delete cmd;
423 qDebug() << "** WARNING Unable to reset property " << name << '.';
424 }
425}
426
427void QDesignerIntegrationPrivate::addDynamicProperty(const QString &name, const QVariant &value)
428{
429 QDesignerFormWindowInterface *formWindow = q->core()->formWindowManager()->activeFormWindow();
430 if (!formWindow)
431 return;
432
433 Selection selection;
434 getSelection(s&: selection);
435 if (selection.empty())
436 return;
437
438 AddDynamicPropertyCommand *cmd = new AddDynamicPropertyCommand(formWindow);
439 if (cmd->init(selection: selection.selection(), current: propertyEditorObject(), propertyName: name, value)) {
440 formWindow->commandHistory()->push(cmd);
441 } else {
442 delete cmd;
443 qDebug() << "** WARNING Unable to add dynamic property " << name << '.';
444 }
445}
446
447void QDesignerIntegrationPrivate::removeDynamicProperty(const QString &name)
448{
449 QDesignerFormWindowInterface *formWindow = q->core()->formWindowManager()->activeFormWindow();
450 if (!formWindow)
451 return;
452
453 Selection selection;
454 getSelection(s&: selection);
455 if (selection.empty())
456 return;
457
458 RemoveDynamicPropertyCommand *cmd = new RemoveDynamicPropertyCommand(formWindow);
459 if (cmd->init(selection: selection.selection(), current: propertyEditorObject(), propertyName: name)) {
460 formWindow->commandHistory()->push(cmd);
461 } else {
462 delete cmd;
463 qDebug() << "** WARNING Unable to remove dynamic property " << name << '.';
464 }
465
466}
467
468void QDesignerIntegrationPrivate::setupFormWindow(QDesignerFormWindowInterface *formWindow)
469{
470 QObject::connect(sender: formWindow, signal: &QDesignerFormWindowInterface::selectionChanged,
471 receiver: q, slot: &QDesignerIntegrationInterface::updateSelection);
472}
473
474void QDesignerIntegrationPrivate::updateSelection()
475{
476 QDesignerFormEditorInterface *core = q->core();
477 QDesignerFormWindowInterface *formWindow = core->formWindowManager()->activeFormWindow();
478 QWidget *selection = nullptr;
479
480 if (formWindow) {
481 selection = formWindow->cursor()->current();
482 }
483
484 if (QDesignerActionEditorInterface *actionEditor = core->actionEditor())
485 actionEditor->setFormWindow(formWindow);
486
487 if (QDesignerPropertyEditorInterface *propertyEditor = core->propertyEditor())
488 propertyEditor->setObject(selection);
489
490 if (QDesignerObjectInspectorInterface *objectInspector = core->objectInspector())
491 objectInspector->setFormWindow(formWindow);
492
493}
494
495QWidget *QDesignerIntegrationPrivate::containerWindow(QWidget *widget) const
496{
497 // Find the parent window to apply a geometry to.
498 while (widget) {
499 if (widget->isWindow())
500 break;
501 if (!qstrcmp(str1: widget->metaObject()->className(), str2: "QMdiSubWindow"))
502 break;
503
504 widget = widget->parentWidget();
505 }
506
507 return widget;
508}
509
510void QDesignerIntegrationPrivate::getSelection(Selection &s)
511{
512 QDesignerFormEditorInterface *core = q->core();
513 // Get multiselection from object inspector
514 if (QDesignerObjectInspector *designerObjectInspector = qobject_cast<QDesignerObjectInspector *>(object: core->objectInspector())) {
515 designerObjectInspector->getSelection(s);
516 // Action editor puts actions that are not on the form yet
517 // into the property editor only.
518 if (s.empty())
519 if (QObject *object = core->propertyEditor()->object())
520 s.objects.push_back(t: object);
521
522 } else {
523 // Just in case someone plugs in an old-style object inspector: Emulate selection
524 s.clear();
525 QDesignerFormWindowInterface *formWindow = core->formWindowManager()->activeFormWindow();
526 if (!formWindow)
527 return;
528
529 QObject *object = core->propertyEditor()->object();
530 if (object->isWidgetType()) {
531 QWidget *widget = static_cast<QWidget*>(object);
532 QDesignerFormWindowCursorInterface *cursor = formWindow->cursor();
533 if (cursor->isWidgetSelected(widget)) {
534 s.managed.push_back(t: widget);
535 } else {
536 s.unmanaged.push_back(t: widget);
537 }
538 } else {
539 s.objects.push_back(t: object);
540 }
541 }
542}
543
544QObject *QDesignerIntegrationPrivate::propertyEditorObject()
545{
546 if (QDesignerPropertyEditorInterface *propertyEditor = q->core()->propertyEditor())
547 return propertyEditor->object();
548 return nullptr;
549}
550
551// Load plugins into widget database and factory.
552void QDesignerIntegrationPrivate::initializePlugins(QDesignerFormEditorInterface *formEditor)
553{
554 // load the plugins
555 qdesigner_internal::WidgetDataBase *widgetDataBase = qobject_cast<qdesigner_internal::WidgetDataBase*>(object: formEditor->widgetDataBase());
556 if (widgetDataBase) {
557 widgetDataBase->loadPlugins();
558 }
559
560 if (qdesigner_internal::WidgetFactory *widgetFactory = qobject_cast<qdesigner_internal::WidgetFactory*>(object: formEditor->widgetFactory())) {
561 widgetFactory->loadPlugins();
562 }
563
564 if (widgetDataBase) {
565 widgetDataBase->grabDefaultPropertyValues();
566 }
567}
568
569void QDesignerIntegrationPrivate::updateCustomWidgetPlugins()
570{
571 QDesignerFormEditorInterface *formEditor = q->core();
572 if (QDesignerPluginManager *pm = formEditor->pluginManager())
573 pm->registerNewPlugins();
574
575 initializePlugins(formEditor);
576
577 // Do not just reload the last file as the WidgetBox merges the compiled-in resources
578 // and $HOME/.designer/widgetbox.xml. This would also double the scratchpad.
579 if (QDesignerWidgetBox *wb = qobject_cast<QDesignerWidgetBox*>(object: formEditor->widgetBox())) {
580 const QDesignerWidgetBox::LoadMode oldLoadMode = wb->loadMode();
581 wb->setLoadMode(QDesignerWidgetBox::LoadCustomWidgetsOnly);
582 wb->load();
583 wb->setLoadMode(oldLoadMode);
584 }
585}
586
587static QString fixHelpClassName(const QString &className)
588{
589 // ### generalize using the Widget Data Base
590 if (className == QStringLiteral("Line"))
591 return QStringLiteral("QFrame");
592 if (className == QStringLiteral("Spacer"))
593 return QStringLiteral("QSpacerItem");
594 if (className == QStringLiteral("QLayoutWidget"))
595 return QStringLiteral("QLayout");
596 return className;
597}
598
599// Return class in which the property is defined
600static QString classForProperty(QDesignerFormEditorInterface *core,
601 QObject *object,
602 const QString &property)
603{
604 if (const QDesignerPropertySheetExtension *ps = qt_extension<QDesignerPropertySheetExtension *>(manager: core->extensionManager(), object)) {
605 const int index = ps->indexOf(name: property);
606 if (index >= 0)
607 return ps->propertyGroup(index);
608 }
609 return QString();
610}
611
612QString QDesignerIntegrationPrivate::contextHelpId() const
613{
614 QDesignerFormEditorInterface *core = q->core();
615 QObject *currentObject = core->propertyEditor()->object();
616 if (!currentObject)
617 return QString();
618 // Return a help index id consisting of "class::property"
619 QString className;
620 QString currentPropertyName = core->propertyEditor()->currentPropertyName();
621 if (!currentPropertyName.isEmpty())
622 className = classForProperty(core, object: currentObject, property: currentPropertyName);
623 if (className.isEmpty()) {
624 currentPropertyName.clear(); // We hit on some fake property.
625 className = qdesigner_internal::WidgetFactory::classNameOf(core, o: currentObject);
626 }
627 QString helpId = fixHelpClassName(className);
628 if (!currentPropertyName.isEmpty()) {
629 helpId += QStringLiteral("::");
630 helpId += currentPropertyName;
631 }
632 return helpId;
633}
634
635} // namespace qdesigner_internal
636
637// -------------- QDesignerIntegration
638// As of 4.4, the header will be distributed with the Eclipse plugin.
639
640QDesignerIntegration::QDesignerIntegration(QDesignerFormEditorInterface *core, QObject *parent) :
641 QDesignerIntegrationInterface(core, parent),
642 d(new qdesigner_internal::QDesignerIntegrationPrivate(this))
643{
644 d->initialize();
645}
646
647QDesignerIntegration::~QDesignerIntegration()
648{
649 QFile f(d->m_gradientsPath);
650 if (f.open(flags: QIODevice::WriteOnly)) {
651 f.write(data: QtGradientUtils::saveState(manager: d->m_gradientManager).toUtf8());
652 f.close();
653 }
654}
655
656QString QDesignerIntegration::headerSuffix() const
657{
658 return d->headerSuffix;
659}
660
661void QDesignerIntegration::setHeaderSuffix(const QString &headerSuffix)
662{
663 d->headerSuffix = headerSuffix;
664}
665
666bool QDesignerIntegration::isHeaderLowercase() const
667{
668 return d->headerLowercase;
669}
670
671void QDesignerIntegration::setHeaderLowercase(bool headerLowercase)
672{
673 d->headerLowercase = headerLowercase;
674}
675
676QDesignerIntegrationInterface::Feature QDesignerIntegration::features() const
677{
678 return d->m_features;
679}
680
681void QDesignerIntegration::setFeatures(Feature f)
682{
683 d->m_features = f;
684}
685
686QDesignerIntegrationInterface::ResourceFileWatcherBehaviour QDesignerIntegration::resourceFileWatcherBehaviour() const
687{
688 return d->m_resourceFileWatcherBehaviour;
689}
690
691void QDesignerIntegration::setResourceFileWatcherBehaviour(ResourceFileWatcherBehaviour behaviour)
692{
693 if (d->m_resourceFileWatcherBehaviour != behaviour) {
694 d->m_resourceFileWatcherBehaviour = behaviour;
695 core()->resourceModel()->setWatcherEnabled(behaviour != QDesignerIntegrationInterface::NoResourceFileWatcher);
696 }
697}
698
699void QDesignerIntegration::updateProperty(const QString &name, const QVariant &value, bool enableSubPropertyHandling)
700{
701 d->updateProperty(name, value, enableSubPropertyHandling);
702 emit propertyChanged(formWindow: core()->formWindowManager()->activeFormWindow(), name, value);
703}
704
705void QDesignerIntegration::updateProperty(const QString &name, const QVariant &value)
706{
707 updateProperty(name, value, enableSubPropertyHandling: true);
708}
709
710void QDesignerIntegration::resetProperty(const QString &name)
711{
712 d->resetProperty(name);
713}
714
715void QDesignerIntegration::addDynamicProperty(const QString &name, const QVariant &value)
716{
717 d->addDynamicProperty(name, value);
718}
719
720void QDesignerIntegration::removeDynamicProperty(const QString &name)
721{
722 d->removeDynamicProperty(name);
723}
724
725void QDesignerIntegration::updateActiveFormWindow(QDesignerFormWindowInterface *)
726{
727 d->updateSelection();
728}
729
730void QDesignerIntegration::setupFormWindow(QDesignerFormWindowInterface *formWindow)
731{
732 d->setupFormWindow(formWindow);
733 connect(sender: formWindow, signal: &QDesignerFormWindowInterface::selectionChanged,
734 receiver: this, slot: &QDesignerIntegrationInterface::updateSelection);
735}
736
737void QDesignerIntegration::updateSelection()
738{
739 d->updateSelection();
740}
741
742QWidget *QDesignerIntegration::containerWindow(QWidget *widget) const
743{
744 return d->containerWindow(widget);
745}
746
747// Load plugins into widget database and factory.
748void QDesignerIntegration::initializePlugins(QDesignerFormEditorInterface *formEditor)
749{
750 qdesigner_internal::QDesignerIntegrationPrivate::initializePlugins(formEditor);
751}
752
753void QDesignerIntegration::updateCustomWidgetPlugins()
754{
755 d->updateCustomWidgetPlugins();
756}
757
758QDesignerResourceBrowserInterface *QDesignerIntegration::createResourceBrowser(QWidget *)
759{
760 return nullptr;
761}
762
763QString QDesignerIntegration::contextHelpId() const
764{
765 return d->contextHelpId();
766}
767
768QT_END_NAMESPACE
769

source code of qttools/src/designer/src/lib/sdk/abstractintegration.cpp