VirtualBox

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

Last change on this file since 47774 was 47774, checked in by vboxsync, 12 years ago

Main,Frontends: IDisplay::GetScreenResolution returns the screen origin.

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

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