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 "qdesigner.h" |
30 | #include "qdesigner_toolwindow.h" |
31 | #include "qdesigner_settings.h" |
32 | #include "qdesigner_workbench.h" |
33 | |
34 | #include <QtDesigner/abstractpropertyeditor.h> |
35 | #include <QtDesigner/abstractformeditor.h> |
36 | #include <QtDesigner/abstractactioneditor.h> |
37 | #include <QtDesigner/abstractobjectinspector.h> |
38 | #include <QtDesigner/abstractwidgetbox.h> |
39 | #include <QtDesigner/QDesignerComponents> |
40 | |
41 | #include <QtCore/qdebug.h> |
42 | #include <QtWidgets/qaction.h> |
43 | #include <QtGui/qevent.h> |
44 | |
45 | enum { debugToolWindow = 0 }; |
46 | |
47 | QT_BEGIN_NAMESPACE |
48 | |
49 | // ---------------- QDesignerToolWindowFontSettings |
50 | bool ToolWindowFontSettings::equals(const ToolWindowFontSettings &rhs) const |
51 | { |
52 | return m_useFont == rhs.m_useFont && |
53 | m_writingSystem == rhs.m_writingSystem && |
54 | m_font == rhs.m_font; |
55 | } |
56 | |
57 | // ---------------- QDesignerToolWindow |
58 | QDesignerToolWindow::QDesignerToolWindow(QDesignerWorkbench *workbench, |
59 | QWidget *w, |
60 | const QString &objectName, |
61 | const QString &title, |
62 | const QString &actionObjectName, |
63 | Qt::DockWidgetArea dockAreaHint, |
64 | QWidget *parent, |
65 | Qt::WindowFlags flags) : |
66 | MainWindowBase(parent, flags), |
67 | m_dockAreaHint(dockAreaHint), |
68 | m_workbench(workbench), |
69 | m_action(new QAction(this)) |
70 | { |
71 | setObjectName(objectName); |
72 | setCentralWidget(w); |
73 | |
74 | setWindowTitle(title); |
75 | |
76 | m_action->setObjectName(actionObjectName); |
77 | m_action->setShortcutContext(Qt::ApplicationShortcut); |
78 | m_action->setText(title); |
79 | m_action->setCheckable(true); |
80 | connect(sender: m_action, signal: &QAction::triggered, receiver: this, slot: &QDesignerToolWindow::showMe); |
81 | } |
82 | |
83 | void QDesignerToolWindow::showMe(bool v) |
84 | { |
85 | // Access the QMdiSubWindow in MDI mode. |
86 | if (QWidget *target = m_workbench->mode() == DockedMode ? parentWidget() : this) { |
87 | if (v) |
88 | target->setWindowState(target->windowState() & ~Qt::WindowMinimized); |
89 | target->setVisible(v); |
90 | } |
91 | } |
92 | |
93 | void QDesignerToolWindow::showEvent(QShowEvent *e) |
94 | { |
95 | Q_UNUSED(e); |
96 | |
97 | bool blocked = m_action->blockSignals(b: true); |
98 | m_action->setChecked(true); |
99 | m_action->blockSignals(b: blocked); |
100 | } |
101 | |
102 | void QDesignerToolWindow::hideEvent(QHideEvent *e) |
103 | { |
104 | Q_UNUSED(e); |
105 | |
106 | bool blocked = m_action->blockSignals(b: true); |
107 | m_action->setChecked(false); |
108 | m_action->blockSignals(b: blocked); |
109 | } |
110 | |
111 | QAction *QDesignerToolWindow::action() const |
112 | { |
113 | return m_action; |
114 | } |
115 | |
116 | void QDesignerToolWindow::changeEvent(QEvent *e) |
117 | { |
118 | switch (e->type()) { |
119 | case QEvent::WindowTitleChange: |
120 | m_action->setText(windowTitle()); |
121 | break; |
122 | case QEvent::WindowIconChange: |
123 | m_action->setIcon(windowIcon()); |
124 | break; |
125 | default: |
126 | break; |
127 | } |
128 | QMainWindow::changeEvent(e); |
129 | } |
130 | |
131 | QDesignerWorkbench *QDesignerToolWindow::workbench() const |
132 | { |
133 | return m_workbench; |
134 | } |
135 | |
136 | QRect QDesignerToolWindow::geometryHint() const |
137 | { |
138 | return QRect(); |
139 | } |
140 | |
141 | QRect QDesignerToolWindow::availableToolWindowGeometry() const |
142 | { |
143 | return m_workbench->availableGeometry(); |
144 | } |
145 | |
146 | // ---------------------- PropertyEditorToolWindow |
147 | |
148 | static inline QWidget *createPropertyEditor(QDesignerFormEditorInterface *core, QWidget *parent = nullptr) |
149 | { |
150 | QDesignerPropertyEditorInterface *widget = QDesignerComponents::createPropertyEditor(core, parent); |
151 | core->setPropertyEditor(widget); |
152 | return widget; |
153 | } |
154 | |
155 | class PropertyEditorToolWindow : public QDesignerToolWindow |
156 | { |
157 | public: |
158 | explicit PropertyEditorToolWindow(QDesignerWorkbench *workbench); |
159 | |
160 | QRect geometryHint() const override; |
161 | |
162 | protected: |
163 | void showEvent(QShowEvent *event) override; |
164 | }; |
165 | |
166 | PropertyEditorToolWindow::PropertyEditorToolWindow(QDesignerWorkbench *workbench) : |
167 | QDesignerToolWindow(workbench, |
168 | createPropertyEditor(core: workbench->core()), |
169 | QStringLiteral("qt_designer_propertyeditor" ), |
170 | QDesignerToolWindow::tr(s: "Property Editor" ), |
171 | QStringLiteral("__qt_property_editor_action" ), |
172 | Qt::RightDockWidgetArea) |
173 | { |
174 | action()->setShortcut(Qt::CTRL | Qt::Key_I); |
175 | |
176 | } |
177 | |
178 | QRect PropertyEditorToolWindow::geometryHint() const |
179 | { |
180 | const QRect g = availableToolWindowGeometry(); |
181 | const int margin = workbench()->marginHint(); |
182 | const int spacing = 40; |
183 | const QSize sz(g.width() * 1/4, g.height() * 4/6); |
184 | |
185 | const QRect rc = QRect((g.right() + 1 - sz.width() - margin), |
186 | (g.top() + margin + g.height() * 1/6) + spacing, |
187 | sz.width(), sz.height()); |
188 | if (debugToolWindow) |
189 | qDebug() << Q_FUNC_INFO << rc; |
190 | return rc; |
191 | } |
192 | |
193 | void PropertyEditorToolWindow::showEvent(QShowEvent *event) |
194 | { |
195 | if (QDesignerPropertyEditorInterface *e = workbench()->core()->propertyEditor()) { |
196 | // workaround to update the propertyeditor when it is not visible! |
197 | e->setObject(e->object()); // ### remove me |
198 | } |
199 | |
200 | QDesignerToolWindow::showEvent(e: event); |
201 | } |
202 | |
203 | // ---------------------- ActionEditorToolWindow |
204 | |
205 | static inline QWidget *createActionEditor(QDesignerFormEditorInterface *core, QWidget *parent = nullptr) |
206 | { |
207 | QDesignerActionEditorInterface *widget = QDesignerComponents::createActionEditor(core, parent); |
208 | core->setActionEditor(widget); |
209 | return widget; |
210 | } |
211 | |
212 | class ActionEditorToolWindow: public QDesignerToolWindow |
213 | { |
214 | public: |
215 | explicit ActionEditorToolWindow(QDesignerWorkbench *workbench); |
216 | |
217 | QRect geometryHint() const override; |
218 | }; |
219 | |
220 | ActionEditorToolWindow::ActionEditorToolWindow(QDesignerWorkbench *workbench) : |
221 | QDesignerToolWindow(workbench, |
222 | createActionEditor(core: workbench->core()), |
223 | QStringLiteral("qt_designer_actioneditor" ), |
224 | QDesignerToolWindow::tr(s: "Action Editor" ), |
225 | QStringLiteral("__qt_action_editor_tool_action" ), |
226 | Qt::RightDockWidgetArea) |
227 | { |
228 | } |
229 | |
230 | QRect ActionEditorToolWindow::geometryHint() const |
231 | { |
232 | const QRect g = availableToolWindowGeometry(); |
233 | const int margin = workbench()->marginHint(); |
234 | |
235 | const QSize sz(g.width() * 1/4, g.height() * 1/6); |
236 | |
237 | const QRect rc = QRect((g.right() + 1 - sz.width() - margin), |
238 | g.top() + margin, |
239 | sz.width(), sz.height()); |
240 | if (debugToolWindow) |
241 | qDebug() << Q_FUNC_INFO << rc; |
242 | return rc; |
243 | } |
244 | |
245 | // ---------------------- ObjectInspectorToolWindow |
246 | |
247 | static inline QWidget *createObjectInspector(QDesignerFormEditorInterface *core, QWidget *parent = nullptr) |
248 | { |
249 | QDesignerObjectInspectorInterface *widget = QDesignerComponents::createObjectInspector(core, parent); |
250 | core->setObjectInspector(widget); |
251 | return widget; |
252 | } |
253 | |
254 | class ObjectInspectorToolWindow: public QDesignerToolWindow |
255 | { |
256 | public: |
257 | explicit ObjectInspectorToolWindow(QDesignerWorkbench *workbench); |
258 | |
259 | QRect geometryHint() const override; |
260 | }; |
261 | |
262 | ObjectInspectorToolWindow::ObjectInspectorToolWindow(QDesignerWorkbench *workbench) : |
263 | QDesignerToolWindow(workbench, |
264 | createObjectInspector(core: workbench->core()), |
265 | QStringLiteral("qt_designer_objectinspector" ), |
266 | QDesignerToolWindow::tr(s: "Object Inspector" ), |
267 | QStringLiteral("__qt_object_inspector_tool_action" ), |
268 | Qt::RightDockWidgetArea) |
269 | { |
270 | } |
271 | |
272 | QRect ObjectInspectorToolWindow::geometryHint() const |
273 | { |
274 | const QRect g = availableToolWindowGeometry(); |
275 | const int margin = workbench()->marginHint(); |
276 | |
277 | const QSize sz(g.width() * 1/4, g.height() * 1/6); |
278 | |
279 | const QRect rc = QRect((g.right() + 1 - sz.width() - margin), |
280 | g.top() + margin, |
281 | sz.width(), sz.height()); |
282 | if (debugToolWindow) |
283 | qDebug() << Q_FUNC_INFO << rc; |
284 | return rc; |
285 | } |
286 | |
287 | // ---------------------- ResourceEditorToolWindow |
288 | |
289 | class ResourceEditorToolWindow: public QDesignerToolWindow |
290 | { |
291 | public: |
292 | explicit ResourceEditorToolWindow(QDesignerWorkbench *workbench); |
293 | |
294 | QRect geometryHint() const override; |
295 | }; |
296 | |
297 | ResourceEditorToolWindow::ResourceEditorToolWindow(QDesignerWorkbench *workbench) : |
298 | QDesignerToolWindow(workbench, |
299 | QDesignerComponents::createResourceEditor(core: workbench->core(), parent: nullptr), |
300 | QStringLiteral("qt_designer_resourceeditor" ), |
301 | QDesignerToolWindow::tr(s: "Resource Browser" ), |
302 | QStringLiteral("__qt_resource_editor_tool_action" ), |
303 | Qt::RightDockWidgetArea) |
304 | { |
305 | } |
306 | |
307 | QRect ResourceEditorToolWindow::geometryHint() const |
308 | { |
309 | const QRect g = availableToolWindowGeometry(); |
310 | const int margin = workbench()->marginHint(); |
311 | |
312 | const QSize sz(g.width() * 1/3, g.height() * 1/6); |
313 | QRect r(QPoint(0, 0), sz); |
314 | r.moveCenter(p: g.center()); |
315 | r.moveBottom(pos: g.bottom() - margin); |
316 | if (debugToolWindow) |
317 | qDebug() << Q_FUNC_INFO << r; |
318 | return r; |
319 | } |
320 | |
321 | // ---------------------- SignalSlotEditorToolWindow |
322 | |
323 | class SignalSlotEditorToolWindow: public QDesignerToolWindow |
324 | { |
325 | public: |
326 | explicit SignalSlotEditorToolWindow(QDesignerWorkbench *workbench); |
327 | |
328 | QRect geometryHint() const override; |
329 | }; |
330 | |
331 | SignalSlotEditorToolWindow::SignalSlotEditorToolWindow(QDesignerWorkbench *workbench) : |
332 | QDesignerToolWindow(workbench, |
333 | QDesignerComponents::createSignalSlotEditor(core: workbench->core(), parent: nullptr), |
334 | QStringLiteral("qt_designer_signalsloteditor" ), |
335 | QDesignerToolWindow::tr(s: "Signal/Slot Editor" ), |
336 | QStringLiteral("__qt_signal_slot_editor_tool_action" ), |
337 | Qt::RightDockWidgetArea) |
338 | { |
339 | } |
340 | |
341 | QRect SignalSlotEditorToolWindow::geometryHint() const |
342 | { |
343 | const QRect g = availableToolWindowGeometry(); |
344 | const int margin = workbench()->marginHint(); |
345 | |
346 | const QSize sz(g.width() * 1/3, g.height() * 1/6); |
347 | QRect r(QPoint(0, 0), sz); |
348 | r.moveCenter(p: g.center()); |
349 | r.moveTop(pos: margin + g.top()); |
350 | if (debugToolWindow) |
351 | qDebug() << Q_FUNC_INFO << r; |
352 | return r; |
353 | } |
354 | |
355 | // ---------------------- WidgetBoxToolWindow |
356 | |
357 | static inline QWidget *createWidgetBox(QDesignerFormEditorInterface *core, QWidget *parent = nullptr) |
358 | { |
359 | QDesignerWidgetBoxInterface *widget = QDesignerComponents::createWidgetBox(core, parent); |
360 | core->setWidgetBox(widget); |
361 | return widget; |
362 | } |
363 | |
364 | class WidgetBoxToolWindow: public QDesignerToolWindow |
365 | { |
366 | public: |
367 | explicit WidgetBoxToolWindow(QDesignerWorkbench *workbench); |
368 | |
369 | QRect geometryHint() const override; |
370 | }; |
371 | |
372 | WidgetBoxToolWindow::WidgetBoxToolWindow(QDesignerWorkbench *workbench) : |
373 | QDesignerToolWindow(workbench, |
374 | createWidgetBox(core: workbench->core()), |
375 | QStringLiteral("qt_designer_widgetbox" ), |
376 | QDesignerToolWindow::tr(s: "Widget Box" ), |
377 | QStringLiteral("__qt_widget_box_tool_action" ), |
378 | Qt::LeftDockWidgetArea) |
379 | { |
380 | } |
381 | |
382 | QRect WidgetBoxToolWindow::geometryHint() const |
383 | { |
384 | const QRect g = availableToolWindowGeometry(); |
385 | const int margin = workbench()->marginHint(); |
386 | const QRect rc = QRect(g.left() + margin, |
387 | g.top() + margin, |
388 | g.width() * 1/4, g.height() * 5/6); |
389 | if (debugToolWindow) |
390 | qDebug() << Q_FUNC_INFO << rc; |
391 | return rc; |
392 | } |
393 | |
394 | // -- Factory |
395 | QDesignerToolWindow *QDesignerToolWindow::createStandardToolWindow(StandardToolWindow which, |
396 | QDesignerWorkbench *workbench) |
397 | { |
398 | switch (which) { |
399 | case ActionEditor: |
400 | return new ActionEditorToolWindow(workbench); |
401 | case ResourceEditor: |
402 | return new ResourceEditorToolWindow(workbench); |
403 | case SignalSlotEditor: |
404 | return new SignalSlotEditorToolWindow(workbench); |
405 | case PropertyEditor: |
406 | return new PropertyEditorToolWindow(workbench); |
407 | case ObjectInspector: |
408 | return new ObjectInspectorToolWindow(workbench); |
409 | case WidgetBox: |
410 | return new WidgetBoxToolWindow(workbench); |
411 | default: |
412 | break; |
413 | } |
414 | return nullptr; |
415 | } |
416 | |
417 | |
418 | QT_END_NAMESPACE |
419 | |