VirtualBox

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

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

FE/Qt: General Icon Update: Session Information dialog icons.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 27.9 KB
Line 
1/* $Id: VBoxVMInformationDlg.cpp 47162 2013-07-15 14:19:04Z 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 console.GetDisplay().GetScreenResolution(0, width, height, bpp);
468 QString resolution = QString ("%1x%2")
469 .arg (width)
470 .arg (height);
471 if (bpp)
472 resolution += QString ("x%1").arg (bpp);
473
474 QString clipboardMode = gpConverter->toString(m.GetClipboardMode());
475 QString dragAndDropMode = gpConverter->toString(m.GetDragAndDropMode());
476
477 CMachineDebugger debugger = console.GetDebugger();
478 QString virtualization = debugger.GetHWVirtExEnabled() ?
479 VBoxGlobal::tr ("Enabled", "details report (VT-x/AMD-V)") :
480 VBoxGlobal::tr ("Disabled", "details report (VT-x/AMD-V)");
481 QString nested = debugger.GetHWVirtExNestedPagingEnabled() ?
482 VBoxGlobal::tr ("Enabled", "details report (Nested Paging)") :
483 VBoxGlobal::tr ("Disabled", "details report (Nested Paging)");
484 QString unrestricted = debugger.GetHWVirtExUXEnabled() ?
485 VBoxGlobal::tr ("Enabled", "details report (Unrestricted Execution)") :
486 VBoxGlobal::tr ("Disabled", "details report (Unrestricted Execution)");
487
488 CGuest guest = console.GetGuest();
489 QString addVersionStr = guest.GetAdditionsVersion();
490 if (addVersionStr.isEmpty())
491 addVersionStr = tr("Not Detected", "guest additions");
492 else
493 {
494 ULONG revision = guest.GetAdditionsRevision();
495 if (revision != 0)
496 addVersionStr += QString(" r%1").arg(revision);
497 }
498 QString osType = guest.GetOSTypeId();
499 if (osType.isEmpty())
500 osType = tr ("Not Detected", "guest os type");
501 else
502 osType = vboxGlobal().vmGuestOSTypeDescription (osType);
503
504 int vrdePort = console.GetVRDEServerInfo().GetPort();
505 QString vrdeInfo = (vrdePort == 0 || vrdePort == -1)?
506 tr ("Not Available", "details report (VRDE server port)") :
507 QString ("%1").arg (vrdePort);
508
509 /* Searching for longest string */
510 QStringList valuesList;
511 valuesList << resolution << virtualization << nested << unrestricted << addVersionStr << osType << vrdeInfo;
512 int maxLength = 0;
513 foreach (const QString &value, valuesList)
514 maxLength = maxLength < fontMetrics().width (value) ?
515 fontMetrics().width (value) : maxLength;
516
517 result += hdrRow.arg (":/state_running_16px.png").arg (tr ("Runtime Attributes"));
518 result += formatValue (tr ("Screen Resolution"), resolution, maxLength);
519 result += formatValue (tr ("Clipboard Mode"), clipboardMode, maxLength);
520 result += formatValue (tr ("Drag'n'Drop Mode"), dragAndDropMode, maxLength);
521 result += formatValue (VBoxGlobal::tr ("VT-x/AMD-V", "details report"), virtualization, maxLength);
522 result += formatValue (VBoxGlobal::tr ("Nested Paging", "details report"), nested, maxLength);
523 result += formatValue (VBoxGlobal::tr ("Unrestricted Execution", "details report"), unrestricted, maxLength);
524 result += formatValue (tr ("Guest Additions"), addVersionStr, maxLength);
525 result += formatValue (tr ("Guest OS Type"), osType, maxLength);
526 result += formatValue (VBoxGlobal::tr ("Remote Desktop Server Port", "details report (VRDE Server)"), vrdeInfo, maxLength);
527 result += paragraph;
528 }
529
530 /* Storage statistics */
531 {
532 QString storageStat;
533
534 result += hdrRow.arg (":/attachment_16px.png").arg (tr ("Storage Statistics"));
535
536 CStorageControllerVector controllers = mSession.GetMachine().GetStorageControllers();
537 int ideCount = 0, sataCount = 0, scsiCount = 0;
538 foreach (const CStorageController &controller, controllers)
539 {
540 QString ctrName = controller.GetName();
541 KStorageBus busType = controller.GetBus();
542 CMediumAttachmentVector attachments = mSession.GetMachine().GetMediumAttachmentsOfController (ctrName);
543 if (!attachments.isEmpty() && busType != KStorageBus_Floppy)
544 {
545 QString header = "<tr><td></td><td colspan=2><nobr>%1</nobr></td></tr>";
546 QString strControllerName = QApplication::translate("UIMachineSettingsStorage", "Controller: %1");
547 storageStat += header.arg(strControllerName.arg(controller.GetName()));
548 int scsiIndex = 0;
549 foreach (const CMediumAttachment &attachment, attachments)
550 {
551 LONG attPort = attachment.GetPort();
552 LONG attDevice = attachment.GetDevice();
553 switch (busType)
554 {
555 case KStorageBus_IDE:
556 {
557 storageStat += formatMedium (ctrName, attPort, attDevice,
558 QString ("/Devices/IDE%1/ATA%2/Unit%3").arg (ideCount).arg (attPort).arg (attDevice));
559 break;
560 }
561 case KStorageBus_SATA:
562 {
563 storageStat += formatMedium (ctrName, attPort, attDevice,
564 QString ("/Devices/SATA%1/Port%2").arg (sataCount).arg (attPort));
565 break;
566 }
567 case KStorageBus_SCSI:
568 {
569 storageStat += formatMedium (ctrName, attPort, attDevice,
570 QString ("/Devices/SCSI%1/%2").arg (scsiCount).arg (scsiIndex));
571 ++ scsiIndex;
572 break;
573 }
574 default:
575 break;
576 }
577 storageStat += paragraph;
578 }
579 }
580
581 switch (busType)
582 {
583 case KStorageBus_IDE:
584 {
585 ++ ideCount;
586 break;
587 }
588 case KStorageBus_SATA:
589 {
590 ++ sataCount;
591 break;
592 }
593 case KStorageBus_SCSI:
594 {
595 ++ scsiCount;
596 break;
597 }
598 default:
599 break;
600 }
601 }
602
603 /* If there are no Hard Disks */
604 if (storageStat.isNull())
605 {
606 storageStat = composeArticle (tr ("No Storage Devices"));
607 storageStat += paragraph;
608 }
609
610 result += storageStat;
611 }
612
613 /* Network Adapters Statistics */
614 {
615 QString networkStat;
616
617 result += hdrRow.arg (":/nw_16px.png").arg (tr ("Network Statistics"));
618
619 /* Network Adapters list */
620 ulong count = vboxGlobal().virtualBox().GetSystemProperties().GetMaxNetworkAdapters(KChipsetType_PIIX3);
621 for (ulong slot = 0; slot < count; ++ slot)
622 {
623 if (m.GetNetworkAdapter (slot).GetEnabled())
624 {
625 networkStat += formatAdapter (slot, QString ("NA%1").arg (slot));
626 networkStat += paragraph;
627 }
628 }
629
630 /* If there are no Network Adapters */
631 if (networkStat.isNull())
632 {
633 networkStat = composeArticle (tr ("No Network Adapters"));
634 networkStat += paragraph;
635 }
636
637 result += networkStat;
638 }
639
640 /* Show full composed page & save/restore scroll-bar position */
641 int vv = mStatisticText->verticalScrollBar()->value();
642 mStatisticText->setText (table.arg (result));
643 mStatisticText->verticalScrollBar()->setValue (vv);
644}
645
646/**
647 * Allows left-aligned values formatting in right column.
648 *
649 * aValueName - the name of value in the left column.
650 * aValue - left-aligned value itself in the right column.
651 * aMaxSize - maximum width (in pixels) of value in right column.
652 */
653QString VBoxVMInformationDlg::formatValue (const QString &aValueName,
654 const QString &aValue, int aMaxSize)
655{
656 QString strMargin;
657 int size = aMaxSize - fontMetrics().width(aValue);
658 for (int i = 0; i < size; ++i)
659 strMargin += QString("<img width=1 height=1 src=:/tpixel.png>");
660
661 QString bdyRow = "<tr>"
662 "<td></td>"
663 "<td><nobr>%1</nobr></td>"
664 "<td align=right><nobr>%2%3</nobr></td>"
665 "</tr>";
666
667 return bdyRow.arg (aValueName).arg (aValue).arg (strMargin);
668}
669
670QString VBoxVMInformationDlg::formatMedium (const QString &aCtrName,
671 LONG aPort, LONG aDevice,
672 const QString &aBelongsTo)
673{
674 if (mSession.isNull())
675 return QString::null;
676
677 QString header = "<tr><td></td><td colspan=2><nobr>&nbsp;&nbsp;%1:</nobr></td></tr>";
678 CStorageController ctr = mSession.GetMachine().GetStorageControllerByName (aCtrName);
679 QString name = gpConverter->toString (StorageSlot (ctr.GetBus(), aPort, aDevice));
680 return header.arg (name) + composeArticle (aBelongsTo, 2);
681}
682
683QString VBoxVMInformationDlg::formatAdapter (ULONG aSlot,
684 const QString &aBelongsTo)
685{
686 if (mSession.isNull())
687 return QString::null;
688
689 QString header = "<tr><td></td><td colspan=2><nobr>%1</nobr></td></tr>";
690 QString name = VBoxGlobal::tr ("Adapter %1", "details report (network)").arg (aSlot + 1);
691 return header.arg (name) + composeArticle (aBelongsTo, 1);
692}
693
694QString VBoxVMInformationDlg::composeArticle (const QString &aBelongsTo, int aSpacesCount)
695{
696 QString body = "<tr><td></td><td width=50%><nobr>%1%2</nobr></td>"
697 "<td align=right><nobr>%3%4</nobr></td></tr>";
698 QString indent;
699 for (int i = 0; i < aSpacesCount; ++ i)
700 indent += "&nbsp;&nbsp;";
701 body = body.arg (indent);
702
703 QString result;
704
705 if (mLinksMap.contains (aBelongsTo))
706 {
707 QStringList keys = mLinksMap [aBelongsTo];
708 foreach (const QString &key, keys)
709 {
710 QString line (body);
711 if (mNamesMap.contains (key) && mValuesMap.contains (key) && mUnitsMap.contains (key))
712 {
713 line = line.arg (mNamesMap [key]).arg (QString ("%L1").arg (mValuesMap [key].toULongLong()));
714 line = mUnitsMap [key].contains (QRegExp ("\\[\\S+\\]")) ?
715 line.arg (QString ("<img src=:/tpixel.png width=%1 height=1>")
716 .arg (QApplication::fontMetrics().width (
717 QString (" %1").arg (mUnitsMap [key]
718 .mid (1, mUnitsMap [key].length() - 2))))) :
719 line.arg (QString (" %1").arg (mUnitsMap [key]));
720 result += line;
721 }
722 }
723 }
724 else
725 result = body.arg (aBelongsTo).arg (QString::null).arg (QString::null);
726
727 return result;
728}
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