VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/globals/UIModalWindowManager.cpp

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 KB
RevLine 
[26714]1/* $Id: UIModalWindowManager.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
[25177]2/** @file
[52727]3 * VBox Qt GUI - UIModalWindowManager class implementation.
[25177]4 */
5
6/*
[98103]7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
[25177]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[25177]26 */
27
[41587]28/* GUI includes: */
[76606]29#include "UIModalWindowManager.h"
30#ifdef VBOX_GUI_WITH_NETWORK_MANAGER
[86996]31# include "UINetworkRequestManager.h"
[76606]32#endif
33#include "UIProgressDialog.h"
[25177]34
[41587]35/* Other VBox includes: */
[76606]36#include <VBox/sup.h>
[41587]37
[52730]38
[45183]39/* static */
[71373]40UIModalWindowManager *UIModalWindowManager::s_pInstance = 0;
41UIModalWindowManager *UIModalWindowManager::instance() { return s_pInstance; }
[45183]42
43/* static */
44void UIModalWindowManager::create()
[45160]45{
[45452]46 /* Make sure instance is NOT created yet: */
[71373]47 if (s_pInstance)
[45452]48 {
49 AssertMsgFailed(("UIModalWindowManager instance is already created!"));
[45183]50 return;
[45452]51 }
[45160]52
[45183]53 /* Create instance: */
54 new UIModalWindowManager;
55}
[45160]56
[45183]57/* static */
58void UIModalWindowManager::destroy()
59{
[45452]60 /* Make sure instance is NOT destroyed yet: */
[71373]61 if (!s_pInstance)
[45452]62 {
63 AssertMsgFailed(("UIModalWindowManager instance is already destroyed!"));
[45183]64 return;
[45452]65 }
[45160]66
[45452]67 /* Destroy instance: */
[71373]68 delete s_pInstance;
[45183]69}
[45160]70
[45183]71UIModalWindowManager::UIModalWindowManager()
[71375]72 : m_pMainWindowShown(0)
[45183]73{
[45452]74 /* Assign instance: */
[71373]75 s_pInstance = this;
[45183]76}
[45160]77
[45183]78UIModalWindowManager::~UIModalWindowManager()
79{
[45452]80 /* Unassign instance: */
[71373]81 s_pInstance = 0;
[45183]82}
[45160]83
[71373]84QWidget *UIModalWindowManager::realParentWindow(QWidget *pWidget)
[45160]85{
[45183]86 /* Null if widget pointer is null: */
87 if (!pWidget)
[45160]88 return 0;
89
[45183]90 /* Get the top-level window for the passed-widget: */
91 QWidget *pTopLevelWindow = pWidget->window();
[45160]92
93 /* Search through all the stack(s) we have: */
94 foreach (const QList<QWidget*> &iteratedWindowStack, m_windows)
95 {
96 /* Search through all the window(s) iterated-stack contains: */
97 foreach (QWidget *pIteratedWindow, iteratedWindowStack)
98 {
99 /* If possible-parent-window found: */
[45183]100 if (pIteratedWindow == pTopLevelWindow)
[45160]101 {
102 /* Return the 'top' of the iterated-window-stack as the result: */
[47612]103 QWidget *pTopWindow = iteratedWindowStack.last();
104 preprocessRealParent(pTopWindow);
105 return pTopWindow;
[45160]106 }
107 }
108 }
109
110 /* If we unable to found the possible-parent-window among all ours,
111 * we have to add it as the new-window-stack only element: */
[47612]112 registerNewParent(pTopLevelWindow);
[45160]113 /* And return as the result: */
[45183]114 return pTopLevelWindow;
[45160]115}
116
[45183]117bool UIModalWindowManager::isWindowInTheModalWindowStack(QWidget *pWindow)
[45160]118{
[45183]119 return contains(pWindow);
120}
[45160]121
[45183]122bool UIModalWindowManager::isWindowOnTheTopOfTheModalWindowStack(QWidget *pWindow)
123{
124 return contains(pWindow, true);
[45160]125}
126
[71373]127void UIModalWindowManager::registerNewParent(QWidget *pWindow, QWidget *pParentWindow /* = 0 */)
[45160]128{
129 /* Make sure passed-widget-pointer is not null: */
130 if (!pWindow)
131 {
132 AssertMsgFailed(("Passed pointer is NULL!"));
133 return;
134 }
135
136 /* Make sure passed-widget is of 'top-level window' type: */
137 if (!pWindow->isWindow())
138 {
139 AssertMsgFailed(("Passed widget is NOT top-level window!"));
140 return;
141 }
142
143 /* Make sure passed-parent-widget is of 'top-level window' type: */
144 if (pParentWindow && !pParentWindow->isWindow())
145 {
146 AssertMsgFailed(("Passed parent widget is NOT top-level window!"));
147 return;
148 }
149
150 /* If parent-window really passed: */
151 if (pParentWindow)
152 {
153 /* Make sure we have passed-parent-window registered already.
154 * If so, we have to make sure its the 'top' element in his stack also.
155 * If so, we have to register passed-window as the new 'top' in that stack. */
156 for (int iIteratedStackIndex = 0; iIteratedStackIndex < m_windows.size(); ++iIteratedStackIndex)
157 {
158 /* Get current-stack: */
159 QList<QWidget*> &iteratedWindowStack = m_windows[iIteratedStackIndex];
160 /* Search through all the window(s) iterated-stack contains: */
161 int iIteratedWindwStackSize = iteratedWindowStack.size();
162 for (int iIteratedWindowIndex = 0; iIteratedWindowIndex < iIteratedWindwStackSize; ++iIteratedWindowIndex)
163 {
164 /* Get iterated-window: */
165 QWidget *pIteratedWindow = iteratedWindowStack[iIteratedWindowIndex];
166 /* If passed-parent-window found: */
167 if (pIteratedWindow == pParentWindow)
168 {
169 /* Make sure it was the last one of the iterated-window(s): */
170 if (iIteratedWindowIndex != iIteratedWindwStackSize - 1)
171 {
172 AssertMsgFailed(("Passed parent window is not on the top of his current-stack!"));
173 return;
174 }
175 /* Register passed-window as the new 'top' in iterated-window-stack: */
176 iteratedWindowStack << pWindow;
[68190]177 connect(pWindow, &QWidget::destroyed, this, &UIModalWindowManager::sltRemoveFromStack);
[45160]178 return;
179 }
180 }
181 }
[45183]182 /* Passed-parent-window was not found: */
183 AssertMsgFailed(("Passed parent window is not registered!"));
184 return;
[45160]185 }
186 /* If no parent-window passed: */
187 else
188 {
189 /* Register passed-window as the only one item in new-window-stack: */
190 QList<QWidget*> newWindowStack(QList<QWidget*>() << pWindow);
191 m_windows << newWindowStack;
[68190]192 connect(pWindow, &QWidget::destroyed, this, &UIModalWindowManager::sltRemoveFromStack);
[45160]193 }
[69003]194
195 /* Notify listeners that their stack may have changed: */
196 emit sigStackChanged();
[45160]197}
198
[45183]199void UIModalWindowManager::sltRemoveFromStack(QObject *pObject)
[45160]200{
201 /* Make sure passed-object still valid: */
202 if (!pObject)
203 return;
204
205 /* Object is already of QObject type,
206 * because inheritance wrapper(s) destructor(s) already called
207 * so we can't search through the m_windows stack
208 * using the standard algorithm functionality.
209 * Lets do it manually: */
210 for (int iIteratedStackIndex = 0; iIteratedStackIndex < m_windows.size(); ++iIteratedStackIndex)
211 {
212 /* Get iterated-stack: */
213 QList<QWidget*> &iteratedWindowStack = m_windows[iIteratedStackIndex];
214 /* Search through all the window(s) iterated-stack contains: */
215 int iIteratedWindowStackSize = iteratedWindowStack.size();
216 for (int iIteratedWindowIndex = 0; iIteratedWindowIndex < iIteratedWindowStackSize; ++iIteratedWindowIndex)
217 {
218 /* Get iterated-window: */
219 QWidget *pIteratedWindow = iteratedWindowStack[iIteratedWindowIndex];
220 /* If passed-object is almost-destroyed iterated-window: */
221 if (pIteratedWindow == pObject)
222 {
223 /* Make sure it was the last added window: */
224 AssertMsg(iIteratedWindowIndex == iIteratedWindowStackSize - 1, ("Removing element from the middle of the stack!"));
225 /* Cleanup window pointer: */
226 iteratedWindowStack.removeAt(iIteratedWindowIndex);
227 /* And stack itself if necessary: */
228 if (iteratedWindowStack.isEmpty())
229 m_windows.removeAt(iIteratedStackIndex);
230 }
231 }
232 }
[69003]233
234 /* Notify listeners that their stack may have changed: */
235 emit sigStackChanged();
[45160]236}
237
[71373]238bool UIModalWindowManager::contains(QWidget *pParentWindow, bool fAsTheTopOfStack /* = false */)
[32296]239{
[45183]240 /* False if passed-parent-widget pointer is null: */
241 if (!pParentWindow)
[25177]242 {
[45183]243 AssertMsgFailed(("Passed pointer is NULL!"));
244 return false;
[25177]245 }
246
[45183]247 /* False if passed-parent-widget is not of 'top-level window' type: */
248 if (!pParentWindow->isWindow())
[25177]249 {
[45183]250 AssertMsgFailed(("Passed widget is NOT top-level window!"));
251 return false;
[25177]252 }
253
[45183]254 /* Search through all the stack(s) we have: */
255 foreach (const QList<QWidget*> &iteratedWindowStack, m_windows)
[25177]256 {
[45183]257 /* Search through all the window(s) iterated-stack contains: */
258 int iIteratedWindowStackSize = iteratedWindowStack.size();
259 for (int iIteratedWidnowIndex = 0; iIteratedWidnowIndex < iIteratedWindowStackSize; ++iIteratedWidnowIndex)
[25177]260 {
[45183]261 /* Get iterated-window: */
262 QWidget *pIteratedWindow = iteratedWindowStack[iIteratedWidnowIndex];
263 /* If passed-parent-window found: */
264 if (pIteratedWindow == pParentWindow)
[32334]265 {
[45183]266 /* True if we are not looking for 'top' of the stack or its the 'top': */
267 return !fAsTheTopOfStack || iIteratedWidnowIndex == iIteratedWindowStackSize - 1;
[32334]268 }
269 }
[25177]270 }
[39096]271
[45183]272 /* False by default: */
273 return false;
[25177]274}
275
[47612]276/* static */
277void UIModalWindowManager::preprocessRealParent(QWidget *pParent)
278{
279 /* Progress dialog can be hidden while we are trying to use it as top-most modal parent,
280 * We should show it in such cases because else on MacOS X there will be a problem. */
281 if (UIProgressDialog *pProgressDialog = qobject_cast<UIProgressDialog*>(pParent))
282 pProgressDialog->show();
283}
284
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use