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

source code of qttools/src/designer/src/components/lib/qdesigner_components.cpp