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
formwindowbase.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
12#include "grid_p.h"
16
17#include <QtDesigner/abstractformeditor.h>
18#include <QtDesigner/container.h>
19#include <QtDesigner/qextensionmanager.h>
20#include <QtDesigner/taskmenu.h>
21#include <QtDesigner/abstractintegration.h>
22
23#include <QtWidgets/qmenu.h>
24#include <QtWidgets/qlistwidget.h>
25#include <QtWidgets/qtreewidget.h>
26#include <QtWidgets/qtablewidget.h>
27#include <QtWidgets/qcombobox.h>
28#include <QtWidgets/qtabwidget.h>
29#include <QtWidgets/qtoolbox.h>
30#include <QtWidgets/qtoolbar.h>
31#include <QtWidgets/qstatusbar.h>
32#include <QtWidgets/qmenu.h>
33#include <QtWidgets/qlabel.h>
34
35#include <QtGui/qaction.h>
36
37#include <QtCore/qdebug.h>
38#include <QtCore/qhash.h>
39#include <QtCore/qlist.h>
40#include <QtCore/qset.h>
41#include <QtCore/qtimer.h>
42
44
45using namespace Qt::StringLiterals;
46
47namespace qdesigner_internal {
48
69
84
86
97
114
119
124
129
134
140
149
160
162{
165 // already connected
166 return;
167 }
169}
170
172{
175 // still need to be connected
176 return;
177 }
179}
180
182{
183 // qobject_cast<QDesignerPropertySheet *>(object)
184 // will fail since the destructor of QDesignerPropertySheet
185 // has already finished
186
187 for (auto it = m_d->m_reloadableResources.begin();
188 it != m_d->m_reloadableResources.end(); ++it) {
189 if (it.key() == object) {
191 break;
192 }
193 }
194
195 for (auto it = m_d->m_reloadablePropertySheets.begin();
197 if (it.key() == object) {
199 break;
200 }
201 }
202}
203
205{
206 pixmapCache()->clear();
207 iconCache()->clear();
210 for (int index : it.value()) {
212 if (qobject_cast<QLabel *>(sheet->object()) && sheet->propertyName(index) == "text"_L1) {
214 // optimize a bit, reset only if the text value might contain a reference to qt resources
215 // (however reloading of icons other than taken from resources might not work here)
216 if (newString.value().contains(":/"_L1)) {
219 }
220 }
222 }
224 const int count = tabWidget->count();
225 const int current = tabWidget->currentIndex();
226 const QString currentTabIcon = u"currentTabIcon"_s;
227 for (int i = 0; i < count; i++) {
229 const int index = sheet->indexOf(currentTabIcon);
231 }
233 } else if (QToolBox *toolBox = qobject_cast<QToolBox *>(sheet->object())) {
234 const int count = toolBox->count();
235 const int current = toolBox->currentIndex();
236 const QString currentItemIcon = u"currentItemIcon"_s;
237 for (int i = 0; i < count; i++) {
239 const int index = sheet->indexOf(currentItemIcon);
241 }
243 }
244 }
247 }
248}
249
260
262{
264 if (m_d->m_hasFormGrid)
266 return rc;
267}
268
276
278{
279 return QPoint(m_d->m_grid.deltaX(), m_d->m_grid.deltaY());
280}
281
283{
286}
287
289{
290 return f & m_d->m_feature;
291}
292
294{
295 w->update();
296
297 for (auto *child : w->children()) {
298 if (QWidget *w = qobject_cast<QWidget*>(child))
299 recursiveUpdate(w);
300 }
301}
302
313
318
320{
321 return m_d->m_grid.visible() && currentTool() == 0;
322}
323
328
333
335{
336 if (m_d->m_grid.snapX() || m_d->m_grid.snapY())
338 else
340}
341
343{
344 m_d->m_grid = grid;
346 recursiveUpdate(this);
347}
348
350{
351 return m_d->m_grid;
352}
353
355{
356 return m_d->m_hasFormGrid;
357}
358
360{
362}
363
368
373
375{
376 return nullptr;
377}
378
379// Widget under mouse for finding the Widget to highlight
380// when doing DnD. Restricts to pages by geometry if a container with
381// a container extension (or one of its helper widgets) is hit; otherwise
382// returns the widget as such (be it managed/unmanaged)
383
385{
386 // widget_under_mouse might be some temporary thing like the dropLine. We need
387 // the actual widget that's part of the edited GUI.
389 if (!rc || qobject_cast<ConnectionEdit*>(rc))
390 return nullptr;
391
392 if (rc == mainContainer()) {
393 // Refuse main container areas if the main container has a container extension,
394 // for example when hitting QToolBox/QTabWidget empty areas.
396 return nullptr;
397 return rc;
398 }
399
400 // If we hit on container extension type container, make sure
401 // we use the top-most current page
402 if (QWidget *container = findContainer(rc, false))
404 // For container that do not have a "stacked" nature (QToolBox, QMdiArea),
405 // make sure the position is within the current page
406 const int ci = c->currentIndex();
407 if (ci < 0)
408 return nullptr;
409 QWidget *page = c->widget(ci);
413 return nullptr;
414 return page;
415 }
416
417 return rc;
418}
419
421{
422 // We need a macro here even for single widgets because the some components (for example,
423 // the signal slot editor are connected to widgetRemoved() and add their
424 // own commands (for example, to delete w's connections)
425 const QString description = widget_list.size() == 1 ?
426 tr("Delete '%1'").arg(widget_list.constFirst()->objectName()) : tr("Delete");
427
429 for (QWidget *w : std::as_const(widget_list)) {
432 cmd->init(w);
434 }
436}
437
439{
440 using ActionList = QList<QAction *>;
442 // 1) Standard public extension
446 if (const auto *intTaskMenu = qobject_cast<QDesignerTaskMenuExtension *>(em->extension(o, u"QDesignerInternalTaskMenuExtension"_s))) {
447 if (!actions.isEmpty()) {
448 QAction *a = new QAction(fw);
449 a->setSeparator(true);
451 }
453 }
454 if (actions.isEmpty())
455 return nullptr;
457 QAction *a = new QAction(fw);
458 a->setSeparator(true);
460 }
461 QMenu *rc = new QMenu;
462 for (auto *a : std::as_const(actions))
463 rc->addAction(a);
464 return rc;
465}
466
471
476
481
486
491
496
501
503{
506}
507
512
517
519{
521}
522
527
529{
530 if (!mainContainer())
531 return QStringList(tr("Invalid form"));
532 // Test for non-laid toplevel spacers, which will not be saved
533 // as not to throw off uic.
535 const auto &spacers = mainContainer()->findChildren<Spacer *>();
536 for (const Spacer *spacer : spacers) {
537 if (spacer->parentWidget() && !spacer->parentWidget()->layout()) {
538 problems.push_back(tr("<p>This file contains top level spacers.<br/>"
539 "They will <b>not</b> be saved.</p><p>"
540 "Perhaps you forgot to create a layout?</p>"));
541 break;
542 }
543 }
544 return problems;
545}
546
547} // namespace qdesigner_internal
548
549QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:421
FormWindowBase::LineTerminatorMode m_lineTerminatorMode
QHash< QDesignerPropertySheet *, QObject * > m_reloadablePropertySheets
QHash< QDesignerPropertySheet *, QSet< int > > m_reloadableResources
QDesignerFormWindowInterface::Feature m_feature
FormWindowBase::ResourceFileSaveMode m_saveResourcesBehaviour
FormWindowBasePrivate(QDesignerFormEditorInterface *core)
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
static void recursiveUpdate(QWidget *w)