VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/runtime/scale/UIMachineWindowScale.cpp@ 35740

Last change on this file since 35740 was 35424, checked in by vboxsync, 13 years ago

FE/Qt4: change the layout of the beta label and add it to the VM window

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 KB
Line 
1/* $Id: UIMachineWindowScale.cpp 35424 2011-01-07 13:05:41Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * UIMachineWindowScale class implementation
6 */
7
8/*
9 * Copyright (C) 2010 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Global includes */
21#include <QDesktopWidget>
22#include <QMenuBar>
23#include <QTimer>
24#include <QContextMenuEvent>
25
26/* Local includes */
27#include "VBoxGlobal.h"
28#include "VBoxProblemReporter.h"
29#include "VBoxUtils.h"
30
31#include "UISession.h"
32#include "UIActionsPool.h"
33#include "UIMachineLogic.h"
34#include "UIMachineView.h"
35#include "UIMachineWindowScale.h"
36#ifdef Q_WS_MAC
37# include "UIImageTools.h"
38#endif /* Q_WS_MAC */
39
40UIMachineWindowScale::UIMachineWindowScale(UIMachineLogic *pMachineLogic, ulong uScreenId)
41 : QIWithRetranslateUI2<QMainWindow>(0, Qt::Window)
42 , UIMachineWindow(pMachineLogic, uScreenId)
43 , m_pMainMenu(0)
44{
45 /* "This" is machine window: */
46 m_pMachineWindow = this;
47
48 /* Set the main window in VBoxGlobal */
49 if (uScreenId == 0)
50 vboxGlobal().setMainWindow(this);
51
52 /* Prepare window icon: */
53 prepareWindowIcon();
54
55 /* Prepare console connections: */
56 prepareConsoleConnections();
57
58 /* Prepare menu: */
59 prepareMenu();
60
61 /* Retranslate normal window finally: */
62 retranslateUi();
63
64 /* Prepare normal machine view container: */
65 prepareMachineViewContainer();
66
67 /* Prepare normal machine view: */
68 prepareMachineView();
69
70 /* Prepare handlers: */
71 prepareHandlers();
72
73 /* Load normal window settings: */
74 loadWindowSettings();
75
76 /* Update all the elements: */
77 updateAppearanceOf(UIVisualElement_AllStuff);
78
79#ifdef Q_WS_MAC
80 /* Beta label? */
81 if (vboxGlobal().isBeta())
82 {
83 QPixmap betaLabel = ::betaLabel(QSize(100, 16));
84 ::darwinLabelWindow(this, &betaLabel, true);
85 }
86#endif /* Q_WS_MAC */
87
88
89 /* Show window: */
90 showSimple();
91}
92
93UIMachineWindowScale::~UIMachineWindowScale()
94{
95 /* Save normal window settings: */
96 saveWindowSettings();
97
98 /* Prepare handlers: */
99 cleanupHandlers();
100
101 /* Cleanup normal machine view: */
102 cleanupMachineView();
103}
104
105void UIMachineWindowScale::sltMachineStateChanged()
106{
107 UIMachineWindow::sltMachineStateChanged();
108}
109
110void UIMachineWindowScale::sltPopupMainMenu()
111{
112 /* Popup main menu if present: */
113 if (m_pMainMenu && !m_pMainMenu->isEmpty())
114 {
115 m_pMainMenu->popup(machineWindow()->geometry().center());
116 QTimer::singleShot(0, m_pMainMenu, SLOT(sltSelectFirstAction()));
117 }
118}
119
120void UIMachineWindowScale::sltTryClose()
121{
122 UIMachineWindow::sltTryClose();
123}
124
125void UIMachineWindowScale::retranslateUi()
126{
127 /* Translate parent class: */
128 UIMachineWindow::retranslateUi();
129}
130
131bool UIMachineWindowScale::event(QEvent *pEvent)
132{
133 switch (pEvent->type())
134 {
135 case QEvent::Resize:
136 {
137 QResizeEvent *pResizeEvent = static_cast<QResizeEvent*>(pEvent);
138 if (!isMaximizedChecked())
139 {
140 m_normalGeometry.setSize(pResizeEvent->size());
141#ifdef VBOX_WITH_DEBUGGER_GUI
142 /* Update debugger window position */
143 updateDbgWindows();
144#endif
145 }
146 break;
147 }
148 case QEvent::Move:
149 {
150 if (!isMaximizedChecked())
151 {
152 m_normalGeometry.moveTo(geometry().x(), geometry().y());
153#ifdef VBOX_WITH_DEBUGGER_GUI
154 /* Update debugger window position */
155 updateDbgWindows();
156#endif
157 }
158 break;
159 }
160 default:
161 break;
162 }
163 return QIWithRetranslateUI2<QMainWindow>::event(pEvent);
164}
165
166#ifdef Q_WS_WIN
167bool UIMachineWindowScale::winEvent(MSG *pMessage, long *pResult)
168{
169 /* Try to keep aspect ratio during window resize if:
170 * 1. machine view exists and 2. event-type is WM_SIZING and 3. shift key is NOT pressed: */
171 if (machineView() && pMessage->message == WM_SIZING && !(QApplication::keyboardModifiers() & Qt::ShiftModifier))
172 {
173 if (double dAspectRatio = machineView()->aspectRatio())
174 {
175 RECT *pRect = reinterpret_cast<RECT*>(pMessage->lParam);
176 switch (pMessage->wParam)
177 {
178 case WMSZ_LEFT:
179 case WMSZ_RIGHT:
180 {
181 pRect->bottom = pRect->top + (double)(pRect->right - pRect->left) / dAspectRatio;
182 break;
183 }
184 case WMSZ_TOP:
185 case WMSZ_BOTTOM:
186 {
187 pRect->right = pRect->left + (double)(pRect->bottom - pRect->top) * dAspectRatio;
188 break;
189 }
190 case WMSZ_BOTTOMLEFT:
191 case WMSZ_BOTTOMRIGHT:
192 {
193 pRect->bottom = pRect->top + (double)(pRect->right - pRect->left) / dAspectRatio;
194 break;
195 }
196 case WMSZ_TOPLEFT:
197 case WMSZ_TOPRIGHT:
198 {
199 pRect->top = pRect->bottom - (double)(pRect->right - pRect->left) / dAspectRatio;
200 break;
201 }
202 default:
203 break;
204 }
205 }
206 }
207 /* Pass event to base-class: */
208 return QMainWindow::winEvent(pMessage, pResult);
209}
210#endif /* Q_WS_WIN */
211
212#ifdef Q_WS_X11
213bool UIMachineWindowScale::x11Event(XEvent *pEvent)
214{
215 return UIMachineWindow::x11Event(pEvent);
216}
217#endif
218
219void UIMachineWindowScale::closeEvent(QCloseEvent *pEvent)
220{
221 return UIMachineWindow::closeEvent(pEvent);
222}
223
224void UIMachineWindowScale::prepareMenu()
225{
226 UIMainMenuType fMenus = UIMainMenuType(UIMainMenuType_All ^ UIMainMenuType_View);
227#ifdef Q_WS_MAC
228 setMenuBar(uisession()->newMenuBar(fMenus));
229#endif /* Q_WS_MAC */
230 /* No view menu in normal mode: */
231 m_pMainMenu = uisession()->newMenu(fMenus);
232}
233
234void UIMachineWindowScale::prepareMachineViewContainer()
235{
236 /* Call to base-class: */
237 UIMachineWindow::prepareMachineViewContainer();
238
239 /* Strict spacers to hide them, they are not necessary for scale-mode: */
240 m_pTopSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
241 m_pBottomSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
242 m_pLeftSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
243 m_pRightSpacer->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
244}
245
246void UIMachineWindowScale::prepareMachineView()
247{
248#ifdef VBOX_WITH_VIDEOHWACCEL
249 /* Need to force the QGL framebuffer in case 2D Video Acceleration is supported & enabled: */
250 bool bAccelerate2DVideo = session().GetMachine().GetAccelerate2DVideoEnabled() && VBoxGlobal::isAcceleration2DVideoAvailable();
251#endif
252
253 /* Set central widget: */
254 setCentralWidget(new QWidget);
255
256 /* Set central widget layout: */
257 centralWidget()->setLayout(m_pMachineViewContainer);
258
259 m_pMachineView = UIMachineView::create( this
260 , m_uScreenId
261 , machineLogic()->visualStateType()
262#ifdef VBOX_WITH_VIDEOHWACCEL
263 , bAccelerate2DVideo
264#endif
265 );
266
267 /* Add machine view into layout: */
268 m_pMachineViewContainer->addWidget(m_pMachineView, 1, 1);
269}
270
271void UIMachineWindowScale::loadWindowSettings()
272{
273 /* Load scale window settings: */
274 CMachine machine = session().GetMachine();
275
276 /* Load extra-data settings: */
277 {
278 QString strPositionAddress = m_uScreenId == 0 ? QString("%1").arg(VBoxDefs::GUI_LastScaleWindowPosition) :
279 QString("%1%2").arg(VBoxDefs::GUI_LastScaleWindowPosition).arg(m_uScreenId);
280 QStringList strPositionSettings = machine.GetExtraDataStringList(strPositionAddress);
281
282 bool ok = !strPositionSettings.isEmpty(), max = false;
283 int x = 0, y = 0, w = 0, h = 0;
284
285 if (ok && strPositionSettings.size() > 0)
286 x = strPositionSettings[0].toInt(&ok);
287 else ok = false;
288 if (ok && strPositionSettings.size() > 1)
289 y = strPositionSettings[1].toInt(&ok);
290 else ok = false;
291 if (ok && strPositionSettings.size() > 2)
292 w = strPositionSettings[2].toInt(&ok);
293 else ok = false;
294 if (ok && strPositionSettings.size() > 3)
295 h = strPositionSettings[3].toInt(&ok);
296 else ok = false;
297 if (ok && strPositionSettings.size() > 4)
298 max = strPositionSettings[4] == VBoxDefs::GUI_LastWindowState_Max;
299
300 QRect ar = ok ? QApplication::desktop()->availableGeometry(QPoint(x, y)) :
301 QApplication::desktop()->availableGeometry(machineWindow());
302
303 /* If previous parameters were read correctly: */
304 if (ok)
305 {
306 /* Restore window size and position: */
307 m_normalGeometry = QRect(x, y, w, h);
308 setGeometry(m_normalGeometry);
309 /* Maximize if needed: */
310 if (max)
311 setWindowState(windowState() | Qt::WindowMaximized);
312 }
313 else
314 {
315 /* Resize to default size: */
316 resize(640, 480);
317 qApp->processEvents();
318 /* Move newly created window to the screen center: */
319 m_normalGeometry = geometry();
320 m_normalGeometry.moveCenter(ar.center());
321 setGeometry(m_normalGeometry);
322 }
323 }
324}
325
326void UIMachineWindowScale::saveWindowSettings()
327{
328 CMachine machine = session().GetMachine();
329
330 /* Save extra-data settings: */
331 {
332 QString strWindowPosition = QString("%1,%2,%3,%4")
333 .arg(m_normalGeometry.x()).arg(m_normalGeometry.y())
334 .arg(m_normalGeometry.width()).arg(m_normalGeometry.height());
335 if (isMaximizedChecked())
336 strWindowPosition += QString(",%1").arg(VBoxDefs::GUI_LastWindowState_Max);
337 QString strPositionAddress = m_uScreenId == 0 ? QString("%1").arg(VBoxDefs::GUI_LastScaleWindowPosition) :
338 QString("%1%2").arg(VBoxDefs::GUI_LastScaleWindowPosition).arg(m_uScreenId);
339 machine.SetExtraData(strPositionAddress, strWindowPosition);
340 }
341}
342
343void UIMachineWindowScale::cleanupMachineView()
344{
345 /* Do not cleanup machine view if it is not present: */
346 if (!machineView())
347 return;
348
349 UIMachineView::destroy(m_pMachineView);
350 m_pMachineView = 0;
351}
352
353void UIMachineWindowScale::cleanupMenu()
354{
355 delete m_pMainMenu;
356 m_pMainMenu = 0;
357}
358
359void UIMachineWindowScale::showSimple()
360{
361 /* Just show window: */
362 show();
363}
364
365bool UIMachineWindowScale::isMaximizedChecked()
366{
367#ifdef Q_WS_MAC
368 /* On the Mac the WindowStateChange signal doesn't seems to be delivered
369 * when the user get out of the maximized state. So check this ourself. */
370 return ::darwinIsWindowMaximized(this);
371#else /* Q_WS_MAC */
372 return isMaximized();
373#endif /* !Q_WS_MAC */
374}
375
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use