VirtualBox

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

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

FE/Qt4: much more cosmetics

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