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
containerwidget_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// Qt-Security score:significant reason:default
4
6
7#include <QtDesigner/abstractformeditor.h>
8#include <QtDesigner/abstractformwindow.h>
9#include <QtDesigner/qextensionmanager.h>
10#include <QtDesigner/container.h>
11
12#include <qdesigner_command_p.h>
13#include <qdesigner_dockwidget_p.h>
14#include <promotiontaskmenu_p.h>
15#include <widgetdatabase_p.h>
16
17#include <QtWidgets/qmainwindow.h>
18#include <QtWidgets/qtoolbox.h>
19#include <QtWidgets/qstackedwidget.h>
20#include <QtWidgets/qtabwidget.h>
21#include <QtWidgets/qscrollarea.h>
22#include <QtWidgets/qmdiarea.h>
23#include <QtWidgets/qwizard.h>
24#include <QtWidgets/qmenu.h>
25
26#include <QtGui/qaction.h>
27
28#include <QtCore/qdebug.h>
29
31
32using namespace Qt::StringLiterals;
33
34namespace qdesigner_internal {
35
36ContainerWidgetTaskMenu::ContainerWidgetTaskMenu(QWidget *widget, ContainerType type, QObject *parent) :
37 QDesignerTaskMenu(widget, parent),
38 m_type(type),
39 m_containerWidget(widget),
40 m_core(formWindow()->core()),
41 m_pagePromotionTaskMenu(new PromotionTaskMenu(nullptr, PromotionTaskMenu::ModeSingleWidget, this)),
42 m_pageMenuAction(new QAction(this)),
43 m_pageMenu(new QMenu),
44 m_actionInsertPageAfter(new QAction(this)),
45 m_actionInsertPage(nullptr),
46 m_actionDeletePage(new QAction(tr("Delete"), this))
47{
48 Q_ASSERT(m_core);
49 m_taskActions.append(createSeparator());
50
51 connect(m_actionDeletePage, &QAction::triggered, this, &ContainerWidgetTaskMenu::removeCurrentPage);
52
53 connect(m_actionInsertPageAfter, &QAction::triggered, this, &ContainerWidgetTaskMenu::addPageAfter);
54 // Empty Per-Page submenu, deletion and promotion. Updated on demand due to promotion state
55 switch (m_type) {
56 case WizardContainer:
57 case PageContainer:
58 m_taskActions.append(createSeparator()); // for the browse actions
59 break;
60 case MdiContainer:
61 break;
62 }
63 // submenu
64 m_pageMenuAction->setMenu(m_pageMenu);
65 m_taskActions.append(m_pageMenuAction);
66 // Insertion
67 switch (m_type) {
68 case WizardContainer:
69 case PageContainer: { // Before and after in a submenu
70 QAction *insertMenuAction = new QAction(tr("Insert"), this);
71 QMenu *insertMenu = new QMenu;
72 // before
73 m_actionInsertPage = new QAction(tr("Insert Page Before Current Page"), this);
74 connect(m_actionInsertPage, &QAction::triggered, this, &ContainerWidgetTaskMenu::addPage);
75 insertMenu->addAction(m_actionInsertPage);
76 // after
77 m_actionInsertPageAfter->setText(tr("Insert Page After Current Page"));
78 insertMenu->addAction(m_actionInsertPageAfter);
79
80 insertMenuAction->setMenu(insertMenu);
81 m_taskActions.append(insertMenuAction);
82 }
83 break;
84 case MdiContainer: // No concept of order
85 m_actionInsertPageAfter->setText(tr("Add Subwindow"));
86 m_taskActions.append(m_actionInsertPageAfter);
87 break;
88 }
89}
90
92
94{
95 return nullptr;
96}
97
98bool ContainerWidgetTaskMenu::canDeletePage() const
99{
100 switch (pageCount()) {
101 case 0:
102 return false;
103 case 1:
104 return m_type != PageContainer; // Do not delete last page of page-type container
105 default:
106 break;
107 }
108 return true;
109}
110
112{
114 return ce->count();
115 return 0;
116}
117
118QString ContainerWidgetTaskMenu::pageMenuText(ContainerType ct, int index, int count)
119{
120 if (ct == MdiContainer)
121 return tr("Subwindow"); // No concept of order, same text everywhere
122 if (index < 0)
123 return tr("Page");
124 return tr("Page %1 of %2").arg(index + 1).arg(count);
125}
126
128{
130 const int index = ce->currentIndex();
131
132 auto actions = QDesignerTaskMenu::taskActions();
133 actions += m_taskActions;
134 // Update the page submenu, deletion and promotion. Updated on demand due to promotion state.
135 m_pageMenu->clear();
136 const bool canAddWidget = ce->canAddWidget();
137 if (m_actionInsertPage)
138 m_actionInsertPage->setEnabled(canAddWidget);
139 m_actionInsertPageAfter->setEnabled(canAddWidget);
140 m_pageMenu->addAction(m_actionDeletePage);
141 m_actionDeletePage->setEnabled(index >= 0 && ce->canRemove(index) && canDeletePage());
142 m_pageMenuAction->setText(pageMenuText(m_type, index, ce->count()));
143 if (index != -1) { // Has a page
144 m_pageMenuAction->setEnabled(true);
145 m_pagePromotionTaskMenu->setWidget(ce->widget(index));
146 m_pagePromotionTaskMenu->addActions(PromotionTaskMenu::LeadingSeparator|PromotionTaskMenu::SuppressGlobalEdit, m_pageMenu);
147 } else { // No page
148 m_pageMenuAction->setEnabled(false);
149 }
150
151 return actions;
152}
153
154QDesignerFormWindowInterface *ContainerWidgetTaskMenu::formWindow() const
155{
156 return QDesignerFormWindowInterface::findFormWindow(m_containerWidget);
157}
158
160{
161 QExtensionManager *mgr = m_core->extensionManager();
162 return qt_extension<QDesignerContainerExtension*>(mgr, m_containerWidget);
163}
164
165void ContainerWidgetTaskMenu::removeCurrentPage()
166{
168 if (c->currentIndex() == -1)
169 return;
170
171 QDesignerFormWindowInterface *fw = formWindow();
172 DeleteContainerWidgetPageCommand *cmd = new DeleteContainerWidgetPageCommand(fw);
173 cmd->init(m_containerWidget, m_type);
174 fw->commandHistory()->push(cmd);
175 }
176}
177
178void ContainerWidgetTaskMenu::addPage()
179{
181 QDesignerFormWindowInterface *fw = formWindow();
182 AddContainerWidgetPageCommand *cmd = new AddContainerWidgetPageCommand(fw);
183 cmd->init(m_containerWidget, m_type, AddContainerWidgetPageCommand::InsertBefore);
184 fw->commandHistory()->push(cmd);
185 }
186}
187
188void ContainerWidgetTaskMenu::addPageAfter()
189{
191 QDesignerFormWindowInterface *fw = formWindow();
192 AddContainerWidgetPageCommand *cmd = new AddContainerWidgetPageCommand(fw);
193 cmd->init(m_containerWidget, m_type, AddContainerWidgetPageCommand::InsertAfter);
194 fw->commandHistory()->push(cmd);
195 }
196}
197
198// -------------- WizardContainerWidgetTaskMenu
199WizardContainerWidgetTaskMenu::WizardContainerWidgetTaskMenu(QWizard *w, QObject *parent) :
201 m_nextAction(new QAction(tr("Next"), this)),
202 m_previousAction(new QAction(tr("Back"), this))
203{
204 connect(m_nextAction, &QAction::triggered, w, &QWizard::next);
205 connect(m_previousAction, &QAction::triggered, w, &QWizard::back);
206 auto &l = containerActions();
207 l.push_front(createSeparator());
208 l.push_front(m_nextAction);
209 l.push_front(m_previousAction);
210 l.push_front(createSeparator());
211}
212
214{
215 // Enable
217 const int index = ce->currentIndex();
218 m_previousAction->setEnabled(index > 0);
219 m_nextAction->setEnabled(index >= 0 && index < (ce->count() - 1));
220 return ContainerWidgetTaskMenu::taskActions();
221}
222
223// -------------- MdiContainerWidgetTaskMenu
224
225MdiContainerWidgetTaskMenu::MdiContainerWidgetTaskMenu(QMdiArea *m, QObject *parent) :
227{
228 initializeActions();
229 connect(m_nextAction, &QAction::triggered, m, &QMdiArea::activateNextSubWindow);
230 connect(m_previousAction, &QAction::triggered, m , &QMdiArea::activatePreviousSubWindow);
231 connect(m_tileAction, &QAction::triggered, m, &QMdiArea::tileSubWindows);
232 connect(m_cascadeAction, &QAction::triggered, m, &QMdiArea::cascadeSubWindows);
233}
234
235void MdiContainerWidgetTaskMenu::initializeActions()
236{
237 m_nextAction =new QAction(tr("Next Subwindow"), this);
238 m_previousAction = new QAction(tr("Previous Subwindow"), this);
239 m_tileAction = new QAction(tr("Tile"), this);
240 m_cascadeAction = new QAction(tr("Cascade"), this);
241
242 auto &l = containerActions();
243 l.push_front(createSeparator());
244 l.push_front(m_tileAction);
245 l.push_front(m_cascadeAction);
246 l.push_front(m_previousAction);
247 l.push_front(m_nextAction);
248 l.push_front(createSeparator());
249}
250
252{
253 const auto rc = ContainerWidgetTaskMenu::taskActions();
254 // Enable
255 const int count = pageCount();
256 m_nextAction->setEnabled(count > 1);
257 m_previousAction->setEnabled(count > 1);
258 m_tileAction->setEnabled(count);
259 m_cascadeAction->setEnabled(count);
260 return rc;
261}
262
263// -------------- ContainerWidgetTaskMenuFactory
264
265ContainerWidgetTaskMenuFactory::ContainerWidgetTaskMenuFactory(QDesignerFormEditorInterface *core, QExtensionManager *extensionManager) :
266 QExtensionFactory(extensionManager),
267 m_core(core)
268{
269}
270
271QObject *ContainerWidgetTaskMenuFactory::createExtension(QObject *object, const QString &iid, QObject *parent) const
272{
273 if (iid != "QDesignerInternalTaskMenuExtension"_L1 || !object->isWidgetType())
274 return nullptr;
275
276 QWidget *widget = qobject_cast<QWidget*>(object);
277
278 if (qobject_cast<QStackedWidget*>(widget)
279 || qobject_cast<QToolBox*>(widget)
280 || qobject_cast<QTabWidget*>(widget)
281 || qobject_cast<QMainWindow*>(widget)) {
282 // Are we using Designer's own container extensions and task menus or did
283 // someone provide an extra one with an addpage method, for example for a QScrollArea?
284 if (const WidgetDataBase *wb = qobject_cast<const WidgetDataBase *>(m_core->widgetDataBase())) {
285 const int idx = wb->indexOfObject(widget);
286 const WidgetDataBaseItem *item = static_cast<const WidgetDataBaseItem *>(wb->item(idx));
287 if (item->addPageMethod().isEmpty())
288 return nullptr;
289 }
290 }
291
292 if (qt_extension<QDesignerContainerExtension*>(extensionManager(), object) == nullptr)
293 return nullptr;
294
295 if (QMdiArea* ma = qobject_cast<QMdiArea*>(widget))
296 return new MdiContainerWidgetTaskMenu(ma, parent);
297 if (QWizard *wz = qobject_cast<QWizard *>(widget))
298 return new WizardContainerWidgetTaskMenu(wz, parent);
299 return new ContainerWidgetTaskMenu(widget, PageContainer, parent);
300}
301
302}
303QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:432
QDesignerContainerExtension * containerExtension() const
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.