VirtualBox

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

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

FE/Qt4: VBox Information Dialog now using storage section formatting similar to VBox Details report since r53487.

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