VirtualBox

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

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

FE/Qt4: created separate icon factory

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