Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qdesigner_components.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include <QtDesigner/QDesignerComponents>
5
6#include <actioneditor_p.h>
7#include <pluginmanager_p.h>
8#include <widgetdatabase_p.h>
9#include <widgetfactory_p.h>
10
11#include <formeditor/formeditor.h>
12#include <widgetbox/widgetbox.h>
13#include <propertyeditor/propertyeditor.h>
14#include <objectinspector/objectinspector.h>
15#include <taskmenu/taskmenu_component.h>
17#include <signalsloteditor/signalsloteditorwindow.h>
18
19#include <buddyeditor/buddyeditor_plugin.h>
20#include <signalsloteditor/signalsloteditor_plugin.h>
21#include <tabordereditor/tabordereditor_plugin.h>
22
23#include <QtDesigner/abstractlanguage.h>
24#include <QtDesigner/qextensionmanager.h>
25#include <QtDesigner/abstractintegration.h>
26#include <QtDesigner/abstractresourcebrowser.h>
27
28#include <QtCore/qplugin.h>
29#include <QtCore/qdir.h>
30#include <QtCore/qtextstream.h>
31#include <QtCore/qdebug.h>
32#include <QtCore/qfile.h>
33#include <QtCore/qfileinfo.h>
34
35#define INIT_PLUGIN_INSTANCE(PLUGIN)
36 do {
37 Static##PLUGIN##PluginInstance instance;
38 Q_UNUSED(instance);
39 } while (0)
40
41Q_IMPORT_PLUGIN(SignalSlotEditorPlugin)
42Q_IMPORT_PLUGIN(BuddyEditorPlugin)
43Q_IMPORT_PLUGIN(TabOrderEditorPlugin)
44
45static void initResources()
46{
47 // Q_INIT_RESOURCE only usable in functions in global namespace
48 Q_INIT_RESOURCE(formeditor);
49 Q_INIT_RESOURCE(widgetbox);
50 Q_INIT_RESOURCE(propertyeditor);
51}
52
53
54static void initInstances()
55{
56 static bool plugins_initialized = false;
57
58 if (!plugins_initialized) {
59 INIT_PLUGIN_INSTANCE(SignalSlotEditorPlugin);
60 INIT_PLUGIN_INSTANCE(BuddyEditorPlugin);
61 INIT_PLUGIN_INSTANCE(TabOrderEditorPlugin);
62 plugins_initialized = true;
63 }
64}
65
66QT_BEGIN_NAMESPACE
67
68using namespace Qt::StringLiterals;
69
70/*!
71 \class QDesignerComponents
72 \brief The QDesignerComponents class provides a central resource for the various components
73 used in the \QD user interface.
74 \inmodule QtDesigner
75 \internal
76
77 The QDesignerComponents class is a factory for each of the standard components present
78 in the \QD user interface. It is mostly useful for developers who want to implement
79 a standalone form editing environment using \QD's components, or who need to integrate
80 \QD's components into an existing integrated development environment (IDE).
81
82 \sa QDesignerFormEditorInterface, QDesignerObjectInspectorInterface,
83 QDesignerPropertyEditorInterface, QDesignerWidgetBoxInterface
84*/
85
86/*!
87 Initializes the resources used by the components.*/
88void QDesignerComponents::initializeResources()
89{
90 initResources();
91}
92
93/*!
94 Initializes the plugins used by the components.*/
95void QDesignerComponents::initializePlugins(QDesignerFormEditorInterface *core)
96{
97 QDesignerIntegration::initializePlugins(core);
98}
99
100// ### fixme Qt 7 createFormEditorWithPluginPaths->createFormEditor
101
102/*!
103 Constructs a form editor interface with the given \a parent.*/
104QDesignerFormEditorInterface *QDesignerComponents::createFormEditor(QObject *parent)
105{
106 return createFormEditorWithPluginPaths({}, parent);
107}
108
109/*!
110 Constructs a form editor interface with the given \a pluginPaths and the \a parent.
111 \since 6.7
112*/
113QDesignerFormEditorInterface *
114 QDesignerComponents::createFormEditorWithPluginPaths(const QStringList &pluginPaths,
115 QObject *parent)
116{
117 initInstances();
118 return new qdesigner_internal::FormEditor(pluginPaths, parent);
119}
120
121/*!
122 Returns a new task menu with the given \a parent for the \a core interface.*/
123QObject *QDesignerComponents::createTaskMenu(QDesignerFormEditorInterface *core, QObject *parent)
124{
125 return new qdesigner_internal::TaskMenuComponent(core, parent);
126}
127
128static inline int qtMajorVersion(int qtVersion) { return qtVersion >> 16; }
129static inline int qtMinorVersion(int qtVersion) { return (qtVersion >> 8) & 0xFF; }
130static inline void setMinorVersion(int minorVersion, int *qtVersion)
131{
132 *qtVersion &= ~0xFF00;
133 *qtVersion |= minorVersion << 8;
134}
135
136// Build the version-dependent name of the user widget box file, '$HOME.designer/widgetbox4.4.xml'
137static inline QString widgetBoxFileName(int qtVersion, const QDesignerLanguageExtension *lang = nullptr)
138{
139 QString rc; {
140 QTextStream str(&rc);
141 str << QDir::homePath() << QDir::separator() << ".designer" << QDir::separator()
142 << "widgetbox";
143 // The naming convention using the version was introduced with 4.4
144 const int major = qtMajorVersion(qtVersion);
145 const int minor = qtMinorVersion(qtVersion);
146 if (major >= 4 && minor >= 4)
147 str << major << '.' << minor;
148 if (lang)
149 str << '.' << lang->uiExtension();
150 str << ".xml";
151 }
152 return rc;
153}
154
155/*!
156 Returns a new widget box interface with the given \a parent for the \a core interface.*/
157QDesignerWidgetBoxInterface *QDesignerComponents::createWidgetBox(QDesignerFormEditorInterface *core, QWidget *parent)
158{
159 qdesigner_internal::WidgetBox *widgetBox = new qdesigner_internal::WidgetBox(core, parent);
160
161 const QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core);
162
163 do {
164 if (lang) {
165 const QString languageWidgetBox = lang->widgetBoxContents();
166 if (!languageWidgetBox.isEmpty()) {
167 widgetBox->loadContents(lang->widgetBoxContents());
168 break;
169 }
170 }
171
172 widgetBox->setFileName(u":/qt-project.org/widgetbox/widgetbox.xml"_s);
173 widgetBox->load();
174 } while (false);
175
176 const QString userWidgetBoxFile = widgetBoxFileName(QT_VERSION, lang);
177
178 widgetBox->setFileName(userWidgetBoxFile);
179 if (!QFileInfo::exists(userWidgetBoxFile)) {
180 // check previous version, that is, are we running the new version for the first time
181 // If so, try to copy the old widget box file
182 if (const int minv = qtMinorVersion(QT_VERSION)) {
183 int oldVersion = QT_VERSION;
184 setMinorVersion(minv - 1, &oldVersion);
185 const QString oldWidgetBoxFile = widgetBoxFileName(oldVersion, lang);
186 if (QFileInfo::exists(oldWidgetBoxFile))
187 QFile::copy(oldWidgetBoxFile, userWidgetBoxFile);
188 }
189 }
190 widgetBox->load();
191
192 return widgetBox;
193}
194
195/*!
196 Returns a new property editor interface with the given \a parent for the \a core interface.*/
197QDesignerPropertyEditorInterface *QDesignerComponents::createPropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent)
198{
199 return new qdesigner_internal::PropertyEditor(core, parent);
200}
201
202/*!
203 Returns a new object inspector interface with the given \a parent for the \a core interface.*/
204QDesignerObjectInspectorInterface *QDesignerComponents::createObjectInspector(QDesignerFormEditorInterface *core, QWidget *parent)
205{
206 return new qdesigner_internal::ObjectInspector(core, parent);
207}
208
209/*!
210 Returns a new action editor interface with the given \a parent for the \a core interface.*/
211QDesignerActionEditorInterface *QDesignerComponents::createActionEditor(QDesignerFormEditorInterface *core, QWidget *parent)
212{
213 return new qdesigner_internal::ActionEditor(core, parent);
214}
215
216/*!
217 Returns a new resource editor with the given \a parent for the \a core interface.*/
218QWidget *QDesignerComponents::createResourceEditor(QDesignerFormEditorInterface *core, QWidget *parent)
219{
220 if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core)) {
221 QWidget *w = lang->createResourceBrowser(parent);
222 if (w)
223 return w;
224 }
225 QtResourceView *resourceView = new QtResourceView(core, parent);
226 resourceView->setResourceModel(core->resourceModel());
227 resourceView->setSettingsKey(u"ResourceBrowser"_s);
228 // Note for integrators: make sure you call createResourceEditor() after you instantiated your subclass of designer integration
229 // (designer doesn't do that since by default editing resources is enabled)
230 const QDesignerIntegrationInterface *integration = core->integration();
231 if (integration && !integration->hasFeature(QDesignerIntegrationInterface::ResourceEditorFeature))
232 resourceView->setResourceEditingEnabled(false);
233 return resourceView;
234}
235
236/*!
237 Returns a new signal-slot editor with the given \a parent for the \a core interface.*/
238QWidget *QDesignerComponents::createSignalSlotEditor(QDesignerFormEditorInterface *core, QWidget *parent)
239{
240 return new qdesigner_internal::SignalSlotEditorWindow(core, parent);
241}
242
243/*!
244 Returns the default plugin paths of Qt Widgets Designer's plugin manager.
245
246 \return Plugin paths
247 \since 6.7
248*/
249QStringList QDesignerComponents::defaultPluginPaths()
250{
251 return QDesignerPluginManager::defaultPluginPaths();
252}
253
254QT_END_NAMESPACE
#define INIT_PLUGIN_INSTANCE(PLUGIN)
static int qtMajorVersion(int qtVersion)
static QString widgetBoxFileName(int qtVersion, const QDesignerLanguageExtension *lang=nullptr)
static void setMinorVersion(int minorVersion, int *qtVersion)
static int qtMinorVersion(int qtVersion)