VirtualBox

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

Last change on this file since 16867 was 16867, checked in by vboxsync, 16 years ago

Main: rename IHardDiskImage2 to IHardDiskImage; rename IFloppyImage2 to IFloppyImage; rename all media-related methods with a '2' suffix

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