VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupStack.cpp@ 82781

Last change on this file since 82781 was 80914, checked in by vboxsync, 5 years ago

FE/Qt: bugref:8938. Changing connection syntax in UILineTextEdit and UIPopupPane related classes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1/* $Id: UIPopupStack.cpp 80914 2019-09-20 06:16:55Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIPopupStack class implementation.
4 */
5
6/*
7 * Copyright (C) 2013-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QEvent>
20#include <QMainWindow>
21#include <QMenuBar>
22#include <QScrollArea>
23#include <QStatusBar>
24#include <QVBoxLayout>
25
26/* GUI includes: */
27#include "UICommon.h"
28#include "UIPopupStack.h"
29#include "UIPopupStackViewport.h"
30
31
32UIPopupStack::UIPopupStack(const QString &strID, UIPopupStackOrientation enmOrientation)
33 : m_strID(strID)
34 , m_enmOrientation(enmOrientation)
35 , m_pScrollArea(0)
36 , m_pScrollViewport(0)
37 , m_iParentMenuBarHeight(0)
38 , m_iParentStatusBarHeight(0)
39{
40 /* Prepare: */
41 prepare();
42}
43
44bool UIPopupStack::exists(const QString &strID) const
45{
46 /* Redirect question to viewport: */
47 return m_pScrollViewport->exists(strID);
48}
49
50void UIPopupStack::createPopupPane(const QString &strID,
51 const QString &strMessage, const QString &strDetails,
52 const QMap<int, QString> &buttonDescriptions)
53{
54 /* Redirect request to viewport: */
55 m_pScrollViewport->createPopupPane(strID,
56 strMessage, strDetails,
57 buttonDescriptions);
58
59 /* Propagate size: */
60 propagateSize();
61}
62
63void UIPopupStack::updatePopupPane(const QString &strID,
64 const QString &strMessage, const QString &strDetails)
65{
66 /* Redirect request to viewport: */
67 m_pScrollViewport->updatePopupPane(strID,
68 strMessage, strDetails);
69}
70
71void UIPopupStack::recallPopupPane(const QString &strID)
72{
73 /* Redirect request to viewport: */
74 m_pScrollViewport->recallPopupPane(strID);
75}
76
77void UIPopupStack::setOrientation(UIPopupStackOrientation enmOrientation)
78{
79 /* Make sure orientation has changed: */
80 if (m_enmOrientation == enmOrientation)
81 return;
82
83 /* Update orientation: */
84 m_enmOrientation = enmOrientation;
85 sltAdjustGeometry();
86}
87
88void UIPopupStack::setParent(QWidget *pParent)
89{
90 /* Call to base-class: */
91 QWidget::setParent(pParent);
92 /* Recalculate parent menu-bar height: */
93 m_iParentMenuBarHeight = parentMenuBarHeight(pParent);
94 /* Recalculate parent status-bar height: */
95 m_iParentStatusBarHeight = parentStatusBarHeight(pParent);
96}
97
98void UIPopupStack::setParent(QWidget *pParent, Qt::WindowFlags flags)
99{
100 /* Call to base-class: */
101 QWidget::setParent(pParent, flags);
102 /* Recalculate parent menu-bar height: */
103 m_iParentMenuBarHeight = parentMenuBarHeight(pParent);
104 /* Recalculate parent status-bar height: */
105 m_iParentStatusBarHeight = parentStatusBarHeight(pParent);
106}
107
108bool UIPopupStack::eventFilter(QObject *pWatched, QEvent *pEvent)
109{
110 /* Call to base-class if that is not parent event: */
111 if (!parent() || pWatched != parent())
112 return QWidget::eventFilter(pWatched, pEvent);
113
114 /* Handle parent geometry events: */
115 switch (pEvent->type())
116 {
117 case QEvent::Resize:
118 {
119 /* Propagate size: */
120 propagateSize();
121 /* Adjust geometry: */
122 sltAdjustGeometry();
123 break;
124 }
125 case QEvent::Move:
126 {
127 /* Adjust geometry: */
128 sltAdjustGeometry();
129 break;
130 }
131 default:
132 break; /* Shuts up MSC. */
133 }
134
135 /* Call to base-class: */
136 return QWidget::eventFilter(pWatched, pEvent);
137}
138
139void UIPopupStack::showEvent(QShowEvent*)
140{
141 /* Propagate size: */
142 propagateSize();
143 /* Adjust geometry: */
144 sltAdjustGeometry();
145}
146
147void UIPopupStack::sltAdjustGeometry()
148{
149 /* Make sure parent is currently set: */
150 if (!parent())
151 return;
152
153 /* Read parent geometry: */
154 QRect geo(parentWidget()->geometry());
155 if (!parentWidget()->isWindow())
156 geo.moveTo(parentWidget()->mapToGlobal(QPoint(0, 0)));
157
158 /* Determine size: */
159 int iWidth = parentWidget()->width();
160 int iHeight = parentWidget()->height();
161 /* Subtract menu-bar and status-bar heights: */
162 iHeight -= (m_iParentMenuBarHeight + m_iParentStatusBarHeight);
163 /* Check if minimum height is even less than current: */
164 if (m_pScrollViewport)
165 {
166 /* Get minimum viewport height: */
167 int iMinimumHeight = m_pScrollViewport->minimumSizeHint().height();
168 /* Subtract layout margins: */
169 int iLeft, iTop, iRight, iBottom;
170 m_pMainLayout->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
171 iMinimumHeight += (iTop + iBottom);
172 /* Compare minimum and current height: */
173 iHeight = qMin(iHeight, iMinimumHeight);
174 }
175
176 /* Determine origin: */
177 int iX = 0;
178 int iY = 0;
179 /* Shift for top-level window: */
180 if (isWindow())
181 {
182 iX += geo.x();
183 iY += geo.y();
184 }
185 switch (m_enmOrientation)
186 {
187 case UIPopupStackOrientation_Top:
188 {
189 /* Just add menu-bar height: */
190 iY += m_iParentMenuBarHeight;
191 break;
192 }
193 case UIPopupStackOrientation_Bottom:
194 {
195 /* Shift to bottom: */
196 iY += (geo.height() - iHeight);
197 /* And subtract status-bar height: */
198 iY -= m_iParentStatusBarHeight;
199 break;
200 }
201 }
202
203 /* Adjust geometry: */
204 UICommon::setTopLevelGeometry(this, iX, iY, iWidth, iHeight);
205}
206
207void UIPopupStack::sltPopupPaneRemoved(QString)
208{
209 /* Move focus to the parent: */
210 if (parentWidget())
211 parentWidget()->setFocus();
212}
213
214void UIPopupStack::sltPopupPanesRemoved()
215{
216 /* Ask popup-center to remove us: */
217 emit sigRemove(m_strID);
218}
219
220void UIPopupStack::prepare()
221{
222 /* Configure background: */
223 setAutoFillBackground(false);
224#if defined(VBOX_WS_WIN) || defined (VBOX_WS_MAC)
225 /* Using Qt API to enable translucent background for the Win/Mac host: */
226 setAttribute(Qt::WA_TranslucentBackground);
227#endif
228
229#ifdef VBOX_WS_MAC
230 /* Do not hide popup-stack: */
231 setAttribute(Qt::WA_MacAlwaysShowToolWindow);
232#endif
233
234 /* Prepare content: */
235 prepareContent();
236}
237
238void UIPopupStack::prepareContent()
239{
240 /* Create main-layout: */
241 m_pMainLayout = new QVBoxLayout(this);
242 {
243 /* Configure main-layout: */
244 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
245 /* Create scroll-area: */
246 m_pScrollArea = new QScrollArea;
247 {
248 /* Configure scroll-area: */
249 UICommon::setCursor(m_pScrollArea, Qt::ArrowCursor);
250 m_pScrollArea->setWidgetResizable(true);
251 m_pScrollArea->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
252 m_pScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
253 //m_pScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
254 QPalette pal = m_pScrollArea->palette();
255 pal.setColor(QPalette::Window, QColor(Qt::transparent));
256 m_pScrollArea->setPalette(pal);
257 /* Create scroll-viewport: */
258 m_pScrollViewport = new UIPopupStackViewport;
259 {
260 /* Configure scroll-viewport: */
261 UICommon::setCursor(m_pScrollViewport, Qt::ArrowCursor);
262 /* Connect scroll-viewport: */
263 connect(this, &UIPopupStack::sigProposeStackViewportSize,
264 m_pScrollViewport, &UIPopupStackViewport::sltHandleProposalForSize);
265 connect(m_pScrollViewport, &UIPopupStackViewport::sigSizeHintChanged,
266 this, &UIPopupStack::sltAdjustGeometry);
267 connect(m_pScrollViewport, &UIPopupStackViewport::sigPopupPaneDone,
268 this, &UIPopupStack::sigPopupPaneDone);
269 connect(m_pScrollViewport, &UIPopupStackViewport::sigPopupPaneRemoved,
270 this, &UIPopupStack::sltPopupPaneRemoved);
271 connect(m_pScrollViewport, &UIPopupStackViewport::sigPopupPanesRemoved,
272 this, &UIPopupStack::sltPopupPanesRemoved);
273 }
274 /* Assign scroll-viewport to scroll-area: */
275 m_pScrollArea->setWidget(m_pScrollViewport);
276 }
277 /* Add scroll-area to layout: */
278 m_pMainLayout->addWidget(m_pScrollArea);
279 }
280}
281
282void UIPopupStack::propagateSize()
283{
284 /* Make sure parent is currently set: */
285 if (!parent())
286 return;
287
288 /* Get parent size: */
289 QSize newSize = parentWidget()->size();
290 /* Subtract left/right layout margins: */
291 if (m_pMainLayout)
292 {
293 int iLeft, iTop, iRight, iBottom;
294 m_pMainLayout->getContentsMargins(&iLeft, &iTop, &iRight, &iBottom);
295 newSize.setWidth(newSize.width() - (iLeft + iRight));
296 newSize.setHeight(newSize.height() - (iTop + iBottom));
297 }
298 /* Subtract scroll-area frame-width: */
299 if (m_pScrollArea)
300 {
301 newSize.setWidth(newSize.width() - (2 * m_pScrollArea->frameWidth()));
302 newSize.setHeight(newSize.height() - (2 * m_pScrollArea->frameWidth()));
303 }
304 newSize.setHeight(newSize.height() - (m_iParentMenuBarHeight + m_iParentStatusBarHeight));
305
306 /* Propose resulting size to viewport: */
307 emit sigProposeStackViewportSize(newSize);
308}
309
310/* static */
311int UIPopupStack::parentMenuBarHeight(QWidget *pParent)
312{
313 /* Menu-bar can exist only on QMainWindow sub-class: */
314 if (pParent)
315 {
316 if (QMainWindow *pMainWindow = qobject_cast<QMainWindow*>(pParent))
317 {
318 /* Search for existing menu-bar child: */
319 if (QMenuBar *pMenuBar = pMainWindow->findChild<QMenuBar*>())
320 return pMenuBar->height();
321 }
322 }
323 /* Zero by default: */
324 return 0;
325}
326
327/* static */
328int UIPopupStack::parentStatusBarHeight(QWidget *pParent)
329{
330 /* Status-bar can exist only on QMainWindow sub-class: */
331 if (pParent)
332 {
333 if (QMainWindow *pMainWindow = qobject_cast<QMainWindow*>(pParent))
334 {
335 /* Search for existing status-bar child: */
336 if (QStatusBar *pStatusBar = pMainWindow->findChild<QStatusBar*>())
337 if (pStatusBar->isVisible())
338 return pStatusBar->height();
339
340 }
341 }
342 /* Zero by default: */
343 return 0;
344}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use