VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/VBoxVMInformationDlg.cpp@ 27087

Last change on this file since 27087 was 27087, checked in by vboxsync, 15 years ago

FE/Qt4: new core: make it possible to use this class in the old and new code at the same time

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 30.4 KB
Line 
1/* $Id: VBoxVMInformationDlg.cpp 27087 2010-03-05 13:28:41Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt4 GUI ("VirtualBox"):
5 * VBoxVMInformationDlg class implementation
6 */
7
8/*
9 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24#ifdef VBOX_WITH_PRECOMPILED_HEADERS
25# include "precomp.h"
26#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
27/* Global Includes */
28#include <QTimer>
29
30/* Local Includes */
31#include <VBoxVMInformationDlg.h>
32#include <VBoxGlobal.h>
33#include <VBoxConsoleView.h>
34#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
35
36#ifdef VBOX_WITH_NEW_RUNTIME_CORE
37#include "UIMachineLogic.h"
38#include "UIMachineWindow.h"
39#include "UIMachineView.h"
40#include "UISession.h"
41#endif /* VBOX_WITH_NEW_RUNTIME_CORE */
42
43VBoxVMInformationDlg::InfoDlgMap VBoxVMInformationDlg::mSelfArray = InfoDlgMap();
44
45#ifdef VBOX_WITH_NEW_RUNTIME_CORE
46void VBoxVMInformationDlg::createInformationDlg(UIMachineWindow *pMachineWindow)
47{
48 CMachine machine = pMachineWindow->machineLogic()->uisession()->session().GetMachine();
49 if (mSelfArray.find (machine.GetName()) == mSelfArray.end())
50 {
51 /* Creating new information dialog if there is no one existing */
52 VBoxVMInformationDlg *id = new VBoxVMInformationDlg(pMachineWindow, Qt::Window);
53 id->centerAccording (pMachineWindow->machineWindow());
54 connect (vboxGlobal().mainWindow(), SIGNAL (closing()), id, SLOT (close()));
55 id->setAttribute (Qt::WA_DeleteOnClose);
56 mSelfArray [machine.GetName()] = id;
57 }
58
59 VBoxVMInformationDlg *info = mSelfArray [machine.GetName()];
60 info->show();
61 info->raise();
62 info->setWindowState (info->windowState() & ~Qt::WindowMinimized);
63 info->activateWindow();
64}
65
66VBoxVMInformationDlg::VBoxVMInformationDlg (UIMachineWindow *pMachineWindow, Qt::WindowFlags aFlags)
67# ifdef Q_WS_MAC
68 : QIWithRetranslateUI2 <QIMainDialog> (pMachineWindow->machineWindow(), aFlags)
69# else /* Q_WS_MAC */
70 : QIWithRetranslateUI2 <QIMainDialog> (0, aFlags)
71# endif /* Q_WS_MAC */
72 , mSession (pMachineWindow->session())
73 , mIsPolished (false)
74 , mStatTimer (new QTimer (this))
75{
76 /* Apply UI decorations */
77 Ui::VBoxVMInformationDlg::setupUi (this);
78
79#ifdef Q_WS_MAC
80 /* No icon for this window on the mac, cause this would act as proxy icon which isn't necessary here. */
81 setWindowIcon (QIcon());
82#else
83 /* Apply window icons */
84 setWindowIcon (vboxGlobal().iconSetFull (QSize (32, 32), QSize (16, 16),
85 ":/session_info_32px.png", ":/session_info_16px.png"));
86#endif
87
88 /* Enable size grip without using a status bar. */
89 setSizeGripEnabled (true);
90
91 /* Setup focus-proxy for pages */
92 mPage1->setFocusProxy (mDetailsText);
93 mPage2->setFocusProxy (mStatisticText);
94
95 /* Setup browsers */
96 mDetailsText->viewport()->setAutoFillBackground (false);
97 mStatisticText->viewport()->setAutoFillBackground (false);
98
99 /* Setup margins */
100 mDetailsText->setViewportMargins (5, 5, 5, 5);
101 mStatisticText->setViewportMargins (5, 5, 5, 5);
102
103 /* Setup handlers */
104 connect (pMachineWindow->uisession(), SIGNAL (sigMediumChange(const CMediumAttachment&)), this, SLOT (updateDetails()));
105 connect (pMachineWindow->uisession(), SIGNAL (sigSharedFolderChange()), this, SLOT (updateDetails()));
106 /* TODO_NEW_CORE: this is ofc not really right in the mm sense. There are
107 * more than one screens. */
108 connect (pMachineWindow->machineView(), SIGNAL (resizeHintDone()), this, SLOT (processStatistics()));
109 connect (mInfoStack, SIGNAL (currentChanged (int)), this, SLOT (onPageChanged (int)));
110 connect (&vboxGlobal(), SIGNAL (mediumEnumFinished (const VBoxMediaList &)), this, SLOT (updateDetails()));
111 connect (mStatTimer, SIGNAL (timeout()), this, SLOT (processStatistics()));
112
113 /* Loading language constants */
114 retranslateUi();
115
116 /* Details page update */
117 updateDetails();
118
119 /* Statistics page update */
120 processStatistics();
121 mStatTimer->start (5000);
122
123 /* Preload dialog attributes for this vm */
124 QString dlgsize = mSession.GetMachine().GetExtraData (VBoxDefs::GUI_InfoDlgState);
125 if (dlgsize.isEmpty())
126 {
127 mWidth = 400;
128 mHeight = 450;
129 mMax = false;
130 }
131 else
132 {
133 QStringList list = dlgsize.split (',');
134 mWidth = list [0].toInt(), mHeight = list [1].toInt();
135 mMax = list [2] == "max";
136 }
137
138 /* Make statistics page the default one */
139 mInfoStack->setCurrentIndex (1);
140}
141#endif /* VBOX_WITH_NEW_RUNTIME_CORE */
142
143void VBoxVMInformationDlg::createInformationDlg (const CSession &aSession, VBoxConsoleView *aConsole)
144{
145 CMachine machine = aSession.GetMachine();
146 if (mSelfArray.find (machine.GetName()) == mSelfArray.end())
147 {
148 /* Creating new information dialog if there is no one existing */
149 VBoxVMInformationDlg *id = new VBoxVMInformationDlg (aConsole, aSession, Qt::Window);
150 id->centerAccording (aConsole);
151 connect (vboxGlobal().mainWindow(), SIGNAL (closing()), id, SLOT (close()));
152 id->setAttribute (Qt::WA_DeleteOnClose);
153 mSelfArray [machine.GetName()] = id;
154 }
155
156 VBoxVMInformationDlg *info = mSelfArray [machine.GetName()];
157 info->show();
158 info->raise();
159 info->setWindowState (info->windowState() & ~Qt::WindowMinimized);
160 info->activateWindow();
161}
162
163VBoxVMInformationDlg::VBoxVMInformationDlg (VBoxConsoleView *aConsole, const CSession &aSession, Qt::WindowFlags aFlags)
164# ifdef Q_WS_MAC
165 : QIWithRetranslateUI2 <QIMainDialog> (aConsole, aFlags)
166# else /* Q_WS_MAC */
167 : QIWithRetranslateUI2 <QIMainDialog> (0, aFlags)
168# endif /* Q_WS_MAC */
169 , mConsole (aConsole)
170 , mSession (aSession)
171 , mIsPolished (false)
172 , mStatTimer (new QTimer (this))
173{
174 /* Apply UI decorations */
175 Ui::VBoxVMInformationDlg::setupUi (this);
176
177#ifdef Q_WS_MAC
178 /* No icon for this window on the mac, cause this would act as proxy icon which isn't necessary here. */
179 setWindowIcon (QIcon());
180#else
181 /* Apply window icons */
182 setWindowIcon (vboxGlobal().iconSetFull (QSize (32, 32), QSize (16, 16),
183 ":/session_info_32px.png", ":/session_info_16px.png"));
184#endif
185
186 /* Enable size grip without using a status bar. */
187 setSizeGripEnabled (true);
188
189 /* Setup focus-proxy for pages */
190 mPage1->setFocusProxy (mDetailsText);
191 mPage2->setFocusProxy (mStatisticText);
192
193 /* Setup browsers */
194 mDetailsText->viewport()->setAutoFillBackground (false);
195 mStatisticText->viewport()->setAutoFillBackground (false);
196
197 /* Setup margins */
198 mDetailsText->setViewportMargins (5, 5, 5, 5);
199 mStatisticText->setViewportMargins (5, 5, 5, 5);
200
201 /* Setup handlers */
202 /* Setup handlers */
203 connect (mConsole, SIGNAL (mediaDriveChanged (VBoxDefs::MediumType)), this, SLOT (updateDetails()));
204 connect (mConsole, SIGNAL (sharedFoldersChanged()), this, SLOT (updateDetails()));
205 connect (mConsole, SIGNAL (resizeHintDone()), this, SLOT (processStatistics()));
206 connect (mInfoStack, SIGNAL (currentChanged (int)), this, SLOT (onPageChanged (int)));
207 connect (&vboxGlobal(), SIGNAL (mediumEnumFinished (const VBoxMediaList &)), this, SLOT (updateDetails()));
208 connect (mStatTimer, SIGNAL (timeout()), this, SLOT (processStatistics()));
209
210 /* Loading language constants */
211 retranslateUi();
212
213 /* Details page update */
214 updateDetails();
215
216 /* Statistics page update */
217 processStatistics();
218 mStatTimer->start (5000);
219
220 /* Preload dialog attributes for this vm */
221 QString dlgsize = mSession.GetMachine().GetExtraData (VBoxDefs::GUI_InfoDlgState);
222 if (dlgsize.isEmpty())
223 {
224 mWidth = 400;
225 mHeight = 450;
226 mMax = false;
227 }
228 else
229 {
230 QStringList list = dlgsize.split (',');
231 mWidth = list [0].toInt(), mHeight = list [1].toInt();
232 mMax = list [2] == "max";
233 }
234
235 /* Make statistics page the default one */
236 mInfoStack->setCurrentIndex (1);
237}
238
239VBoxVMInformationDlg::~VBoxVMInformationDlg()
240{
241 /* Save dialog attributes for this vm */
242 QString dlgsize ("%1,%2,%3");
243 mSession.GetMachine().SetExtraData (VBoxDefs::GUI_InfoDlgState,
244 dlgsize.arg (mWidth).arg (mHeight).arg (isMaximized() ? "max" : "normal"));
245
246 if (!mSession.isNull() && !mSession.GetMachine().isNull())
247 mSelfArray.remove (mSession.GetMachine().GetName());
248}
249
250void VBoxVMInformationDlg::retranslateUi()
251{
252 /* Translate uic generated strings */
253 Ui::VBoxVMInformationDlg::retranslateUi (this);
254
255 updateDetails();
256
257 AssertReturnVoid (!mSession.isNull());
258 CMachine machine = mSession.GetMachine();
259 AssertReturnVoid (!machine.isNull());
260
261 /* Setup a dialog caption */
262 setWindowTitle (tr ("%1 - Session Information").arg (machine.GetName()));
263
264 /* Setup a tabwidget page names */
265 mInfoStack->setTabText (0, tr ("&Details"));
266 mInfoStack->setTabText (1, tr ("&Runtime"));
267
268 /* Clear counter names initially */
269 mNamesMap.clear();
270 mUnitsMap.clear();
271 mLinksMap.clear();
272
273 /* Storage statistics */
274 CSystemProperties sp = vboxGlobal().virtualBox().GetSystemProperties();
275 CStorageControllerVector controllers = mSession.GetMachine().GetStorageControllers();
276 int ideCount = 0, sataCount = 0, scsiCount = 0;
277 foreach (const CStorageController &controller, controllers)
278 {
279 switch (controller.GetBus())
280 {
281 case KStorageBus_IDE:
282 {
283 for (ULONG i = 0; i < sp.GetMaxPortCountForStorageBus (KStorageBus_IDE); ++ i)
284 {
285 for (ULONG j = 0; j < sp.GetMaxDevicesPerPortForStorageBus (KStorageBus_IDE); ++ j)
286 {
287 /* Names */
288 mNamesMap [QString ("/Devices/IDE%1/ATA%2/Unit%3/*DMA")
289 .arg (ideCount).arg (i).arg (j)] = tr ("DMA Transfers");
290 mNamesMap [QString ("/Devices/IDE%1/ATA%2/Unit%3/*PIO")
291 .arg (ideCount).arg (i).arg (j)] = tr ("PIO Transfers");
292 mNamesMap [QString ("/Devices/IDE%1/ATA%2/Unit%3/ReadBytes")
293 .arg (ideCount).arg (i).arg (j)] = tr ("Data Read");
294 mNamesMap [QString ("/Devices/IDE%1/ATA%2/Unit%3/WrittenBytes")
295 .arg (ideCount).arg (i).arg (j)] = tr ("Data Written");
296
297 /* Units */
298 mUnitsMap [QString ("/Devices/IDE%1/ATA%2/Unit%3/*DMA")
299 .arg (ideCount).arg (i).arg (j)] = "[B]";
300 mUnitsMap [QString ("/Devices/IDE%1/ATA%2/Unit%3/*PIO")
301 .arg (ideCount).arg (i).arg (j)] = "[B]";
302 mUnitsMap [QString ("/Devices/IDE%1/ATA%2/Unit%3/ReadBytes")
303 .arg (ideCount).arg (i).arg (j)] = "B";
304 mUnitsMap [QString ("/Devices/IDE%1/ATA%2/Unit%3/WrittenBytes")
305 .arg (ideCount).arg (i).arg (j)] = "B";
306
307 /* Belongs to */
308 mLinksMap [QString ("/Devices/IDE%1/ATA%2/Unit%3").arg (ideCount).arg (i).arg (j)] = QStringList()
309 << QString ("/Devices/IDE%1/ATA%2/Unit%3/*DMA").arg (ideCount).arg (i).arg (j)
310 << QString ("/Devices/IDE%1/ATA%2/Unit%3/*PIO").arg (ideCount).arg (i).arg (j)
311 << QString ("/Devices/IDE%1/ATA%2/Unit%3/ReadBytes").arg (ideCount).arg (i).arg (j)
312 << QString ("/Devices/IDE%1/ATA%2/Unit%3/WrittenBytes").arg (ideCount).arg (i).arg (j);
313 }
314 }
315 ++ ideCount;
316 break;
317 }
318 case KStorageBus_SATA:
319 {
320 for (ULONG i = 0; i < sp.GetMaxPortCountForStorageBus (KStorageBus_SATA); ++ i)
321 {
322 for (ULONG j = 0; j < sp.GetMaxDevicesPerPortForStorageBus (KStorageBus_SATA); ++ j)
323 {
324 /* Names */
325 mNamesMap [QString ("/Devices/SATA%1/Port%2/DMA").arg (sataCount).arg (i)]
326 = tr ("DMA Transfers");
327 mNamesMap [QString ("/Devices/SATA%1/Port%2/ReadBytes").arg (sataCount).arg (i)]
328 = tr ("Data Read");
329 mNamesMap [QString ("/Devices/SATA%1/Port%2/WrittenBytes").arg (sataCount).arg (i)]
330 = tr ("Data Written");
331
332 /* Units */
333 mUnitsMap [QString ("/Devices/SATA%1/Port%2/DMA").arg (sataCount).arg (i)] = "[B]";
334 mUnitsMap [QString ("/Devices/SATA%1/Port%2/ReadBytes").arg (sataCount).arg (i)] = "B";
335 mUnitsMap [QString ("/Devices/SATA%1/Port%2/WrittenBytes").arg (sataCount).arg (i)] = "B";
336
337 /* Belongs to */
338 mLinksMap [QString ("/Devices/SATA%1/Port%2").arg (sataCount).arg (i)] = QStringList()
339 << QString ("/Devices/SATA%1/Port%2/DMA").arg (sataCount).arg (i)
340 << QString ("/Devices/SATA%1/Port%2/ReadBytes").arg (sataCount).arg (i)
341 << QString ("/Devices/SATA%1/Port%2/WrittenBytes").arg (sataCount).arg (i);
342 }
343 }
344 ++ sataCount;
345 break;
346 }
347 case KStorageBus_SCSI:
348 {
349 for (ULONG i = 0; i < sp.GetMaxPortCountForStorageBus (KStorageBus_SCSI); ++ i)
350 {
351 for (ULONG j = 0; j < sp.GetMaxDevicesPerPortForStorageBus (KStorageBus_SCSI); ++ j)
352 {
353 /* Names */
354 mNamesMap [QString ("/Devices/SCSI%1/%2/ReadBytes").arg (scsiCount).arg (i)]
355 = tr ("Data Read");
356 mNamesMap [QString ("/Devices/SCSI%1/%2/WrittenBytes").arg (scsiCount).arg (i)]
357 = tr ("Data Written");
358
359 /* Units */
360 mUnitsMap [QString ("/Devices/SCSI%1/%2/ReadBytes").arg (scsiCount).arg (i)] = "B";
361 mUnitsMap [QString ("/Devices/SCSI%1/%2/WrittenBytes").arg (scsiCount).arg (i)] = "B";
362
363 /* Belongs to */
364 mLinksMap [QString ("/Devices/SCSI%1/%2").arg (scsiCount).arg (i)] = QStringList()
365 << QString ("/Devices/SCSI%1/%2/ReadBytes").arg (scsiCount).arg (i)
366 << QString ("/Devices/SCSI%1/%2/WrittenBytes").arg (scsiCount).arg (i);
367 }
368 }
369 ++ scsiCount;
370 break;
371 }
372 default:
373 break;
374 }
375 }
376
377 /* Network statistics: */
378 ulong count = vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount();
379 for (ulong i = 0; i < count; ++ i)
380 {
381 CNetworkAdapter na = machine.GetNetworkAdapter (i);
382 KNetworkAdapterType ty = na.GetAdapterType();
383 const char *name;
384
385 switch (ty)
386 {
387 case KNetworkAdapterType_I82540EM:
388 case KNetworkAdapterType_I82543GC:
389 case KNetworkAdapterType_I82545EM:
390 name = "E1k";
391 break;
392 case KNetworkAdapterType_Virtio:
393 name = "VNet";
394 break;
395 default:
396 name = "PCNet";
397 break;
398 }
399
400 /* Names */
401 mNamesMap [QString ("/Devices/%1%2/TransmitBytes")
402 .arg (name).arg (i)] = tr ("Data Transmitted");
403 mNamesMap [QString ("/Devices/%1%2/ReceiveBytes")
404 .arg (name).arg (i)] = tr ("Data Received");
405
406 /* Units */
407 mUnitsMap [QString ("/Devices/%1%2/TransmitBytes")
408 .arg (name).arg (i)] = "B";
409 mUnitsMap [QString ("/Devices/%1%2/ReceiveBytes")
410 .arg (name).arg (i)] = "B";
411
412 /* Belongs to */
413 mLinksMap [QString ("NA%1").arg (i)] = QStringList()
414 << QString ("/Devices/%1%2/TransmitBytes").arg (name).arg (i)
415 << QString ("/Devices/%1%2/ReceiveBytes").arg (name).arg (i);
416 }
417
418 /* Statistics page update. */
419 refreshStatistics();
420}
421
422bool VBoxVMInformationDlg::event (QEvent *aEvent)
423{
424 bool result = QIMainDialog::event (aEvent);
425 switch (aEvent->type())
426 {
427 case QEvent::WindowStateChange:
428 {
429 if (mIsPolished)
430 mMax = isMaximized();
431 else if (mMax == isMaximized())
432 mIsPolished = true;
433 break;
434 }
435 default:
436 break;
437 }
438 return result;
439}
440
441void VBoxVMInformationDlg::resizeEvent (QResizeEvent *aEvent)
442{
443 QIMainDialog::resizeEvent (aEvent);
444
445 /* Store dialog size for this vm */
446 if (mIsPolished && !isMaximized())
447 {
448 mWidth = width();
449 mHeight = height();
450 }
451}
452
453void VBoxVMInformationDlg::showEvent (QShowEvent *aEvent)
454{
455 /* One may think that QWidget::polish() is the right place to do things
456 * below, but apparently, by the time when QWidget::polish() is called,
457 * the widget style & layout are not fully done, at least the minimum
458 * size hint is not properly calculated. Since this is sometimes necessary,
459 * we provide our own "polish" implementation */
460 if (!mIsPolished)
461 {
462 /* Load window size and state */
463 resize (mWidth, mHeight);
464 if (mMax)
465 QTimer::singleShot (0, this, SLOT (showMaximized()));
466 else
467 mIsPolished = true;
468 }
469
470 QIMainDialog::showEvent (aEvent);
471}
472
473
474void VBoxVMInformationDlg::updateDetails()
475{
476 /* Details page update */
477 mDetailsText->setText (vboxGlobal().detailsReport (mSession.GetMachine(), false /* aWithLinks */));
478}
479
480void VBoxVMInformationDlg::processStatistics()
481{
482 CMachineDebugger dbg = mSession.GetConsole().GetDebugger();
483 QString info;
484
485 /* Process selected statistics: */
486 for (DataMapType::const_iterator it = mNamesMap.begin(); it != mNamesMap.end(); ++ it)
487 {
488 dbg.GetStats (it.key(), true, info);
489 mValuesMap [it.key()] = parseStatistics (info);
490 }
491
492 /* Statistics page update */
493 refreshStatistics();
494}
495
496void VBoxVMInformationDlg::onPageChanged (int aIndex)
497{
498 /* Focusing the browser on shown page */
499 mInfoStack->widget (aIndex)->setFocus();
500}
501
502QString VBoxVMInformationDlg::parseStatistics (const QString &aText)
503{
504 /* Filters the statistic counters body */
505 QRegExp query ("^.+<Statistics>\n(.+)\n</Statistics>.*$");
506 if (query.indexIn (aText) == -1)
507 return QString::null;
508
509 QStringList wholeList = query.cap (1).split ("\n");
510
511 ULONG64 summa = 0;
512 for (QStringList::Iterator lineIt = wholeList.begin(); lineIt != wholeList.end(); ++ lineIt)
513 {
514 QString text = *lineIt;
515 text.remove (1, 1);
516 text.remove (text.length() - 2, 2);
517
518 /* Parse incoming counter and fill the counter-element values. */
519 CounterElementType counter;
520 counter.type = text.section (" ", 0, 0);
521 text = text.section (" ", 1);
522 QStringList list = text.split ("\" ");
523 for (QStringList::Iterator it = list.begin(); it != list.end(); ++ it)
524 {
525 QString pair = *it;
526 QRegExp regExp ("^(.+)=\"([^\"]*)\"?$");
527 regExp.indexIn (pair);
528 counter.list.insert (regExp.cap (1), regExp.cap (2));
529 }
530
531 /* Fill the output with the necessary counter's value.
532 * Currently we are using "c" field of simple counter only. */
533 QString result = counter.list.contains ("c") ? counter.list ["c"] : "0";
534 summa += result.toULongLong();
535 }
536
537 return QString::number (summa);
538}
539
540void VBoxVMInformationDlg::refreshStatistics()
541{
542 if (mSession.isNull())
543 return;
544
545 QString table = "<table width=100% cellspacing=1 cellpadding=0>%1</table>";
546 QString hdrRow = "<tr><td width=22><img src='%1'></td>"
547 "<td colspan=2><nobr><b>%2</b></nobr></td></tr>";
548 QString paragraph = "<tr><td colspan=3></td></tr>";
549 QString result;
550
551 CMachine m = mSession.GetMachine();
552
553 /* Runtime Information */
554 {
555 CConsole console = mSession.GetConsole();
556 ULONG bpp = console.GetDisplay().GetBitsPerPixel();
557 QString resolution = QString ("%1x%2")
558 .arg (console.GetDisplay().GetWidth())
559 .arg (console.GetDisplay().GetHeight());
560 if (bpp)
561 resolution += QString ("x%1").arg (bpp);
562 QString virtualization = console.GetDebugger().GetHWVirtExEnabled() ?
563 VBoxGlobal::tr ("Enabled", "details report (VT-x/AMD-V)") :
564 VBoxGlobal::tr ("Disabled", "details report (VT-x/AMD-V)");
565 QString nested = console.GetDebugger().GetHWVirtExNestedPagingEnabled() ?
566 VBoxGlobal::tr ("Enabled", "details report (Nested Paging)") :
567 VBoxGlobal::tr ("Disabled", "details report (Nested Paging)");
568 QString addInfo = console.GetGuest().GetAdditionsVersion();
569 uint addVersion = addInfo.toUInt();
570 QString addVerisonStr = !addInfo.isNull() ?
571 tr ("Version %1.%2", "guest additions")
572 .arg (RT_HIWORD (addVersion)).arg (RT_LOWORD (addVersion)) :
573 tr ("Not Detected", "guest additions");
574 QString osType = console.GetGuest().GetOSTypeId();
575 if (osType.isNull())
576 osType = tr ("Not Detected", "guest os type");
577 else
578 osType = vboxGlobal().vmGuestOSTypeDescription (osType);
579 int vrdpPort = console.GetRemoteDisplayInfo().GetPort();
580 QString vrdpInfo = (vrdpPort == 0 || vrdpPort == -1)?
581 tr ("Not Available", "details report (VRDP server port)") :
582 QString ("%1").arg (vrdpPort);
583
584 /* Searching for longest string */
585 QStringList valuesList;
586 valuesList << resolution << virtualization << nested << addVerisonStr << osType << vrdpInfo;
587 int maxLength = 0;
588 foreach (const QString &value, valuesList)
589 maxLength = maxLength < fontMetrics().width (value) ?
590 fontMetrics().width (value) : maxLength;
591
592 result += hdrRow.arg (":/state_running_16px.png").arg (tr ("Runtime Attributes"));
593 result += formatValue (tr ("Screen Resolution"), resolution, maxLength);
594 result += formatValue (VBoxGlobal::tr ("VT-x/AMD-V", "details report"), virtualization, maxLength);
595 result += formatValue (VBoxGlobal::tr ("Nested Paging", "details report"), nested, maxLength);
596 result += formatValue (tr ("Guest Additions"), addVerisonStr, maxLength);
597 result += formatValue (tr ("Guest OS Type"), osType, maxLength);
598 result += formatValue (VBoxGlobal::tr ("Remote Display Server Port", "details report (VRDP Server)"), vrdpInfo, maxLength);
599 result += paragraph;
600 }
601
602 /* Storage statistics */
603 {
604 QString storageStat;
605
606 result += hdrRow.arg (":/attachment_16px.png").arg (tr ("Storage Statistics"));
607
608 CStorageControllerVector controllers = mSession.GetMachine().GetStorageControllers();
609 int ideCount = 0, sataCount = 0, scsiCount = 0;
610 foreach (const CStorageController &controller, controllers)
611 {
612 QString ctrName = controller.GetName();
613 KStorageBus busType = controller.GetBus();
614 CMediumAttachmentVector attachments = mSession.GetMachine().GetMediumAttachmentsOfController (ctrName);
615 if (!attachments.isEmpty() && busType != KStorageBus_Floppy)
616 {
617 QString header = "<tr><td></td><td colspan=2><nobr>%1</nobr></td></tr>";
618 storageStat += header.arg (ctrName);
619 int scsiIndex = 0;
620 foreach (const CMediumAttachment &attachment, attachments)
621 {
622 LONG attPort = attachment.GetPort();
623 LONG attDevice = attachment.GetDevice();
624 switch (busType)
625 {
626 case KStorageBus_IDE:
627 {
628 storageStat += formatMedium (ctrName, attPort, attDevice,
629 QString ("/Devices/IDE%1/ATA%2/Unit%3").arg (ideCount).arg (attPort).arg (attDevice));
630 break;
631 }
632 case KStorageBus_SATA:
633 {
634 storageStat += formatMedium (ctrName, attPort, attDevice,
635 QString ("/Devices/SATA%1/Port%2").arg (sataCount).arg (attPort));
636 break;
637 }
638 case KStorageBus_SCSI:
639 {
640 storageStat += formatMedium (ctrName, attPort, attDevice,
641 QString ("/Devices/SCSI%1/%2").arg (scsiCount).arg (scsiIndex));
642 ++ scsiIndex;
643 break;
644 }
645 default:
646 break;
647 }
648 storageStat += paragraph;
649 }
650 }
651
652 switch (busType)
653 {
654 case KStorageBus_IDE:
655 {
656 ++ ideCount;
657 break;
658 }
659 case KStorageBus_SATA:
660 {
661 ++ sataCount;
662 break;
663 }
664 case KStorageBus_SCSI:
665 {
666 ++ scsiCount;
667 break;
668 }
669 default:
670 break;
671 }
672 }
673
674 /* If there are no Hard Disks */
675 if (storageStat.isNull())
676 {
677 storageStat = composeArticle (tr ("No Storage Devices"));
678 storageStat += paragraph;
679 }
680
681 result += storageStat;
682 }
683
684 /* Network Adapters Statistics */
685 {
686 QString networkStat;
687
688 result += hdrRow.arg (":/nw_16px.png").arg (tr ("Network Statistics"));
689
690 /* Network Adapters list */
691 ulong count = vboxGlobal().virtualBox().GetSystemProperties().GetNetworkAdapterCount();
692 for (ulong slot = 0; slot < count; ++ slot)
693 {
694 if (m.GetNetworkAdapter (slot).GetEnabled())
695 {
696 networkStat += formatAdapter (slot, QString ("NA%1").arg (slot));
697 networkStat += paragraph;
698 }
699 }
700
701 /* If there are no Network Adapters */
702 if (networkStat.isNull())
703 {
704 networkStat = composeArticle (tr ("No Network Adapters"));
705 networkStat += paragraph;
706 }
707
708 result += networkStat;
709 }
710
711 /* Show full composed page & save/restore scroll-bar position */
712 int vv = mStatisticText->verticalScrollBar()->value();
713 mStatisticText->setText (table.arg (result));
714 mStatisticText->verticalScrollBar()->setValue (vv);
715}
716
717/**
718 * Allows left-aligned values formatting in right column.
719 *
720 * aValueName - the name of value in the left column.
721 * aValue - left-aligned value itself in the right column.
722 * aMaxSize - maximum width (in pixels) of value in right column.
723 */
724QString VBoxVMInformationDlg::formatValue (const QString &aValueName,
725 const QString &aValue, int aMaxSize)
726{
727 QString bdyRow = "<tr><td></td><td width=50%><nobr>%1</nobr></td>"
728 "<td align=right><nobr>%2"
729 "<img src=:/tpixel.png width=%3 height=1></nobr></td></tr>";
730
731 int size = aMaxSize - fontMetrics().width (aValue);
732 return bdyRow.arg (aValueName).arg (aValue).arg (size);
733}
734
735QString VBoxVMInformationDlg::formatMedium (const QString &aCtrName,
736 LONG aPort, LONG aDevice,
737 const QString &aBelongsTo)
738{
739 if (mSession.isNull())
740 return QString::null;
741
742 QString header = "<tr><td></td><td colspan=2><nobr>&nbsp;&nbsp;%1:</nobr></td></tr>";
743 CStorageController ctr = mSession.GetMachine().GetStorageControllerByName (aCtrName);
744 QString name = vboxGlobal().toString (StorageSlot (ctr.GetBus(), aPort, aDevice));
745 return header.arg (name) + composeArticle (aBelongsTo, 2);
746}
747
748QString VBoxVMInformationDlg::formatAdapter (ULONG aSlot,
749 const QString &aBelongsTo)
750{
751 if (mSession.isNull())
752 return QString::null;
753
754 QString header = "<tr><td></td><td colspan=2><nobr>%1</nobr></td></tr>";
755 QString name = VBoxGlobal::tr ("Adapter %1", "details report (network)").arg (aSlot + 1);
756 return header.arg (name) + composeArticle (aBelongsTo, 1);
757}
758
759QString VBoxVMInformationDlg::composeArticle (const QString &aBelongsTo, int aSpacesCount)
760{
761 QString body = "<tr><td></td><td width=50%><nobr>%1%2</nobr></td>"
762 "<td align=right><nobr>%3%4</nobr></td></tr>";
763 QString indent;
764 for (int i = 0; i < aSpacesCount; ++ i)
765 indent += "&nbsp;&nbsp;";
766 body = body.arg (indent);
767
768 QString result;
769
770 if (mLinksMap.contains (aBelongsTo))
771 {
772 QStringList keys = mLinksMap [aBelongsTo];
773 foreach (const QString &key, keys)
774 {
775 QString line (body);
776 if (mNamesMap.contains (key) && mValuesMap.contains (key) && mUnitsMap.contains (key))
777 {
778 line = line.arg (mNamesMap [key]).arg (QString ("%L1").arg (mValuesMap [key].toULongLong()));
779 line = mUnitsMap [key].contains (QRegExp ("\\[\\S+\\]")) ?
780 line.arg (QString ("<img src=:/tpixel.png width=%1 height=1>")
781 .arg (QApplication::fontMetrics().width (
782 QString (" %1").arg (mUnitsMap [key]
783 .mid (1, mUnitsMap [key].length() - 2))))) :
784 line.arg (QString (" %1").arg (mUnitsMap [key]));
785 result += line;
786 }
787 }
788 }
789 else
790 result = body.arg (aBelongsTo).arg (QString::null).arg (QString::null);
791
792 return result;
793}
794
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette