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_taskmenu.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
11#include "layout_p.h"
16#include "metadatabase_p.h"
22#include "morphmenu_p.h"
27
28#include <shared_enums_p.h>
29
30#include <QtDesigner/abstractformwindow.h>
31#include <QtDesigner/abstractformwindowcursor.h>
32#include <QtDesigner/propertysheet.h>
33#include <QtDesigner/abstractformeditor.h>
34#include <QtDesigner/abstractlanguage.h>
35#include <QtDesigner/abstractintegration.h>
36#include <QtDesigner/qextensionmanager.h>
37
38#include <QtWidgets/qwidget.h>
39#include <QtWidgets/qmenubar.h>
40#include <QtWidgets/qmainwindow.h>
41#include <QtWidgets/qstatusbar.h>
42#include <QtWidgets/qdialogbuttonbox.h>
43#include <QtWidgets/qboxlayout.h>
44#include <QtWidgets/qpushbutton.h>
45
46#include <QtGui/qaction.h>
47#include <QtGui/qactiongroup.h>
48#include <QtGui/qundostack.h>
49
50#include <QtCore/qdebug.h>
51#include <QtCore/qcoreapplication.h>
52
54
55using namespace Qt::StringLiterals;
56
57static inline QAction *createSeparatorHelper(QObject *parent) {
58 QAction *rc = new QAction(parent);
59 rc->setSeparator(true);
60 return rc;
61}
62
63static QString objName(const QDesignerFormEditorInterface *core, QObject *object) {
65 = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), object);
66 Q_ASSERT(sheet != nullptr);
67
68 const int index = sheet->indexOf(u"objectName"_s);
69 const QVariant v = sheet->property(index);
70 if (v.canConvert<qdesigner_internal::PropertySheetStringValue>())
71 return v.value<qdesigner_internal::PropertySheetStringValue>().value();
72 return v.toString();
73}
74
76
77namespace {
78// --------------- ObjectNameDialog
79class ObjectNameDialog : public QDialog
80{
81 public:
82 ObjectNameDialog(QWidget *parent, const QString &oldName);
83 QString newObjectName() const;
84
85 private:
86 qdesigner_internal::TextPropertyEditor *m_editor;
87};
88
89ObjectNameDialog::ObjectNameDialog(QWidget *parent, const QString &oldName)
90 : QDialog(parent),
91 m_editor( new qdesigner_internal::TextPropertyEditor(this, qdesigner_internal::TextPropertyEditor::EmbeddingNone,
92 qdesigner_internal::ValidationObjectName))
93{
94 setWindowTitle(QCoreApplication::translate("ObjectNameDialog", "Change Object Name"));
95
96 QVBoxLayout *vboxLayout = new QVBoxLayout(this);
97 vboxLayout->addWidget(new QLabel(QCoreApplication::translate("ObjectNameDialog", "Object Name")));
98
99 m_editor->setText(oldName);
100 m_editor->selectAll();
101 m_editor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
102 vboxLayout->addWidget(m_editor);
103
104 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
105 Qt::Horizontal, this);
106 QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
107 okButton->setDefault(true);
108 vboxLayout->addWidget(buttonBox);
109
110 connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
111 connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
112}
113
114QString ObjectNameDialog::newObjectName() const
115{
116 return m_editor->text();
117}
118} // namespace
119
120namespace qdesigner_internal {
121
122// Sub menu displaying the alignment options of a widget in a managed
123// grid/box layout cell.
126public:
128
129 QAction *subMenuAction() const { return m_subMenuAction; }
130
131 // Set up enabled state and checked actions according to widget (managed box/grid)
132 bool setAlignment(const QDesignerFormEditorInterface *core, QWidget *w);
133
134 // Return the currently checked alignment
136
137signals:
138 void changed();
139
140private:
141 enum Actions { HorizNone, Left, HorizCenter, Right, VerticalNone, Top, VerticalCenter, Bottom };
142 static QAction *createAction(const QString &text, int data, QMenu *menu, QActionGroup *ag);
143
144 QAction *m_subMenuAction;
145 QActionGroup *m_horizGroup;
146 QActionGroup *m_verticalGroup;
147 QAction *m_actions[Bottom + 1];
148};
149
150QAction *LayoutAlignmentMenu::createAction(const QString &text, int data, QMenu *menu, QActionGroup *ag)
151{
152 QAction * a = new QAction(text, nullptr);
153 a->setCheckable(true);
154 a->setData(QVariant(data));
155 menu->addAction(a);
156 ag->addAction(a);
157 return a;
158}
159
160LayoutAlignmentMenu::LayoutAlignmentMenu(QObject *parent) : QObject(parent),
161 m_subMenuAction(new QAction(QDesignerTaskMenu::tr("Layout Alignment"), parent)),
162 m_horizGroup(new QActionGroup(parent)),
163 m_verticalGroup(new QActionGroup(parent))
164{
165 m_horizGroup->setExclusive(true);
166 m_verticalGroup->setExclusive(true);
167 connect(m_horizGroup, &QActionGroup::triggered, this, &LayoutAlignmentMenu::changed);
168 connect(m_verticalGroup, &QActionGroup::triggered, this, &LayoutAlignmentMenu::changed);
169
170 QMenu *menu = new QMenu;
171 m_subMenuAction->setMenu(menu);
172
173 m_actions[HorizNone] = createAction(QDesignerTaskMenu::tr("No Horizontal Alignment"), 0, menu, m_horizGroup);
174 m_actions[Left] = createAction(QDesignerTaskMenu::tr("Left"), Qt::AlignLeft, menu, m_horizGroup);
175 m_actions[HorizCenter] = createAction(QDesignerTaskMenu::tr("Center Horizontally"), Qt::AlignHCenter, menu, m_horizGroup);
176 m_actions[Right] = createAction(QDesignerTaskMenu::tr("Right"), Qt::AlignRight, menu, m_horizGroup);
177 menu->addSeparator();
178 m_actions[VerticalNone] = createAction(QDesignerTaskMenu::tr("No Vertical Alignment"), 0, menu, m_verticalGroup);
179 m_actions[Top] = createAction(QDesignerTaskMenu::tr("Top"), Qt::AlignTop, menu, m_verticalGroup);
180 m_actions[VerticalCenter] = createAction(QDesignerTaskMenu::tr("Center Vertically"), Qt::AlignVCenter, menu, m_verticalGroup);
181 m_actions[Bottom] = createAction(QDesignerTaskMenu::tr("Bottom"), Qt::AlignBottom, menu, m_verticalGroup);
182}
183
184bool LayoutAlignmentMenu::setAlignment(const QDesignerFormEditorInterface *core, QWidget *w)
185{
186 bool enabled;
187 const Qt::Alignment alignment = LayoutAlignmentCommand::alignmentOf(core, w, &enabled);
188 m_subMenuAction->setEnabled(enabled);
189 if (!enabled) {
190 m_actions[HorizNone]->setChecked(true);
191 m_actions[VerticalNone]->setChecked(true);
192 return false;
193 }
194 // Get alignment
195 switch (alignment & Qt::AlignHorizontal_Mask) {
196 case Qt::AlignLeft:
197 m_actions[Left]->setChecked(true);
198 break;
199 case Qt::AlignHCenter:
200 m_actions[HorizCenter]->setChecked(true);
201 break;
202 case Qt::AlignRight:
203 m_actions[Right]->setChecked(true);
204 break;
205 default:
206 m_actions[HorizNone]->setChecked(true);
207 break;
208 }
209 switch (alignment & Qt::AlignVertical_Mask) {
210 case Qt::AlignTop:
211 m_actions[Top]->setChecked(true);
212 break;
213 case Qt::AlignVCenter:
214 m_actions[VerticalCenter]->setChecked(true);
215 break;
216 case Qt::AlignBottom:
217 m_actions[Bottom]->setChecked(true);
218 break;
219 default:
220 m_actions[VerticalNone]->setChecked(true);
221 break;
222 }
223 return true;
224}
225
227{
228 Qt::Alignment alignment;
229 if (const QAction *horizAction = m_horizGroup->checkedAction())
230 if (const int horizAlign = horizAction->data().toInt())
231 alignment |= static_cast<Qt::Alignment>(horizAlign);
232 if (const QAction *vertAction = m_verticalGroup->checkedAction())
233 if (const int vertAlign = vertAction->data().toInt())
234 alignment |= static_cast<Qt::Alignment>(vertAlign);
235 return alignment;
236}
237
238// -------------- QDesignerTaskMenuPrivate
271
273 m_q(nullptr),
282 m_changeObjectNameAction(new QAction(QDesignerTaskMenu::tr("Change objectName..."), parent)),
283 m_changeToolTip(new QAction(QDesignerTaskMenu::tr("Change toolTip..."), parent)),
284 m_changeWhatsThis(new QAction(QDesignerTaskMenu::tr("Change whatsThis..."), parent)),
285 m_changeStyleSheet(new QAction(QDesignerTaskMenu::tr("Change styleSheet..."), parent)),
288 m_addMenuBar(new QAction(QDesignerTaskMenu::tr("Create Menu Bar"), parent)),
289 m_addToolBar(new QAction(QDesignerTaskMenu::tr("Add Tool Bar"), parent)),
290 m_addAreaSubMenu(new QAction(QDesignerTaskMenu::tr("Add Tool Bar to Other Area"), parent)),
291 m_addStatusBar(new QAction(QDesignerTaskMenu::tr("Create Status Bar"), parent)),
292 m_removeStatusBar(new QAction(QDesignerTaskMenu::tr("Remove Status Bar"), parent)),
293 m_containerFakeMethods(new QAction(QDesignerTaskMenu::tr("Change signals/slots..."), parent)),
294 m_navigateToSlot(new QAction(QDesignerTaskMenu::tr("Go to slot..."), parent)),
298 m_sizeActionsSubMenu(new QAction(QDesignerTaskMenu::tr("Size Constraints"), parent))
299{
300 QMenu *sizeMenu = new QMenu;
301 m_sizeActionsSubMenu->setMenu(sizeMenu);
302 QAction *sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Width"));
303 sizeAction->setData(ApplyMinimumWidth);
304 sizeMenu->addAction(sizeAction);
305
306 sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Height"));
307 sizeAction->setData(ApplyMinimumHeight);
308 sizeMenu->addAction(sizeAction);
309
310 sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Minimum Size"));
311 sizeAction->setData(ApplyMinimumWidth|ApplyMinimumHeight);
312 sizeMenu->addAction(sizeAction);
313
314 sizeMenu->addSeparator();
315
316 sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Width"));
317 sizeAction->setData(ApplyMaximumWidth);
318 sizeMenu->addAction(sizeAction);
319
320 sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Height"));
321 sizeAction->setData(ApplyMaximumHeight);
322 sizeMenu->addAction(sizeAction);
323
324 sizeAction = m_sizeActionGroup->addAction(QDesignerTaskMenu::tr("Set Maximum Size"));
325 sizeAction->setData(ApplyMaximumWidth|ApplyMaximumHeight);
326 sizeMenu->addAction(sizeAction);
327}
328
329// --------- QDesignerTaskMenu
333{
334 d->m_q = this;
336
343 [this] () { this->addToolBar(Qt::TopToolBarArea); });
344 auto areaMenu = new QMenu;
346 areaMenu->addAction(QDesignerTaskMenu::tr("Left"), this,
347 [this] () { this->addToolBar(Qt::LeftToolBarArea); });
348 areaMenu->addAction(QDesignerTaskMenu::tr("Right"), this,
349 [this] () { this->addToolBar(Qt::RightToolBarArea); });
350 areaMenu->addAction(QDesignerTaskMenu::tr("Bottom"), this,
351 [this] () { this->addToolBar(Qt::BottomToolBarArea); });
359}
360
362{
363 delete d;
364}
365
370
372{
373 return d->m_widget;
374}
375
382
384{
387 if (!mw) {
388 // ### warning message
389 return;
390 }
391
393 cmd->init(mw);
395 }
396}
397
399{
402 if (!mw) {
403 // ### warning message
404 return;
405 }
406
408 cmd->init(mw, area);
410 }
411}
412
414{
417 if (!mw) {
418 // ### warning message
419 return;
420 }
421
423 cmd->init(mw);
425 }
426}
427
429{
432 if (!mw) {
433 // ### warning message
434 return;
435 }
436
440 }
441}
442
444{
447
448 const bool isMainContainer = formWindow->mainContainer() == widget();
449
451
453 if (isMainContainer || mw->centralWidget() == widget()) {
454 if (mw->findChild<QMenuBar *>(QString(), Qt::FindDirectChildrenOnly) == nullptr)
456
459 // ### create the status bar
462 else
464
466 }
467 }
479
483
487 }
488
492 }
493
494 return actions;
495}
496
498{
500 Q_ASSERT(fw != nullptr);
501
502 const QString oldObjectName = objName(fw->core(), widget());
503
505 if (dialog.exec() == QDialog::Accepted) {
510 setProperty(fw, CurrentWidgetMode, u"objectName"_s,
512 }
513 }
514}
515
517{
519 if (!fw)
520 return;
521 Q_ASSERT(d->m_widget->parentWidget() != nullptr);
522
524 const int index = sheet->indexOf(propertyName);
525 if (index == -1) {
526 qDebug() << "** WARNING Invalid property" << propertyName << " passed to changeTextProperty!";
527 return;
528 }
530 const QString oldText = textValue.value();
531 // Pop up respective dialog
532 bool accepted = false;
534 switch (desiredFormat) {
535 case Qt::PlainText: {
537 if (!windowTitle.isEmpty())
542 newText = dlg.text();
543 }
544 break;
545 default: {
547 if (!windowTitle.isEmpty())
553 }
554 break;
555 }
556 // change property
557 if (!accepted || oldText == newText)
558 return;
559
560
563}
564
566{
567 changeTextProperty(u"toolTip"_s, tr("Edit ToolTip"), MultiSelectionMode, Qt::AutoText);
568}
569
571{
572 changeTextProperty(u"whatsThis"_s, tr("Edit WhatsThis"), MultiSelectionMode, Qt::AutoText);
573}
574
576{
579 dlg.exec();
580 }
581}
582
584{
586 if (!fw)
587 return;
589}
590
595
597{
599 Q_ASSERT(core);
601}
602
605 const QString &defaultSignal)
606{
609 if (dialog.exec() != QDialog::Accepted)
610 return;
611 // TODO: Check whether signal is connected to slot
613 if (method.isValid()) {
617 }
618}
619
620// Add a command that takes over the value of the current geometry as
621// minimum/maximum size according to the flags.
622static void createSizeCommand(QDesignerFormWindowInterface *fw, QWidget *w, int flags)
623{
624 const QSize size = w->size();
626 QSize minimumSize = w-> minimumSize();
627 if (flags & ApplyMinimumWidth)
628 minimumSize.setWidth(size.width());
629 if (flags & ApplyMinimumHeight)
630 minimumSize.setHeight(size.height());
631 SetPropertyCommand* cmd = new SetPropertyCommand(fw);
632 cmd->init(w, u"minimumSize"_s, minimumSize);
633 fw->commandHistory()->push(cmd);
634 }
636 QSize maximumSize = w-> maximumSize();
637 if (flags & ApplyMaximumWidth)
638 maximumSize.setWidth(size.width());
639 if (flags & ApplyMaximumHeight)
640 maximumSize.setHeight(size.height());
641 SetPropertyCommand* cmd = new SetPropertyCommand(fw);
642 cmd->init(w, u"maximumSize"_s, maximumSize);
643 fw->commandHistory()->push(cmd);
644 }
645}
646
648{
650 if (!fw)
651 return;
652
654 if (selection.isEmpty())
655 return;
656
657 const int mask = a->data().toInt();
658 fw->commandHistory()->beginMacro(tr("Set size constraint on %n widget(s)", nullptr,
659 int(selection.size())));
660 for (auto *w : selection)
663}
664
665template <class Container>
666 static void getApplicableObjects(const QDesignerFormWindowInterface *fw, QWidget *current,
667 QDesignerTaskMenu::PropertyMode pm, Container *c)
668{
669 // Current is always first
670 c->push_back(current);
671 if (pm == QDesignerTaskMenu::CurrentWidgetMode)
672 return;
673 QDesignerObjectInspector *designerObjectInspector = qobject_cast<QDesignerObjectInspector *>(fw->core()->objectInspector());
674 if (!designerObjectInspector)
675 return; // Ooops, someone plugged an old-style Object Inspector
676 // Add managed or unmanaged selection according to current type, make current first
677 Selection s;
678 designerObjectInspector->getSelection(s);
679 const QWidgetList &source = fw->isManaged(current) ? s.managed : s.unmanaged;
680 for (auto *w : source) {
681 if (w != current) // was first
682 c->append(w);
683 }
684}
685
692
699
710
712{
716 if (cmd->init(d->m_widget, newAlignment)) {
718 } else {
719 delete cmd;
720 }
721}
722} // namespace qdesigner_internal
723
724QT_END_NAMESPACE
725
726#include "qdesigner_taskmenu.moc"
friend class QWidget
Definition qpainter.h:421
bool setAlignment(const QDesignerFormEditorInterface *core, QWidget *w)
QDesignerTaskMenuPrivate(QWidget *widget, QObject *parent)
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.
static void createSizeCommand(QDesignerFormWindowInterface *fw, QWidget *w, int flags)
static void getApplicableObjects(const QDesignerFormWindowInterface *fw, QWidget *current, QDesignerTaskMenu::PropertyMode pm, Container *c)
static QString objName(const QDesignerFormEditorInterface *core, QObject *object)
static QAction * createSeparatorHelper(QObject *parent)
@ ApplyMaximumWidth
@ ApplyMaximumHeight
@ ApplyMinimumHeight
@ ApplyMinimumWidth