Changeset 89006 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- May 12, 2021 9:22:52 AM (4 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 1 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
r88971 r89006 623 623 src/medium/UIMediumManager.h \ 624 624 src/activity/overview/UIVMActivityOverviewWidget.h \ 625 src/activity/overview/UIVMActivityListWidget.h \ 625 626 src/networkmanager/UIDetailsWidgetHostNetwork.h \ 626 627 src/networkmanager/UIDetailsWidgetNATNetwork.h \ … … 1114 1115 src/medium/UIMediumManager.cpp \ 1115 1116 src/activity/overview/UIVMActivityOverviewWidget.cpp \ 1117 src/activity/overview/UIVMActivityListWidget.cpp \ 1116 1118 src/networkmanager/UIDetailsWidgetHostNetwork.cpp \ 1117 1119 src/networkmanager/UIDetailsWidgetNATNetwork.cpp \ -
trunk/src/VBox/Frontends/VirtualBox/src/activity/overview/UIVMActivityListWidget.cpp
r88999 r89006 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIVMActivity OverviewWidget class implementation.3 * VBox Qt GUI - UIVMActivityListWidget class implementation. 4 4 */ 5 5 … … 39 39 #include "UIIconPool.h" 40 40 #include "UIVMActivityMonitor.h" 41 #include "UIVMActivity OverviewWidget.h"41 #include "UIVMActivityListWidget.h" 42 42 #include "UIMessageCenter.h" 43 43 #include "QIToolBar.h" … … 57 57 #include <iprt/cidr.h> 58 58 59 struct ResourceColumn60 {61 QString m_strName;62 bool m_fEnabled;63 };64 65 /** Draws a doughnut shaped chart for the passed data values and can have a text drawn in the center. */66 67 68 59 /********************************************************************************************************************************* 69 * Class UIVMActivity OverviewDoughnutChart definition.*60 * Class UIVMActivityListWidget implementation. * 70 61 *********************************************************************************************************************************/ 71 62 72 class UIVMActivityOverviewDoughnutChart : public QWidget 73 { 74 75 Q_OBJECT; 76 77 public: 78 79 UIVMActivityOverviewDoughnutChart(QWidget *pParent = 0); 80 void updateData(quint64 iData0, quint64 iData1); 81 void setChartColors(const QColor &color0, const QColor &color1); 82 void setChartCenterString(const QString &strCenter); 83 void setDataMaximum(quint64 iMax); 84 85 protected: 86 87 virtual void paintEvent(QPaintEvent *pEvent) /* override */; 88 89 private: 90 91 quint64 m_iData0; 92 quint64 m_iData1; 93 quint64 m_iDataMaximum; 94 int m_iMargin; 95 QColor m_color0; 96 QColor m_color1; 97 /** If not empty this text is drawn at the center of the doughnut chart. */ 98 QString m_strCenter; 99 }; 100 101 /** A simple container to store host related performance values. */ 102 103 104 /********************************************************************************************************************************* 105 * Class UIVMActivityOverviewHostStats definition. * 106 *********************************************************************************************************************************/ 107 108 class UIVMActivityOverviewHostStats 109 { 110 111 public: 112 113 UIVMActivityOverviewHostStats(); 114 quint64 m_iCPUUserLoad; 115 quint64 m_iCPUKernelLoad; 116 quint64 m_iCPUFreq; 117 quint64 m_iRAMTotal; 118 quint64 m_iRAMFree; 119 quint64 m_iFSTotal; 120 quint64 m_iFSFree; 121 }; 122 123 /** A container QWidget to layout host stats. related widgets. */ 124 125 126 /********************************************************************************************************************************* 127 * Class UIVMActivityOverviewHostStatsWidget definition. * 128 *********************************************************************************************************************************/ 129 130 class UIVMActivityOverviewHostStatsWidget : public QIWithRetranslateUI<QWidget> 131 { 132 133 Q_OBJECT; 134 135 public: 136 137 UIVMActivityOverviewHostStatsWidget(QWidget *pParent = 0); 138 void setHostStats(const UIVMActivityOverviewHostStats &hostStats); 139 140 protected: 141 142 virtual void retranslateUi() /* override */; 143 144 private: 145 146 void prepare(); 147 void addVerticalLine(QHBoxLayout *pLayout); 148 void updateLabels(); 149 150 UIVMActivityOverviewDoughnutChart *m_pHostCPUChart; 151 UIVMActivityOverviewDoughnutChart *m_pHostRAMChart; 152 UIVMActivityOverviewDoughnutChart *m_pHostFSChart; 153 QLabel *m_pCPUTitleLabel; 154 QLabel *m_pCPUUserLabel; 155 QLabel *m_pCPUKernelLabel; 156 QLabel *m_pCPUTotalLabel; 157 QLabel *m_pRAMTitleLabel; 158 QLabel *m_pRAMUsedLabel; 159 QLabel *m_pRAMFreeLabel; 160 QLabel *m_pRAMTotalLabel; 161 QLabel *m_pFSTitleLabel; 162 QLabel *m_pFSUsedLabel; 163 QLabel *m_pFSFreeLabel; 164 QLabel *m_pFSTotalLabel; 165 QColor m_CPUUserColor; 166 QColor m_CPUKernelColor; 167 QColor m_RAMFreeColor; 168 QColor m_RAMUsedColor; 169 UIVMActivityOverviewHostStats m_hostStats; 170 }; 171 172 173 /********************************************************************************************************************************* 174 * Class UIVMActivityOverviewTableView definition. * 175 *********************************************************************************************************************************/ 176 /** A QTableView extension so manage the column width a bit better than what Qt offers out of box. */ 177 class UIVMActivityOverviewTableView : public QTableView 178 { 179 Q_OBJECT; 180 181 signals: 182 183 void sigSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); 184 185 public: 186 187 UIVMActivityOverviewTableView(QWidget *pParent = 0); 188 void setMinimumColumnWidths(const QMap<int, int>& widths); 189 void updateColumVisibility(); 190 int selectedItemIndex() const; 191 bool hasSelection() const; 192 193 protected: 194 195 virtual void resizeEvent(QResizeEvent *pEvent) /* override */; 196 virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) /* override */; 197 virtual void mousePressEvent(QMouseEvent *pEvent) /* override */; 198 199 private slots: 200 201 202 203 private: 204 205 /** Resizes all the columns in response to resizeEvent. Columns cannot be narrower than m_minimumColumnWidths values. */ 206 void resizeHeaders(); 207 /** Value is in pixels. Columns cannot be narrower than this width. */ 208 QMap<int, int> m_minimumColumnWidths; 209 }; 210 211 /** Each instance of UIVMActivityOverviewItem corresponds to a running vm whose stats are displayed. 212 * they are owned my the model. */ 213 /********************************************************************************************************************************* 214 * Class UIVMActivityOverviewItem definition. * 215 *********************************************************************************************************************************/ 216 class UIActivityOverviewItem 217 { 218 219 public: 220 221 UIActivityOverviewItem(const QUuid &uid, const QString &strVMName, KMachineState enmState); 222 //yUIActivityOverviewItem(const QUuid &uid); 223 UIActivityOverviewItem(); 224 ~UIActivityOverviewItem(); 225 bool operator==(const UIActivityOverviewItem& other) const; 226 bool isWithGuestAdditions(); 227 void resetDebugger(); 228 229 QUuid m_VMuid; 230 QString m_strVMName; 231 KMachineState m_enmMachineState; 232 233 quint64 m_uCPUGuestLoad; 234 quint64 m_uCPUVMMLoad; 235 236 quint64 m_uTotalRAM; 237 quint64 m_uFreeRAM; 238 quint64 m_uUsedRAM; 239 float m_fRAMUsagePercentage; 240 241 quint64 m_uNetworkDownRate; 242 quint64 m_uNetworkUpRate; 243 quint64 m_uNetworkDownTotal; 244 quint64 m_uNetworkUpTotal; 245 246 quint64 m_uDiskWriteRate; 247 quint64 m_uDiskReadRate; 248 quint64 m_uDiskWriteTotal; 249 quint64 m_uDiskReadTotal; 250 251 quint64 m_uVMExitRate; 252 quint64 m_uVMExitTotal; 253 254 CSession m_comSession; 255 CMachineDebugger m_comDebugger; 256 CGuest m_comGuest; 257 /** The strings of each column for the item. We update this during performance query 258 * instead of model's data function to know the string length earlier. */ 259 QMap<int, QString> m_columnData; 260 261 private: 262 263 void setupPerformanceCollector(); 264 }; 265 266 Q_DECLARE_METATYPE(UIActivityOverviewItem); 267 268 269 /********************************************************************************************************************************* 270 * Class UIVMActivityOverviewProxyModel definition. * 271 *********************************************************************************************************************************/ 272 class UIActivityOverviewProxyModel : public QSortFilterProxyModel 273 { 274 275 Q_OBJECT; 276 277 public: 278 279 UIActivityOverviewProxyModel(QObject *parent = 0); 280 void dataUpdate(); 281 void setNotRunningVMVisibility(bool fShow); 282 283 protected: 284 285 virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const /* override*/; 286 bool filterAcceptsRow(int iSourceRow, const QModelIndex &sourceParent) const /* override*/; 287 288 private: 289 290 bool m_fShowNotRunningVMs; 291 }; 292 293 294 /********************************************************************************************************************************* 295 * Class UIActivityOverviewModel definition. * 296 *********************************************************************************************************************************/ 297 class UIActivityOverviewModel : public QAbstractTableModel 298 { 299 Q_OBJECT; 300 301 signals: 302 303 void sigDataUpdate(); 304 void sigHostStatsUpdate(const UIVMActivityOverviewHostStats &stats); 305 306 public: 307 308 UIActivityOverviewModel(QObject *parent = 0); 309 int rowCount(const QModelIndex &parent = QModelIndex()) const /* override */; 310 int columnCount(const QModelIndex &parent = QModelIndex()) const /* override */; 311 QVariant data(const QModelIndex &index, int role) const /* override */; 312 void clearData(); 313 QVariant headerData(int section, Qt::Orientation orientation, int role) const; 314 void setColumnCaptions(const QMap<int, QString>& captions); 315 void setColumnVisible(const QMap<int, bool>& columnVisible); 316 bool columnVisible(int iColumnId) const; 317 void setShouldUpdate(bool fShouldUpdate); 318 const QMap<int, int> dataLengths() const; 319 QUuid itemUid(int iIndex); 320 int itemIndex(const QUuid &uid); 321 /* Return the state of the machine represented by the item at @rowIndex. */ 322 KMachineState machineState(int rowIndex) const; 323 void setDefaultViewFont(const QFont &font); 324 void setDefaultViewFontColor(const QColor &color); 325 326 private slots: 327 328 void sltMachineStateChanged(const QUuid &uId, const KMachineState state); 329 void sltMachineRegistered(const QUuid &uId, bool fRegistered); 330 void sltTimeout(); 331 332 private: 333 334 void initialize(); 335 void initializeItems(); 336 void setupPerformanceCollector(); 337 void queryPerformanceCollector(); 338 void addItem(const QUuid& uMachineId, const QString& strMachineName, KMachineState enmState); 339 void removeItem(const QUuid& uMachineId); 340 void getHostRAMStats(); 341 342 QVector<UIActivityOverviewItem> m_itemList; 343 QMap<int, QString> m_columnTitles; 344 QTimer *m_pTimer; 345 /** @name The following are used during UIPerformanceCollector::QueryMetricsData(..) 346 * @{ */ 347 QVector<QString> m_nameList; 348 QVector<CUnknown> m_objectList; 349 /** @} */ 350 CPerformanceCollector m_performanceCollector; 351 QMap<int, bool> m_columnVisible; 352 /** If true the table data and corresponding view is updated. Possibly set by host widget to true only 353 * when the widget is visible in the main UI. */ 354 bool m_fShouldUpdate; 355 UIVMActivityOverviewHostStats m_hostStats; 356 QFont m_defaultViewFont; 357 QColor m_defaultViewFontColor; 358 /** Maximum length of string length of data displayed in column. Updated in UIActivityOverviewModel::data(..). */ 359 mutable QMap<int, int> m_columnDataMaxLength; 360 }; 361 362 363 /********************************************************************************************************************************* 364 * UIVMActivityOverviewDelegate definition. * 365 *********************************************************************************************************************************/ 366 /** A QItemDelegate child class to disable dashed lines drawn around selected cells in QTableViews */ 367 class UIVMActivityOverviewDelegate : public QItemDelegate 368 { 369 370 Q_OBJECT; 371 372 protected: 373 374 virtual void drawFocus ( QPainter * /*painter*/, const QStyleOptionViewItem & /*option*/, const QRect & /*rect*/ ) const {} 375 }; 376 377 378 /********************************************************************************************************************************* 379 * Class UIVMActivityOverviewDoughnutChart implementation. * 380 *********************************************************************************************************************************/ 381 UIVMActivityOverviewDoughnutChart::UIVMActivityOverviewDoughnutChart(QWidget *pParent /* = 0 */) 382 :QWidget(pParent) 383 , m_iData0(0) 384 , m_iData1(0) 385 , m_iDataMaximum(0) 386 , m_iMargin(3) 387 { 388 } 389 390 void UIVMActivityOverviewDoughnutChart::updateData(quint64 iData0, quint64 iData1) 391 { 392 m_iData0 = iData0; 393 m_iData1 = iData1; 394 update(); 395 } 396 397 void UIVMActivityOverviewDoughnutChart::setChartColors(const QColor &color0, const QColor &color1) 398 { 399 m_color0 = color0; 400 m_color1 = color1; 401 } 402 403 void UIVMActivityOverviewDoughnutChart::setChartCenterString(const QString &strCenter) 404 { 405 m_strCenter = strCenter; 406 } 407 408 void UIVMActivityOverviewDoughnutChart::setDataMaximum(quint64 iMax) 409 { 410 m_iDataMaximum = iMax; 411 } 412 413 void UIVMActivityOverviewDoughnutChart::paintEvent(QPaintEvent *pEvent) 414 { 415 QWidget::paintEvent(pEvent); 416 417 QPainter painter(this); 418 painter.setRenderHint(QPainter::Antialiasing); 419 420 int iFrameHeight = height()- 2 * m_iMargin; 421 QRectF outerRect = QRectF(QPoint(m_iMargin,m_iMargin), QSize(iFrameHeight, iFrameHeight)); 422 QRectF innerRect = UIMonitorCommon::getScaledRect(outerRect, 0.6f, 0.6f); 423 UIMonitorCommon::drawCombinedDoughnutChart(m_iData0, m_color0, 424 m_iData1, m_color1, 425 painter, m_iDataMaximum, 426 outerRect, innerRect, 80); 427 if (!m_strCenter.isEmpty()) 428 { 429 float mul = 1.f / 1.4f; 430 QRectF textRect = UIMonitorCommon::getScaledRect(innerRect, mul, mul); 431 painter.setPen(Qt::black); 432 painter.drawText(textRect, Qt::AlignCenter, m_strCenter); 433 } 434 } 435 436 437 /********************************************************************************************************************************* 438 * Class UIVMActivityOverviewHostStatsWidget implementation. * 439 *********************************************************************************************************************************/ 440 441 UIVMActivityOverviewHostStatsWidget::UIVMActivityOverviewHostStatsWidget(QWidget *pParent /* = 0 */) 442 : QIWithRetranslateUI<QWidget>(pParent) 443 , m_pHostCPUChart(0) 444 , m_pHostRAMChart(0) 445 , m_pHostFSChart(0) 446 , m_pCPUTitleLabel(0) 447 , m_pCPUUserLabel(0) 448 , m_pCPUKernelLabel(0) 449 , m_pCPUTotalLabel(0) 450 , m_pRAMTitleLabel(0) 451 , m_pRAMUsedLabel(0) 452 , m_pRAMFreeLabel(0) 453 , m_pRAMTotalLabel(0) 454 , m_pFSTitleLabel(0) 455 , m_pFSUsedLabel(0) 456 , m_pFSFreeLabel(0) 457 , m_pFSTotalLabel(0) 458 , m_CPUUserColor(Qt::red) 459 , m_CPUKernelColor(Qt::blue) 460 , m_RAMFreeColor(Qt::blue) 461 , m_RAMUsedColor(Qt::red) 462 { 463 prepare(); 464 retranslateUi(); 465 } 466 467 void UIVMActivityOverviewHostStatsWidget::setHostStats(const UIVMActivityOverviewHostStats &hostStats) 468 { 469 m_hostStats = hostStats; 470 if (m_pHostCPUChart) 471 { 472 m_pHostCPUChart->updateData(m_hostStats.m_iCPUUserLoad, m_hostStats.m_iCPUKernelLoad); 473 QString strCenter = QString("%1\nMHz").arg(m_hostStats.m_iCPUFreq); 474 m_pHostCPUChart->setChartCenterString(strCenter); 475 } 476 if (m_pHostRAMChart) 477 { 478 quint64 iUsedRAM = m_hostStats.m_iRAMTotal - m_hostStats.m_iRAMFree; 479 m_pHostRAMChart->updateData(iUsedRAM, m_hostStats.m_iRAMFree); 480 m_pHostRAMChart->setDataMaximum(m_hostStats.m_iRAMTotal); 481 if (m_hostStats.m_iRAMTotal != 0) 482 { 483 quint64 iUsedRamPer = 100 * (iUsedRAM / (float) m_hostStats.m_iRAMTotal); 484 QString strCenter = QString("%1%\n%2").arg(iUsedRamPer).arg(UIVMActivityOverviewWidget::tr("Used")); 485 m_pHostRAMChart->setChartCenterString(strCenter); 486 } 487 } 488 if (m_pHostFSChart) 489 { 490 quint64 iUsedFS = m_hostStats.m_iFSTotal - m_hostStats.m_iFSFree; 491 m_pHostFSChart->updateData(iUsedFS, m_hostStats.m_iFSFree); 492 m_pHostFSChart->setDataMaximum(m_hostStats.m_iFSTotal); 493 if (m_hostStats.m_iFSTotal != 0) 494 { 495 quint64 iUsedFSPer = 100 * (iUsedFS / (float) m_hostStats.m_iFSTotal); 496 QString strCenter = QString("%1%\n%2").arg(iUsedFSPer).arg(UIVMActivityOverviewWidget::tr("Used")); 497 m_pHostFSChart->setChartCenterString(strCenter); 498 } 499 } 500 501 updateLabels(); 502 } 503 504 void UIVMActivityOverviewHostStatsWidget::retranslateUi() 505 { 506 updateLabels(); 507 } 508 509 void UIVMActivityOverviewHostStatsWidget::addVerticalLine(QHBoxLayout *pLayout) 510 { 511 QFrame *pLine = new QFrame; 512 pLine->setFrameShape(QFrame::VLine); 513 pLine->setFrameShadow(QFrame::Sunken); 514 pLayout->addWidget(pLine); 515 } 516 517 void UIVMActivityOverviewHostStatsWidget::prepare() 518 { 519 QHBoxLayout *pLayout = new QHBoxLayout; 520 setLayout(pLayout); 521 int iMinimumSize = 3 * QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize); 522 523 /* CPU Stuff: */ 524 { 525 /* Host CPU Labels: */ 526 QWidget *pCPULabelContainer = new QWidget; 527 pCPULabelContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); 528 pLayout->addWidget(pCPULabelContainer); 529 QVBoxLayout *pCPULabelsLayout = new QVBoxLayout; 530 pCPULabelsLayout->setContentsMargins(0, 0, 0, 0); 531 pCPULabelContainer->setLayout(pCPULabelsLayout); 532 m_pCPUTitleLabel = new QLabel; 533 pCPULabelsLayout->addWidget(m_pCPUTitleLabel); 534 m_pCPUUserLabel = new QLabel; 535 pCPULabelsLayout->addWidget(m_pCPUUserLabel); 536 m_pCPUKernelLabel = new QLabel; 537 pCPULabelsLayout->addWidget(m_pCPUKernelLabel); 538 m_pCPUTotalLabel = new QLabel; 539 pCPULabelsLayout->addWidget(m_pCPUTotalLabel); 540 pCPULabelsLayout->setAlignment(Qt::AlignTop); 541 pCPULabelsLayout->setSpacing(0); 542 /* Host CPU chart widget: */ 543 m_pHostCPUChart = new UIVMActivityOverviewDoughnutChart; 544 if (m_pHostCPUChart) 545 { 546 m_pHostCPUChart->setMinimumSize(iMinimumSize, iMinimumSize); 547 m_pHostCPUChart->setDataMaximum(100); 548 pLayout->addWidget(m_pHostCPUChart); 549 m_pHostCPUChart->setChartColors(m_CPUUserColor, m_CPUKernelColor); 550 } 551 } 552 addVerticalLine(pLayout); 553 /* RAM Stuff: */ 554 { 555 QWidget *pRAMLabelContainer = new QWidget; 556 pRAMLabelContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); 557 558 pLayout->addWidget(pRAMLabelContainer); 559 QVBoxLayout *pRAMLabelsLayout = new QVBoxLayout; 560 pRAMLabelsLayout->setContentsMargins(0, 0, 0, 0); 561 pRAMLabelsLayout->setSpacing(0); 562 pRAMLabelContainer->setLayout(pRAMLabelsLayout); 563 m_pRAMTitleLabel = new QLabel; 564 pRAMLabelsLayout->addWidget(m_pRAMTitleLabel); 565 m_pRAMUsedLabel = new QLabel; 566 pRAMLabelsLayout->addWidget(m_pRAMUsedLabel); 567 m_pRAMFreeLabel = new QLabel; 568 pRAMLabelsLayout->addWidget(m_pRAMFreeLabel); 569 m_pRAMTotalLabel = new QLabel; 570 pRAMLabelsLayout->addWidget(m_pRAMTotalLabel); 571 572 m_pHostRAMChart = new UIVMActivityOverviewDoughnutChart; 573 if (m_pHostRAMChart) 574 { 575 m_pHostRAMChart->setMinimumSize(iMinimumSize, iMinimumSize); 576 pLayout->addWidget(m_pHostRAMChart); 577 m_pHostRAMChart->setChartColors(m_RAMUsedColor, m_RAMFreeColor); 578 } 579 } 580 addVerticalLine(pLayout); 581 /* FS Stuff: */ 582 { 583 QWidget *pFSLabelContainer = new QWidget; 584 pLayout->addWidget(pFSLabelContainer); 585 pFSLabelContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); 586 QVBoxLayout *pFSLabelsLayout = new QVBoxLayout; 587 pFSLabelsLayout->setContentsMargins(0, 0, 0, 0); 588 pFSLabelsLayout->setSpacing(0); 589 pFSLabelContainer->setLayout(pFSLabelsLayout); 590 m_pFSTitleLabel = new QLabel; 591 pFSLabelsLayout->addWidget(m_pFSTitleLabel); 592 m_pFSUsedLabel = new QLabel; 593 pFSLabelsLayout->addWidget(m_pFSUsedLabel); 594 m_pFSFreeLabel = new QLabel; 595 pFSLabelsLayout->addWidget(m_pFSFreeLabel); 596 m_pFSTotalLabel = new QLabel; 597 pFSLabelsLayout->addWidget(m_pFSTotalLabel); 598 599 m_pHostFSChart = new UIVMActivityOverviewDoughnutChart; 600 if (m_pHostFSChart) 601 { 602 m_pHostFSChart->setMinimumSize(iMinimumSize, iMinimumSize); 603 pLayout->addWidget(m_pHostFSChart); 604 m_pHostFSChart->setChartColors(m_RAMUsedColor, m_RAMFreeColor); 605 } 606 607 } 608 pLayout->addStretch(2); 609 } 610 611 void UIVMActivityOverviewHostStatsWidget::updateLabels() 612 { 613 if (m_pCPUTitleLabel) 614 m_pCPUTitleLabel->setText(QString("<b>%1</b>").arg(UIVMActivityOverviewWidget::tr("Host CPU Load"))); 615 if (m_pCPUUserLabel) 616 { 617 QString strColor = QColor(m_CPUUserColor).name(QColor::HexRgb); 618 m_pCPUUserLabel->setText(QString("<font color=\"%1\">%2: %3%</font>").arg(strColor).arg(UIVMActivityOverviewWidget::tr("User")).arg(QString::number(m_hostStats.m_iCPUUserLoad))); 619 } 620 if (m_pCPUKernelLabel) 621 { 622 QString strColor = QColor(m_CPUKernelColor).name(QColor::HexRgb); 623 m_pCPUKernelLabel->setText(QString("<font color=\"%1\">%2: %3%</font>").arg(strColor).arg(UIVMActivityOverviewWidget::tr("Kernel")).arg(QString::number(m_hostStats.m_iCPUKernelLoad))); 624 } 625 if (m_pCPUTotalLabel) 626 m_pCPUTotalLabel->setText(QString("%1: %2%").arg(UIVMActivityOverviewWidget::tr("Total")).arg(m_hostStats.m_iCPUUserLoad + m_hostStats.m_iCPUKernelLoad)); 627 if (m_pRAMTitleLabel) 628 m_pRAMTitleLabel->setText(QString("<b>%1</b>").arg(UIVMActivityOverviewWidget::tr("Host RAM Usage"))); 629 if (m_pRAMFreeLabel) 630 { 631 QString strRAM = uiCommon().formatSize(m_hostStats.m_iRAMFree); 632 QString strColor = QColor(m_RAMFreeColor).name(QColor::HexRgb); 633 m_pRAMFreeLabel->setText(QString("<font color=\"%1\">%2: %3</font>").arg(strColor).arg(UIVMActivityOverviewWidget::tr("Free")).arg(strRAM)); 634 } 635 if (m_pRAMUsedLabel) 636 { 637 QString strRAM = uiCommon().formatSize(m_hostStats.m_iRAMTotal - m_hostStats.m_iRAMFree); 638 QString strColor = QColor(m_RAMUsedColor).name(QColor::HexRgb); 639 m_pRAMUsedLabel->setText(QString("<font color=\"%1\">%2: %3</font>").arg(strColor).arg(UIVMActivityOverviewWidget::tr("Used")).arg(strRAM)); 640 } 641 if (m_pRAMTotalLabel) 642 { 643 QString strRAM = uiCommon().formatSize(m_hostStats.m_iRAMTotal); 644 m_pRAMTotalLabel->setText(QString("%1: %2").arg(UIVMActivityOverviewWidget::tr("Total")).arg(strRAM)); 645 } 646 if (m_pFSTitleLabel) 647 m_pFSTitleLabel->setText(QString("<b>%1</b>").arg(UIVMActivityOverviewWidget::tr("Host File System"))); 648 if (m_pFSFreeLabel) 649 { 650 QString strFS = uiCommon().formatSize(m_hostStats.m_iFSFree); 651 QString strColor = QColor(m_RAMFreeColor).name(QColor::HexRgb); 652 m_pFSFreeLabel->setText(QString("<font color=\"%1\">%2: %3</font>").arg(strColor).arg(UIVMActivityOverviewWidget::tr("Free")).arg(strFS)); 653 } 654 if (m_pFSUsedLabel) 655 { 656 QString strFS = uiCommon().formatSize(m_hostStats.m_iFSTotal - m_hostStats.m_iFSFree); 657 QString strColor = QColor(m_RAMUsedColor).name(QColor::HexRgb); 658 m_pFSUsedLabel->setText(QString("<font color=\"%1\">%2: %3</font>").arg(strColor).arg(UIVMActivityOverviewWidget::tr("Used")).arg(strFS)); 659 } 660 if (m_pFSTotalLabel) 661 { 662 QString strFS = uiCommon().formatSize(m_hostStats.m_iFSTotal); 663 m_pFSTotalLabel->setText(QString("%1: %2").arg(UIVMActivityOverviewWidget::tr("Total")).arg(strFS)); 664 } 665 } 666 667 668 669 /********************************************************************************************************************************* 670 * Class UIVMActivityOverviewTableView implementation. * 671 *********************************************************************************************************************************/ 672 673 UIVMActivityOverviewTableView::UIVMActivityOverviewTableView(QWidget *pParent /* = 0 */) 674 :QTableView(pParent) 675 { 676 } 677 678 void UIVMActivityOverviewTableView::setMinimumColumnWidths(const QMap<int, int>& widths) 679 { 680 m_minimumColumnWidths = widths; 681 resizeHeaders(); 682 } 683 684 void UIVMActivityOverviewTableView::updateColumVisibility() 685 { 686 UIActivityOverviewProxyModel *pProxyModel = qobject_cast<UIActivityOverviewProxyModel *>(model()); 687 if (!pProxyModel) 688 return; 689 UIActivityOverviewModel *pModel = qobject_cast<UIActivityOverviewModel *>(pProxyModel->sourceModel()); 690 QHeaderView *pHeader = horizontalHeader(); 691 692 if (!pModel || !pHeader) 693 return; 694 for (int i = (int)VMActivityOverviewColumn_Name; i < (int)VMActivityOverviewColumn_Max; ++i) 695 { 696 if (!pModel->columnVisible(i)) 697 pHeader->hideSection(i); 698 else 699 pHeader->showSection(i); 700 } 701 resizeHeaders(); 702 } 703 704 int UIVMActivityOverviewTableView::selectedItemIndex() const 705 { 706 UIActivityOverviewProxyModel *pModel = qobject_cast<UIActivityOverviewProxyModel*>(model()); 707 if (!pModel) 708 return -1; 709 710 QItemSelectionModel *pSelectionModel = selectionModel(); 711 if (!pSelectionModel) 712 return -1; 713 QModelIndexList selectedItemIndices = pSelectionModel->selectedRows(); 714 if (selectedItemIndices.isEmpty()) 715 return -1; 716 717 /* just use the the 1st index: */ 718 QModelIndex modelIndex = pModel->mapToSource(selectedItemIndices[0]); 719 720 if (!modelIndex.isValid()) 721 return -1; 722 return modelIndex.row(); 723 } 724 725 bool UIVMActivityOverviewTableView::hasSelection() const 726 { 727 if (!selectionModel()) 728 return false; 729 return selectionModel()->hasSelection(); 730 } 731 732 void UIVMActivityOverviewTableView::resizeEvent(QResizeEvent *pEvent) 733 { 734 resizeHeaders(); 735 QTableView::resizeEvent(pEvent); 736 } 737 738 void UIVMActivityOverviewTableView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) 739 { 740 emit sigSelectionChanged(selected, deselected); 741 QTableView::selectionChanged(selected, deselected); 742 } 743 744 void UIVMActivityOverviewTableView::mousePressEvent(QMouseEvent *pEvent) 745 { 746 if (!indexAt(pEvent->pos()).isValid()) 747 clearSelection(); 748 QTableView::mousePressEvent(pEvent); 749 } 750 751 void UIVMActivityOverviewTableView::resizeHeaders() 752 { 753 QHeaderView* pHeader = horizontalHeader(); 754 if (!pHeader) 755 return; 756 int iSectionCount = pHeader->count(); 757 int iHiddenSectionCount = pHeader->hiddenSectionCount(); 758 int iWidth = width() / (iSectionCount - iHiddenSectionCount); 759 for (int i = 0; i < iSectionCount; ++i) 760 { 761 if (pHeader->isSectionHidden(i)) 762 continue; 763 int iMinWidth = m_minimumColumnWidths.value((VMActivityOverviewColumn)i, 0); 764 pHeader->resizeSection(i, iWidth < iMinWidth ? iMinWidth : iWidth); 765 } 766 } 767 768 769 /********************************************************************************************************************************* 770 * Class UIVMActivityOverviewItem implementation. * 771 *********************************************************************************************************************************/ 772 UIActivityOverviewItem::UIActivityOverviewItem(const QUuid &uid, const QString &strVMName, KMachineState enmState) 773 : m_VMuid(uid) 774 , m_strVMName(strVMName) 775 , m_enmMachineState(enmState) 776 , m_uCPUGuestLoad(0) 777 , m_uCPUVMMLoad(0) 778 , m_uTotalRAM(0) 779 , m_uFreeRAM(0) 780 , m_uUsedRAM(0) 781 , m_fRAMUsagePercentage(0) 782 , m_uNetworkDownRate(0) 783 , m_uNetworkUpRate(0) 784 , m_uNetworkDownTotal(0) 785 , m_uNetworkUpTotal(0) 786 , m_uDiskWriteRate(0) 787 , m_uDiskReadRate(0) 788 , m_uDiskWriteTotal(0) 789 , m_uDiskReadTotal(0) 790 , m_uVMExitRate(0) 791 , m_uVMExitTotal(0) 792 { 793 resetDebugger(); 794 } 795 796 UIActivityOverviewItem::UIActivityOverviewItem() 797 : m_VMuid(QUuid()) 798 , m_uCPUGuestLoad(0) 799 , m_uCPUVMMLoad(0) 800 , m_uTotalRAM(0) 801 , m_uUsedRAM(0) 802 , m_fRAMUsagePercentage(0) 803 , m_uNetworkDownRate(0) 804 , m_uNetworkUpRate(0) 805 , m_uNetworkDownTotal(0) 806 , m_uNetworkUpTotal(0) 807 , m_uDiskWriteRate(0) 808 , m_uDiskReadRate(0) 809 , m_uDiskWriteTotal(0) 810 , m_uDiskReadTotal(0) 811 , m_uVMExitRate(0) 812 , m_uVMExitTotal(0) 813 { 814 } 815 816 void UIActivityOverviewItem::resetDebugger() 817 { 818 m_comSession = uiCommon().openSession(m_VMuid, KLockType_Shared); 819 if (!m_comSession.isNull()) 820 { 821 CConsole comConsole = m_comSession.GetConsole(); 822 if (!comConsole.isNull()) 823 { 824 m_comGuest = comConsole.GetGuest(); 825 m_comDebugger = comConsole.GetDebugger(); 826 } 827 } 828 } 829 830 UIActivityOverviewItem::~UIActivityOverviewItem() 831 { 832 if (!m_comSession.isNull()) 833 m_comSession.UnlockMachine(); 834 } 835 836 bool UIActivityOverviewItem::operator==(const UIActivityOverviewItem& other) const 837 { 838 if (m_VMuid == other.m_VMuid) 839 return true; 840 return false; 841 } 842 843 bool UIActivityOverviewItem::isWithGuestAdditions() 844 { 845 if (m_comGuest.isNull()) 846 return false; 847 return m_comGuest.GetAdditionsStatus(m_comGuest.GetAdditionsRunLevel()); 848 } 849 850 851 /********************************************************************************************************************************* 852 * Class UIVMActivityOverviewHostStats implementation. * 853 *********************************************************************************************************************************/ 854 855 UIVMActivityOverviewHostStats::UIVMActivityOverviewHostStats() 856 : m_iCPUUserLoad(0) 857 , m_iCPUKernelLoad(0) 858 , m_iCPUFreq(0) 859 , m_iRAMTotal(0) 860 , m_iRAMFree(0) 861 , m_iFSTotal(0) 862 , m_iFSFree(0) 863 { 864 } 865 866 867 /********************************************************************************************************************************* 868 * Class UIVMActivityOverviewProxyModel implementation. * 869 *********************************************************************************************************************************/ 870 UIActivityOverviewProxyModel::UIActivityOverviewProxyModel(QObject *parent /* = 0 */) 871 :QSortFilterProxyModel(parent) 872 { 873 } 874 875 void UIActivityOverviewProxyModel::dataUpdate() 876 { 877 if (sourceModel()) 878 emit dataChanged(index(0,0), index(sourceModel()->rowCount(), sourceModel()->columnCount())); 879 invalidate(); 880 } 881 882 void UIActivityOverviewProxyModel::setNotRunningVMVisibility(bool fShow) 883 { 884 m_fShowNotRunningVMs = fShow; 885 invalidateFilter(); 886 } 887 888 889 bool UIActivityOverviewProxyModel::lessThan(const QModelIndex &sourceLeftIndex, const QModelIndex &sourceRightIndex) const 890 { 891 UIActivityOverviewModel *pModel = qobject_cast<UIActivityOverviewModel*>(sourceModel()); 892 if (pModel) 893 { 894 KMachineState enmLeftState = pModel->machineState(sourceLeftIndex.row()); 895 KMachineState enmRightState = pModel->machineState(sourceRightIndex.row()); 896 if ((enmLeftState == KMachineState_Running) && (enmRightState != KMachineState_Running)) 897 { 898 if (sortOrder() == Qt::AscendingOrder) 899 return true; 900 else 901 return false; 902 } 903 if ((enmLeftState != KMachineState_Running) && (enmRightState == KMachineState_Running)) 904 { 905 if (sortOrder() == Qt::AscendingOrder) 906 return false; 907 else 908 return true; 909 } 910 911 } 912 return QSortFilterProxyModel::lessThan(sourceLeftIndex, sourceRightIndex); 913 } 914 915 bool UIActivityOverviewProxyModel::filterAcceptsRow(int iSourceRow, const QModelIndex &sourceParent) const 916 { 917 Q_UNUSED(sourceParent); 918 if (m_fShowNotRunningVMs) 919 return true; 920 UIActivityOverviewModel *pModel = qobject_cast<UIActivityOverviewModel*>(sourceModel()); 921 if (!pModel) 922 return true; 923 if (pModel->machineState(iSourceRow) != KMachineState_Running) 924 return false; 925 return true; 926 } 927 928 929 /********************************************************************************************************************************* 930 * Class UIActivityOverviewModel implementation. * 931 *********************************************************************************************************************************/ 932 UIActivityOverviewModel::UIActivityOverviewModel(QObject *parent /*= 0*/) 933 :QAbstractTableModel(parent) 934 , m_pTimer(new QTimer(this)) 935 , m_fShouldUpdate(true) 936 { 937 initialize(); 938 } 939 940 void UIActivityOverviewModel::initialize() 941 { 942 for (int i = 0; i < (int)VMActivityOverviewColumn_Max; ++i) 943 m_columnDataMaxLength[i] = 0; 944 945 initializeItems(); 946 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigMachineStateChange, 947 this, &UIActivityOverviewModel::sltMachineStateChanged); 948 connect(gVBoxEvents, &UIVirtualBoxEventHandler::sigMachineRegistered, 949 this, &UIActivityOverviewModel::sltMachineRegistered); 950 if (m_pTimer) 951 { 952 connect(m_pTimer, &QTimer::timeout, this, &UIActivityOverviewModel::sltTimeout); 953 m_pTimer->start(1000); 954 } 955 } 956 957 int UIActivityOverviewModel::rowCount(const QModelIndex &parent /* = QModelIndex() */) const 958 { 959 Q_UNUSED(parent); 960 return m_itemList.size(); 961 } 962 963 int UIActivityOverviewModel::columnCount(const QModelIndex &parent /* = QModelIndex() */) const 964 { 965 Q_UNUSED(parent); 966 return VMActivityOverviewColumn_Max; 967 } 968 969 void UIActivityOverviewModel::setShouldUpdate(bool fShouldUpdate) 970 { 971 m_fShouldUpdate = fShouldUpdate; 972 } 973 974 const QMap<int, int> UIActivityOverviewModel::dataLengths() const 975 { 976 return m_columnDataMaxLength; 977 } 978 979 QUuid UIActivityOverviewModel::itemUid(int iIndex) 980 { 981 if (iIndex >= m_itemList.size()) 982 return QUuid(); 983 return m_itemList[iIndex].m_VMuid; 984 } 985 986 int UIActivityOverviewModel::itemIndex(const QUuid &uid) 987 { 988 for (int i = 0; i < m_itemList.size(); ++i) 989 { 990 if (m_itemList[i].m_VMuid == uid) 991 return i; 992 } 993 return -1; 994 } 995 996 KMachineState UIActivityOverviewModel::machineState(int rowIndex) const 997 { 998 if (rowIndex >= m_itemList.size() || rowIndex < 0) 999 return KMachineState_Null; 1000 return m_itemList[rowIndex].m_enmMachineState; 1001 } 1002 1003 void UIActivityOverviewModel::setDefaultViewFont(const QFont &font) 1004 { 1005 m_defaultViewFont = font; 1006 } 1007 1008 void UIActivityOverviewModel::setDefaultViewFontColor(const QColor &color) 1009 { 1010 m_defaultViewFontColor = color; 1011 } 1012 1013 QVariant UIActivityOverviewModel::data(const QModelIndex &index, int role) const 1014 { 1015 if (machineState(index.row()) != KMachineState_Running) 1016 { 1017 if (role == Qt::FontRole) 1018 { 1019 QFont font(m_defaultViewFont); 1020 font.setItalic(true); 1021 return font; 1022 } 1023 if (role == Qt::ForegroundRole) 1024 return m_defaultViewFontColor.lighter(250); 1025 } 1026 if (!index.isValid() || role != Qt::DisplayRole || index.row() >= rowCount()) 1027 return QVariant(); 1028 if (index.column() == VMActivityOverviewColumn_Name) 1029 return m_itemList[index.row()].m_columnData[index.column()]; 1030 if (m_itemList[index.row()].m_enmMachineState != KMachineState_Running) 1031 return gpConverter->toString(m_itemList[index.row()].m_enmMachineState); 1032 return m_itemList[index.row()].m_columnData[index.column()]; 1033 } 1034 1035 void UIActivityOverviewModel::clearData() 1036 { 1037 /* We have a request to detach COM stuff, 1038 * first of all we are removing all the items, 1039 * this will detach COM wrappers implicitly: */ 1040 m_itemList.clear(); 1041 /* Detaching perf. collector finally, 1042 * please do not use it after all: */ 1043 m_performanceCollector.detach(); 1044 } 1045 1046 QVariant UIActivityOverviewModel::headerData(int section, Qt::Orientation orientation, int role) const 1047 { 1048 if (role == Qt::DisplayRole && orientation == Qt::Horizontal) 1049 return m_columnTitles.value((VMActivityOverviewColumn)section, QString());; 1050 return QVariant(); 1051 } 1052 1053 void UIActivityOverviewModel::setColumnCaptions(const QMap<int, QString>& captions) 1054 { 1055 m_columnTitles = captions; 1056 } 1057 1058 void UIActivityOverviewModel::initializeItems() 1059 { 1060 foreach (const CMachine &comMachine, uiCommon().virtualBox().GetMachines()) 1061 { 1062 if (!comMachine.isNull()) 1063 addItem(comMachine.GetId(), comMachine.GetName(), comMachine.GetState()); 1064 } 1065 setupPerformanceCollector(); 1066 } 1067 1068 void UIActivityOverviewModel::sltMachineStateChanged(const QUuid &uId, const KMachineState state) 1069 { 1070 int iIndex = itemIndex(uId); 1071 if (iIndex != -1 && iIndex < m_itemList.size()) 1072 { 1073 m_itemList[iIndex].m_enmMachineState = state; 1074 if (state == KMachineState_Running) 1075 m_itemList[iIndex].resetDebugger(); 1076 } 1077 } 1078 1079 void UIActivityOverviewModel::sltMachineRegistered(const QUuid &uId, bool fRegistered) 1080 { 1081 if (fRegistered) 1082 { 1083 CMachine comMachine = uiCommon().virtualBox().FindMachine(uId.toString()); 1084 if (!comMachine.isNull()) 1085 addItem(uId, comMachine.GetName(), comMachine.GetState()); 1086 } 1087 else 1088 removeItem(uId); 1089 emit sigDataUpdate(); 1090 } 1091 1092 void UIActivityOverviewModel::getHostRAMStats() 1093 { 1094 CHost comHost = uiCommon().host(); 1095 m_hostStats.m_iRAMTotal = _1M * (quint64)comHost.GetMemorySize(); 1096 m_hostStats.m_iRAMFree = _1M * (quint64)comHost.GetMemoryAvailable(); 1097 } 1098 1099 void UIActivityOverviewModel::sltTimeout() 1100 { 1101 if (!m_fShouldUpdate) 1102 return; 1103 ULONG aPctExecuting; 1104 ULONG aPctHalted; 1105 ULONG aPctVMM; 1106 1107 bool fCPUColumns = columnVisible(VMActivityOverviewColumn_CPUVMMLoad) || columnVisible(VMActivityOverviewColumn_CPUGuestLoad); 1108 bool fNetworkColumns = columnVisible(VMActivityOverviewColumn_NetworkUpRate) 1109 || columnVisible(VMActivityOverviewColumn_NetworkDownRate) 1110 || columnVisible(VMActivityOverviewColumn_NetworkUpTotal) 1111 || columnVisible(VMActivityOverviewColumn_NetworkDownTotal); 1112 bool fIOColumns = columnVisible(VMActivityOverviewColumn_DiskIOReadRate) 1113 || columnVisible(VMActivityOverviewColumn_DiskIOWriteRate) 1114 || columnVisible(VMActivityOverviewColumn_DiskIOReadTotal) 1115 || columnVisible(VMActivityOverviewColumn_DiskIOWriteTotal); 1116 bool fVMExitColumn = columnVisible(VMActivityOverviewColumn_VMExits); 1117 1118 /* Host's RAM usage is obtained from IHost not from IPerformanceCollectior: */ 1119 getHostRAMStats(); 1120 1121 /* RAM usage and Host Stats: */ 1122 queryPerformanceCollector(); 1123 1124 for (int i = 0; i < m_itemList.size(); ++i) 1125 { 1126 if (!m_itemList[i].m_comDebugger.isNull()) 1127 { 1128 /* CPU Load: */ 1129 if (fCPUColumns) 1130 { 1131 m_itemList[i].m_comDebugger.GetCPULoad(0x7fffffff, aPctExecuting, aPctHalted, aPctVMM); 1132 m_itemList[i].m_uCPUGuestLoad = aPctExecuting; 1133 m_itemList[i].m_uCPUVMMLoad = aPctVMM; 1134 } 1135 /* Network rate: */ 1136 if (fNetworkColumns) 1137 { 1138 quint64 uPrevDownTotal = m_itemList[i].m_uNetworkDownTotal; 1139 quint64 uPrevUpTotal = m_itemList[i].m_uNetworkUpTotal; 1140 UIMonitorCommon::getNetworkLoad(m_itemList[i].m_comDebugger, 1141 m_itemList[i].m_uNetworkDownTotal, m_itemList[i].m_uNetworkUpTotal); 1142 m_itemList[i].m_uNetworkDownRate = m_itemList[i].m_uNetworkDownTotal - uPrevDownTotal; 1143 m_itemList[i].m_uNetworkUpRate = m_itemList[i].m_uNetworkUpTotal - uPrevUpTotal; 1144 } 1145 /* IO rate: */ 1146 if (fIOColumns) 1147 { 1148 quint64 uPrevWriteTotal = m_itemList[i].m_uDiskWriteTotal; 1149 quint64 uPrevReadTotal = m_itemList[i].m_uDiskReadTotal; 1150 UIMonitorCommon::getDiskLoad(m_itemList[i].m_comDebugger, 1151 m_itemList[i].m_uDiskWriteTotal, m_itemList[i].m_uDiskReadTotal); 1152 m_itemList[i].m_uDiskWriteRate = m_itemList[i].m_uDiskWriteTotal - uPrevWriteTotal; 1153 m_itemList[i].m_uDiskReadRate = m_itemList[i].m_uDiskReadTotal - uPrevReadTotal; 1154 } 1155 /* VM Exits: */ 1156 if (fVMExitColumn) 1157 { 1158 quint64 uPrevVMExitsTotal = m_itemList[i].m_uVMExitTotal; 1159 UIMonitorCommon::getVMMExitCount(m_itemList[i].m_comDebugger, m_itemList[i].m_uVMExitTotal); 1160 m_itemList[i].m_uVMExitRate = m_itemList[i].m_uVMExitTotal - uPrevVMExitsTotal; 1161 } 1162 } 1163 } 1164 int iDecimalCount = 2; 1165 for (int i = 0; i < m_itemList.size(); ++i) 1166 { 1167 m_itemList[i].m_columnData[VMActivityOverviewColumn_Name] = m_itemList[i].m_strVMName; 1168 m_itemList[i].m_columnData[VMActivityOverviewColumn_CPUGuestLoad] = 1169 QString("%1%").arg(QString::number(m_itemList[i].m_uCPUGuestLoad)); 1170 m_itemList[i].m_columnData[VMActivityOverviewColumn_CPUVMMLoad] = 1171 QString("%1%").arg(QString::number(m_itemList[i].m_uCPUVMMLoad)); 1172 1173 if (m_itemList[i].isWithGuestAdditions()) 1174 m_itemList[i].m_columnData[VMActivityOverviewColumn_RAMUsedAndTotal] = 1175 QString("%1/%2").arg(uiCommon().formatSize(_1K * m_itemList[i].m_uUsedRAM, iDecimalCount)). 1176 arg(uiCommon().formatSize(_1K * m_itemList[i].m_uTotalRAM, iDecimalCount)); 1177 else 1178 m_itemList[i].m_columnData[VMActivityOverviewColumn_RAMUsedAndTotal] = UIVMActivityOverviewWidget::tr("N/A"); 1179 1180 if (m_itemList[i].isWithGuestAdditions()) 1181 m_itemList[i].m_columnData[VMActivityOverviewColumn_RAMUsedPercentage] = 1182 QString("%1%").arg(QString::number(m_itemList[i].m_fRAMUsagePercentage, 'f', 2)); 1183 else 1184 m_itemList[i].m_columnData[VMActivityOverviewColumn_RAMUsedPercentage] = UIVMActivityOverviewWidget::tr("N/A"); 1185 1186 m_itemList[i].m_columnData[VMActivityOverviewColumn_NetworkUpRate] = 1187 QString("%1").arg(uiCommon().formatSize(m_itemList[i].m_uNetworkUpRate, iDecimalCount)); 1188 1189 m_itemList[i].m_columnData[VMActivityOverviewColumn_NetworkDownRate] = 1190 QString("%1").arg(uiCommon().formatSize(m_itemList[i].m_uNetworkDownRate, iDecimalCount)); 1191 1192 m_itemList[i].m_columnData[VMActivityOverviewColumn_NetworkUpTotal] = 1193 QString("%1").arg(uiCommon().formatSize(m_itemList[i].m_uNetworkUpTotal, iDecimalCount)); 1194 1195 m_itemList[i].m_columnData[VMActivityOverviewColumn_NetworkDownTotal] = 1196 QString("%1").arg(uiCommon().formatSize(m_itemList[i].m_uNetworkDownTotal, iDecimalCount)); 1197 1198 m_itemList[i].m_columnData[VMActivityOverviewColumn_DiskIOReadRate] = 1199 QString("%1").arg(uiCommon().formatSize(m_itemList[i].m_uDiskReadRate, iDecimalCount)); 1200 1201 m_itemList[i].m_columnData[VMActivityOverviewColumn_DiskIOWriteRate] = 1202 QString("%1").arg(uiCommon().formatSize(m_itemList[i].m_uDiskWriteRate, iDecimalCount)); 1203 1204 m_itemList[i].m_columnData[VMActivityOverviewColumn_DiskIOReadTotal] = 1205 QString("%1").arg(uiCommon().formatSize(m_itemList[i].m_uDiskReadTotal, iDecimalCount)); 1206 1207 m_itemList[i].m_columnData[VMActivityOverviewColumn_DiskIOWriteTotal] = 1208 QString("%1").arg(uiCommon().formatSize(m_itemList[i].m_uDiskWriteTotal, iDecimalCount)); 1209 1210 m_itemList[i].m_columnData[VMActivityOverviewColumn_VMExits] = 1211 QString("%1/%2").arg(UICommon::addMetricSuffixToNumber(m_itemList[i].m_uVMExitRate)). 1212 arg(UICommon::addMetricSuffixToNumber(m_itemList[i].m_uVMExitTotal)); 1213 } 1214 1215 for (int i = 0; i < (int)VMActivityOverviewColumn_Max; ++i) 1216 { 1217 for (int j = 0; j < m_itemList.size(); ++j) 1218 if (m_columnDataMaxLength.value(i, 0) < m_itemList[j].m_columnData[i].length()) 1219 m_columnDataMaxLength[i] = m_itemList[j].m_columnData[i].length(); 1220 } 1221 emit sigDataUpdate(); 1222 emit sigHostStatsUpdate(m_hostStats); 1223 } 1224 1225 void UIActivityOverviewModel::setupPerformanceCollector() 1226 { 1227 m_nameList.clear(); 1228 m_objectList.clear(); 1229 /* Initialize and configure CPerformanceCollector: */ 1230 const ULONG iPeriod = 1; 1231 const int iMetricSetupCount = 1; 1232 if (m_performanceCollector.isNull()) 1233 m_performanceCollector = uiCommon().virtualBox().GetPerformanceCollector(); 1234 for (int i = 0; i < m_itemList.size(); ++i) 1235 m_nameList << "Guest/RAM/Usage*"; 1236 /* This is for the host: */ 1237 m_nameList << "CPU*"; 1238 m_nameList << "FS*"; 1239 m_objectList = QVector<CUnknown>(m_nameList.size(), CUnknown()); 1240 m_performanceCollector.SetupMetrics(m_nameList, m_objectList, iPeriod, iMetricSetupCount); 1241 } 1242 1243 void UIActivityOverviewModel::queryPerformanceCollector() 1244 { 1245 QVector<QString> aReturnNames; 1246 QVector<CUnknown> aReturnObjects; 1247 QVector<QString> aReturnUnits; 1248 QVector<ULONG> aReturnScales; 1249 QVector<ULONG> aReturnSequenceNumbers; 1250 QVector<ULONG> aReturnDataIndices; 1251 QVector<ULONG> aReturnDataLengths; 1252 1253 QVector<LONG> returnData = m_performanceCollector.QueryMetricsData(m_nameList, 1254 m_objectList, 1255 aReturnNames, 1256 aReturnObjects, 1257 aReturnUnits, 1258 aReturnScales, 1259 aReturnSequenceNumbers, 1260 aReturnDataIndices, 1261 aReturnDataLengths); 1262 /* Parse the result we get from CPerformanceCollector to get respective values: */ 1263 for (int i = 0; i < aReturnNames.size(); ++i) 1264 { 1265 if (aReturnDataLengths[i] == 0) 1266 continue; 1267 /* Read the last of the return data disregarding the rest since we are caching the data in GUI side: */ 1268 float fData = returnData[aReturnDataIndices[i] + aReturnDataLengths[i] - 1] / (float)aReturnScales[i]; 1269 if (aReturnNames[i].contains("RAM", Qt::CaseInsensitive) && !aReturnNames[i].contains(":")) 1270 { 1271 if (aReturnNames[i].contains("Total", Qt::CaseInsensitive) || aReturnNames[i].contains("Free", Qt::CaseInsensitive)) 1272 { 1273 { 1274 CMachine comMachine = (CMachine)aReturnObjects[i]; 1275 if (comMachine.isNull()) 1276 continue; 1277 int iIndex = itemIndex(comMachine.GetId()); 1278 if (iIndex == -1 || iIndex >= m_itemList.size()) 1279 continue; 1280 if (aReturnNames[i].contains("Total", Qt::CaseInsensitive)) 1281 m_itemList[iIndex].m_uTotalRAM = fData; 1282 else 1283 m_itemList[iIndex].m_uFreeRAM = fData; 1284 } 1285 } 1286 } 1287 else if (aReturnNames[i].contains("CPU/Load/User", Qt::CaseInsensitive) && !aReturnNames[i].contains(":")) 1288 { 1289 CHost comHost = (CHost)aReturnObjects[i]; 1290 if (!comHost.isNull()) 1291 m_hostStats.m_iCPUUserLoad = fData; 1292 } 1293 else if (aReturnNames[i].contains("CPU/Load/Kernel", Qt::CaseInsensitive) && !aReturnNames[i].contains(":")) 1294 { 1295 CHost comHost = (CHost)aReturnObjects[i]; 1296 if (!comHost.isNull()) 1297 m_hostStats.m_iCPUKernelLoad = fData; 1298 } 1299 else if (aReturnNames[i].contains("CPU/MHz", Qt::CaseInsensitive) && !aReturnNames[i].contains(":")) 1300 { 1301 CHost comHost = (CHost)aReturnObjects[i]; 1302 if (!comHost.isNull()) 1303 m_hostStats.m_iCPUFreq = fData; 1304 } 1305 else if (aReturnNames[i].contains("FS", Qt::CaseInsensitive) && 1306 aReturnNames[i].contains("Total", Qt::CaseInsensitive) && 1307 !aReturnNames[i].contains(":")) 1308 { 1309 CHost comHost = (CHost)aReturnObjects[i]; 1310 if (!comHost.isNull()) 1311 m_hostStats.m_iFSTotal = _1M * fData; 1312 } 1313 else if (aReturnNames[i].contains("FS", Qt::CaseInsensitive) && 1314 aReturnNames[i].contains("Free", Qt::CaseInsensitive) && 1315 !aReturnNames[i].contains(":")) 1316 { 1317 CHost comHost = (CHost)aReturnObjects[i]; 1318 if (!comHost.isNull()) 1319 m_hostStats.m_iFSFree = _1M * fData; 1320 } 1321 } 1322 for (int i = 0; i < m_itemList.size(); ++i) 1323 { 1324 m_itemList[i].m_uUsedRAM = m_itemList[i].m_uTotalRAM - m_itemList[i].m_uFreeRAM; 1325 if (m_itemList[i].m_uTotalRAM != 0) 1326 m_itemList[i].m_fRAMUsagePercentage = 100.f * (m_itemList[i].m_uUsedRAM / (float)m_itemList[i].m_uTotalRAM); 1327 } 1328 } 1329 1330 void UIActivityOverviewModel::addItem(const QUuid& uMachineId, const QString& strMachineName, KMachineState enmState) 1331 { 1332 m_itemList.append(UIActivityOverviewItem(uMachineId, strMachineName, enmState)); 1333 } 1334 1335 void UIActivityOverviewModel::removeItem(const QUuid& uMachineId) 1336 { 1337 int iIndex = itemIndex(uMachineId); 1338 if (iIndex == -1) 1339 return; 1340 m_itemList.remove(iIndex); 1341 } 1342 1343 void UIActivityOverviewModel::setColumnVisible(const QMap<int, bool>& columnVisible) 1344 { 1345 m_columnVisible = columnVisible; 1346 } 1347 1348 bool UIActivityOverviewModel::columnVisible(int iColumnId) const 1349 { 1350 return m_columnVisible.value(iColumnId, true); 1351 } 1352 1353 1354 /********************************************************************************************************************************* 1355 * Class UIVMActivityOverviewWidget implementation. * 1356 *********************************************************************************************************************************/ 1357 1358 UIVMActivityOverviewWidget::UIVMActivityOverviewWidget(EmbedTo enmEmbedding, UIActionPool *pActionPool, 63 UIVMActivityListWidget::UIVMActivityListWidget(EmbedTo enmEmbedding, UIActionPool *pActionPool, 1359 64 bool fShowToolbar /* = true */, QWidget *pParent /* = 0 */) 1360 65 : QIWithRetranslateUI<QWidget>(pParent) … … 1363 68 , m_fShowToolbar(fShowToolbar) 1364 69 , m_pToolBar(0) 1365 , m_pTableView(0)1366 , m_pProxyModel(0)1367 , m_pModel(0)1368 , m_pColumnVisibilityToggleMenu(0)1369 , m_pHostStatsWidget(0)1370 , m_fIsCurrentTool(true)1371 , m_iSortIndicatorWidth(0)1372 , m_fShowNotRunningVMs(false)1373 70 { 1374 71 prepare(); 1375 72 } 1376 73 1377 QMenu *UIVMActivity OverviewWidget::menu() const74 QMenu *UIVMActivityListWidget::menu() const 1378 75 { 1379 76 return NULL; 1380 77 } 1381 78 1382 QMenu *UIVMActivityOverviewWidget::columnVisiblityToggleMenu() const 1383 { 1384 return m_pColumnVisibilityToggleMenu; 1385 } 1386 1387 bool UIVMActivityOverviewWidget::isCurrentTool() const 79 bool UIVMActivityListWidget::isCurrentTool() const 1388 80 { 1389 81 return m_fIsCurrentTool; 1390 82 } 1391 83 1392 void UIVMActivity OverviewWidget::setIsCurrentTool(bool fIsCurrentTool)84 void UIVMActivityListWidget::setIsCurrentTool(bool fIsCurrentTool) 1393 85 { 1394 86 m_fIsCurrentTool = fIsCurrentTool; 1395 if (m_pModel)1396 m_pModel->setShouldUpdate(fIsCurrentTool);1397 87 } 1398 88 1399 void UIVMActivity OverviewWidget::retranslateUi()89 void UIVMActivityListWidget::retranslateUi() 1400 90 { 1401 m_columnTitles[VMActivityOverviewColumn_Name] = UIVMActivityOverviewWidget::tr("VM Name");1402 m_columnTitles[VMActivityOverviewColumn_CPUGuestLoad] = UIVMActivityOverviewWidget::tr("CPU Guest");1403 m_columnTitles[VMActivityOverviewColumn_CPUVMMLoad] = UIVMActivityOverviewWidget::tr("CPU VMM");1404 m_columnTitles[VMActivityOverviewColumn_RAMUsedAndTotal] = UIVMActivityOverviewWidget::tr("RAM Used/Total");1405 m_columnTitles[VMActivityOverviewColumn_RAMUsedPercentage] = UIVMActivityOverviewWidget::tr("RAM %");1406 m_columnTitles[VMActivityOverviewColumn_NetworkUpRate] = UIVMActivityOverviewWidget::tr("Network Up Rate");1407 m_columnTitles[VMActivityOverviewColumn_NetworkDownRate] = UIVMActivityOverviewWidget::tr("Network Down Rate");1408 m_columnTitles[VMActivityOverviewColumn_NetworkUpTotal] = UIVMActivityOverviewWidget::tr("Network Up Total");1409 m_columnTitles[VMActivityOverviewColumn_NetworkDownTotal] = UIVMActivityOverviewWidget::tr("Network Down Total");1410 m_columnTitles[VMActivityOverviewColumn_DiskIOReadRate] = UIVMActivityOverviewWidget::tr("Disk Read Rate");1411 m_columnTitles[VMActivityOverviewColumn_DiskIOWriteRate] = UIVMActivityOverviewWidget::tr("Disk Write Rate");1412 m_columnTitles[VMActivityOverviewColumn_DiskIOReadTotal] = UIVMActivityOverviewWidget::tr("Disk Read Total");1413 m_columnTitles[VMActivityOverviewColumn_DiskIOWriteTotal] = UIVMActivityOverviewWidget::tr("Disk Write Total");1414 m_columnTitles[VMActivityOverviewColumn_VMExits] = UIVMActivityOverviewWidget::tr("VM Exits");1415 1416 updateColumnsMenu();1417 1418 if (m_pModel)1419 m_pModel->setColumnCaptions(m_columnTitles);1420 1421 computeMinimumColumnWidths();1422 91 } 1423 92 1424 void UIVMActivity OverviewWidget::showEvent(QShowEvent *pEvent)93 void UIVMActivityListWidget::showEvent(QShowEvent *pEvent) 1425 94 { 1426 if (m_pVMActivityMonitorAction && m_pTableView)1427 m_pVMActivityMonitorAction->setEnabled(m_pTableView->hasSelection());1428 1429 95 QIWithRetranslateUI<QWidget>::showEvent(pEvent); 1430 96 } 1431 97 1432 void UIVMActivity OverviewWidget::prepare()98 void UIVMActivityListWidget::prepare() 1433 99 { 1434 /* Try to guest the sort indicator's width: */1435 int iIndicatorMargin = 3;1436 QIcon sortIndicator = qApp->QApplication::style()->standardIcon(QStyle::SP_TitleBarUnshadeButton);1437 QList<QSize> iconSizes = sortIndicator.availableSizes();1438 foreach(const QSize &msize, iconSizes)1439 m_iSortIndicatorWidth = qMax(m_iSortIndicatorWidth, msize.width());1440 if (m_iSortIndicatorWidth == 0)1441 m_iSortIndicatorWidth = 20;1442 m_iSortIndicatorWidth += 2 * iIndicatorMargin;1443 1444 prepareWidgets();1445 loadSettings();1446 prepareActions();1447 retranslateUi();1448 updateModelColumVisibilityCache();1449 uiCommon().setHelpKeyword(this, "vm-activity-overview-widget");1450 connect(&uiCommon(), &UICommon::sigAskToCommitData,1451 this, &UIVMActivityOverviewWidget::sltSaveSettings);1452 connect(&uiCommon(), &UICommon::sigAskToDetachCOM,1453 this, &UIVMActivityOverviewWidget::sltClearCOMData);1454 100 } 1455 101 1456 void UIVMActivity OverviewWidget::prepareWidgets()102 void UIVMActivityListWidget::prepareWidgets() 1457 103 { 1458 /* Create main-layout: */1459 new QVBoxLayout(this);1460 if (!layout())1461 return;1462 /* Configure layout: */1463 layout()->setContentsMargins(0, 0, 0, 0);1464 #ifdef VBOX_WS_MAC1465 layout()->setSpacing(10);1466 #else1467 layout()->setSpacing(qApp->style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing) / 2);1468 #endif1469 1470 if (m_fShowToolbar)1471 prepareToolBar();1472 1473 m_pHostStatsWidget = new UIVMActivityOverviewHostStatsWidget;1474 if (m_pHostStatsWidget)1475 layout()->addWidget(m_pHostStatsWidget);1476 1477 m_pModel = new UIActivityOverviewModel(this);1478 m_pProxyModel = new UIActivityOverviewProxyModel(this);1479 m_pTableView = new UIVMActivityOverviewTableView();1480 if (m_pTableView && m_pModel && m_pProxyModel)1481 {1482 layout()->addWidget(m_pTableView);1483 m_pProxyModel->setSourceModel(m_pModel);1484 m_pProxyModel->setNotRunningVMVisibility(m_fShowNotRunningVMs);1485 m_pTableView->setModel(m_pProxyModel);1486 m_pTableView->setItemDelegate(new UIVMActivityOverviewDelegate);1487 m_pTableView->setSelectionMode(QAbstractItemView::SingleSelection);1488 m_pTableView->setSelectionBehavior(QAbstractItemView::SelectRows);1489 m_pTableView->setShowGrid(false);1490 m_pTableView->setContextMenuPolicy(Qt::CustomContextMenu);1491 m_pTableView->horizontalHeader()->setHighlightSections(false);1492 m_pTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);1493 m_pTableView->verticalHeader()->setVisible(false);1494 m_pTableView->setEditTriggers(QAbstractItemView::NoEditTriggers);1495 /* Minimize the row height: */1496 m_pTableView->verticalHeader()->setDefaultSectionSize(m_pTableView->verticalHeader()->minimumSectionSize());1497 m_pTableView->setAlternatingRowColors(true);1498 m_pTableView->setSortingEnabled(true);1499 m_pTableView->sortByColumn(0, Qt::AscendingOrder);1500 /* Store the default font and its color of the table on the view. They are used in ::data(..): */1501 m_pModel->setDefaultViewFont(m_pTableView->font());1502 m_pModel->setDefaultViewFontColor(m_pTableView->palette().color(QPalette::WindowText));1503 1504 connect(m_pModel, &UIActivityOverviewModel::sigDataUpdate,1505 this, &UIVMActivityOverviewWidget::sltHandleDataUpdate);1506 connect(m_pModel, &UIActivityOverviewModel::sigHostStatsUpdate,1507 this, &UIVMActivityOverviewWidget::sltHandleHostStatsUpdate);1508 connect(m_pTableView, &UIVMActivityOverviewTableView::customContextMenuRequested,1509 this, &UIVMActivityOverviewWidget::sltHandleTableContextMenuRequest);1510 connect(m_pTableView, &UIVMActivityOverviewTableView::sigSelectionChanged,1511 this, &UIVMActivityOverviewWidget::sltHandleTableSelectionChanged);1512 updateModelColumVisibilityCache();1513 }1514 104 } 1515 105 1516 void UIVMActivityOverviewWidget::updateColumnsMenu() 106 107 void UIVMActivityListWidget::prepareActions() 1517 108 { 1518 UIMenu *pMenu = m_pActionPool->action(UIActionIndexMN_M_VMActivityOverview_M_Columns)->menu();1519 if (!pMenu)1520 return;1521 pMenu->clear();1522 for (int i = 0; i < VMActivityOverviewColumn_Max; ++i)1523 {1524 QAction *pAction = pMenu->addAction(m_columnTitles[i]);1525 pAction->setCheckable(true);1526 if (i == (int)VMActivityOverviewColumn_Name)1527 pAction->setEnabled(false);1528 pAction->setData(i);1529 pAction->setChecked(columnVisible(i));1530 connect(pAction, &QAction::toggled, this, &UIVMActivityOverviewWidget::sltHandleColumnAction);1531 }1532 109 } 1533 110 1534 void UIVMActivityOverviewWidget::prepareActions() 1535 { 1536 updateColumnsMenu(); 1537 m_pVMActivityMonitorAction = 1538 m_pActionPool->action(UIActionIndexMN_M_VMActivityOverview_S_SwitchToMachinePerformance); 1539 1540 if (m_pVMActivityMonitorAction) 1541 connect(m_pVMActivityMonitorAction, &QAction::triggered, this, &UIVMActivityOverviewWidget::sltHandleShowVMActivityMonitor); 1542 } 1543 1544 void UIVMActivityOverviewWidget::prepareToolBar() 111 void UIVMActivityListWidget::prepareToolBar() 1545 112 { 1546 113 /* Create toolbar: */ … … 1567 134 } 1568 135 1569 void UIVMActivityOverviewWidget::loadSettings() 1570 { 1571 /* Load the list of hidden columns: */ 1572 QStringList hiddenColumnList = gEDataManager->VMActivityOverviewHiddenColumnList(); 1573 for (int i = (int)VMActivityOverviewColumn_Name; i < (int)VMActivityOverviewColumn_Max; ++i) 1574 m_columnVisible[i] = true; 1575 foreach(const QString& strColumn, hiddenColumnList) 1576 setColumnVisible((int)gpConverter->fromInternalString<VMActivityOverviewColumn>(strColumn), false); 1577 /* Load other options: */ 1578 sltNotRunningVMVisibility(gEDataManager->VMActivityOverviewShowAllMachines()); 1579 } 1580 1581 void UIVMActivityOverviewWidget::sltSaveSettings() 1582 { 1583 /* Save the list of hidden columns: */ 1584 QStringList hiddenColumnList; 1585 for (int i = 0; i < m_columnVisible.size(); ++i) 1586 { 1587 if (!columnVisible(i)) 1588 hiddenColumnList << gpConverter->toInternalString((VMActivityOverviewColumn) i); 1589 } 1590 gEDataManager->setVMActivityOverviewHiddenColumnList(hiddenColumnList); 1591 gEDataManager->setVMActivityOverviewShowAllMachines(m_fShowNotRunningVMs); 1592 } 1593 1594 void UIVMActivityOverviewWidget::sltClearCOMData() 1595 { 1596 if (m_pModel) 1597 m_pModel->clearData(); 1598 } 1599 1600 void UIVMActivityOverviewWidget::sltToggleColumnSelectionMenu(bool fChecked) 1601 { 1602 (void)fChecked; 1603 if (!m_pColumnVisibilityToggleMenu) 1604 return; 1605 m_pColumnVisibilityToggleMenu->exec(this->mapToGlobal(QPoint(0,0))); 1606 } 1607 1608 void UIVMActivityOverviewWidget::sltHandleColumnAction(bool fChecked) 1609 { 1610 QAction* pSender = qobject_cast<QAction*>(sender()); 1611 if (!pSender) 1612 return; 1613 setColumnVisible(pSender->data().toInt(), fChecked); 1614 } 1615 1616 void UIVMActivityOverviewWidget::sltHandleHostStatsUpdate(const UIVMActivityOverviewHostStats &stats) 1617 { 1618 if (m_pHostStatsWidget) 1619 m_pHostStatsWidget->setHostStats(stats); 1620 } 1621 1622 void UIVMActivityOverviewWidget::sltHandleDataUpdate() 1623 { 1624 computeMinimumColumnWidths(); 1625 if (m_pProxyModel) 1626 m_pProxyModel->dataUpdate(); 1627 } 1628 1629 void UIVMActivityOverviewWidget::sltHandleTableContextMenuRequest(const QPoint &pos) 1630 { 1631 if (!m_pTableView) 1632 return; 1633 1634 QMenu menu; 1635 if (m_pVMActivityMonitorAction) 1636 menu.addAction(m_pVMActivityMonitorAction); 1637 menu.addSeparator(); 1638 QAction *pHideNotRunningAction = 1639 menu.addAction(UIVMActivityOverviewWidget::tr("List all virtual machines")); 1640 pHideNotRunningAction->setCheckable(true); 1641 pHideNotRunningAction->setChecked(m_fShowNotRunningVMs); 1642 connect(pHideNotRunningAction, &QAction::triggered, 1643 this, &UIVMActivityOverviewWidget::sltNotRunningVMVisibility); 1644 menu.exec(m_pTableView->mapToGlobal(pos)); 1645 } 1646 1647 void UIVMActivityOverviewWidget::sltHandleTableSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected) 1648 { 1649 Q_UNUSED(deselected); 1650 if (!m_pVMActivityMonitorAction || !m_pModel || !m_pProxyModel) 1651 return; 1652 1653 if (selected.indexes().empty()) 1654 { 1655 m_pVMActivityMonitorAction->setEnabled(false); 1656 return; 1657 } 1658 int iMachineIndex = m_pProxyModel->mapToSource(selected.indexes()[0]).row(); 1659 if (m_pModel->machineState(iMachineIndex) != KMachineState_Running) 1660 { 1661 m_pVMActivityMonitorAction->setEnabled(false); 1662 return; 1663 } 1664 m_pVMActivityMonitorAction->setEnabled(true); 1665 } 1666 1667 void UIVMActivityOverviewWidget::sltHandleShowVMActivityMonitor() 1668 { 1669 if (!m_pTableView || !m_pModel) 1670 return; 1671 const QUuid uMachineId = m_pModel->itemUid(m_pTableView->selectedItemIndex()); 1672 if (uMachineId.isNull()) 1673 return; 1674 emit sigSwitchToMachinePerformancePane(uMachineId); 1675 } 1676 1677 void UIVMActivityOverviewWidget::sltNotRunningVMVisibility(bool fShow) 1678 { 1679 m_fShowNotRunningVMs = fShow; 1680 if (m_pProxyModel) 1681 m_pProxyModel->setNotRunningVMVisibility(m_fShowNotRunningVMs); 1682 } 1683 1684 void UIVMActivityOverviewWidget::setColumnVisible(int iColumnId, bool fVisible) 1685 { 1686 if (m_columnVisible.contains(iColumnId) && m_columnVisible[iColumnId] == fVisible) 1687 return; 1688 m_columnVisible[iColumnId] = fVisible; 1689 updateModelColumVisibilityCache(); 1690 } 1691 1692 void UIVMActivityOverviewWidget::updateModelColumVisibilityCache() 1693 { 1694 if (m_pModel) 1695 m_pModel->setColumnVisible(m_columnVisible); 1696 /* Notify the table view for the changed column visibility: */ 1697 if (m_pTableView) 1698 m_pTableView->updateColumVisibility(); 1699 } 1700 1701 void UIVMActivityOverviewWidget::computeMinimumColumnWidths() 1702 { 1703 if (!m_pTableView || !m_pModel) 1704 return; 1705 QFontMetrics fontMetrics(m_pTableView->font()); 1706 const QMap<int, int> &columnDataStringLengths = m_pModel->dataLengths(); 1707 QMap<int, int> columnWidthsInPixels; 1708 for (int i = 0; i < (int)VMActivityOverviewColumn_Max; ++i) 1709 { 1710 int iColumnStringWidth = columnDataStringLengths.value(i, 0); 1711 int iColumnTitleWidth = m_columnTitles.value(i, QString()).length(); 1712 int iMax = iColumnStringWidth > iColumnTitleWidth ? iColumnStringWidth : iColumnTitleWidth; 1713 columnWidthsInPixels[i] = iMax * fontMetrics.width('x') + 1714 QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin) + 1715 QApplication::style()->pixelMetric(QStyle::PM_LayoutRightMargin) + 1716 m_iSortIndicatorWidth; 1717 } 1718 m_pTableView->setMinimumColumnWidths(columnWidthsInPixels); 1719 } 1720 1721 bool UIVMActivityOverviewWidget::columnVisible(int iColumnId) const 1722 { 1723 return m_columnVisible.value(iColumnId, true); 1724 } 1725 1726 1727 /********************************************************************************************************************************* 1728 * Class UIVMActivityOverviewFactory implementation. * 1729 *********************************************************************************************************************************/ 1730 1731 UIVMActivityOverviewFactory::UIVMActivityOverviewFactory(UIActionPool *pActionPool /* = 0 */) 1732 : m_pActionPool(pActionPool) 136 void UIVMActivityListWidget::loadSettings() 1733 137 { 1734 138 } 1735 1736 void UIVMActivityOverviewFactory::create(QIManagerDialog *&pDialog, QWidget *pCenterWidget)1737 {1738 pDialog = new UIVMActivityOverviewDialog(pCenterWidget, m_pActionPool);1739 }1740 1741 1742 /*********************************************************************************************************************************1743 * Class UIActivityOverview implementation. *1744 *********************************************************************************************************************************/1745 1746 UIVMActivityOverviewDialog::UIVMActivityOverviewDialog(QWidget *pCenterWidget, UIActionPool *pActionPool)1747 : QIWithRetranslateUI<QIManagerDialog>(pCenterWidget)1748 , m_pActionPool(pActionPool)1749 {1750 }1751 1752 void UIVMActivityOverviewDialog::retranslateUi()1753 {1754 setWindowTitle(UIVMActivityOverviewWidget::tr("VM Activity Overview"));1755 }1756 1757 void UIVMActivityOverviewDialog::configure()1758 {1759 /* Apply window icons: */1760 setWindowIcon(UIIconPool::iconSetFull(":/host_iface_manager_32px.png", ":/host_iface_manager_16px.png"));1761 }1762 1763 void UIVMActivityOverviewDialog::configureCentralWidget()1764 {1765 UIVMActivityOverviewWidget *pWidget = new UIVMActivityOverviewWidget(EmbedTo_Dialog, m_pActionPool, true, this);1766 AssertPtrReturnVoid(pWidget);1767 {1768 setWidget(pWidget);1769 setWidgetMenu(pWidget->menu());1770 #ifdef VBOX_WS_MAC1771 setWidgetToolbar(pWidget->toolbar());1772 #endif1773 centralWidget()->layout()->addWidget(pWidget);1774 }1775 }1776 1777 void UIVMActivityOverviewDialog::configureButtonBox()1778 {1779 }1780 1781 void UIVMActivityOverviewDialog::finalize()1782 {1783 retranslateUi();1784 }1785 1786 UIVMActivityOverviewWidget *UIVMActivityOverviewDialog::widget()1787 {1788 return qobject_cast<UIVMActivityOverviewWidget*>(QIManagerDialog::widget());1789 }1790 1791 1792 #include "UIVMActivityOverviewWidget.moc" -
trunk/src/VBox/Frontends/VirtualBox/src/activity/overview/UIVMActivityListWidget.h
r88997 r89006 1 1 /* $Id$ */ 2 2 /** @file 3 * VBox Qt GUI - UIVMActivity OverviewWidget class declaration.3 * VBox Qt GUI - UIVMActivityListWidget class declaration. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #ifndef FEQT_INCLUDED_SRC_activity_overview_UIVMActivity OverviewWidget_h19 #define FEQT_INCLUDED_SRC_activity_overview_UIVMActivity OverviewWidget_h18 #ifndef FEQT_INCLUDED_SRC_activity_overview_UIVMActivityListWidget_h 19 #define FEQT_INCLUDED_SRC_activity_overview_UIVMActivityListWidget_h 20 20 #ifndef RT_WITHOUT_PRAGMA_ONCE 21 21 # pragma once … … 46 46 47 47 /** QWidget extension to display a Linux top like utility that sort running vm wrt. resource allocations. */ 48 class UIVMActivity OverviewWidget : public QIWithRetranslateUI<QWidget>48 class UIVMActivityListWidget : public QIWithRetranslateUI<QWidget> 49 49 { 50 50 Q_OBJECT; … … 52 52 signals: 53 53 54 void sigSwitchToMachinePerformancePane(const QUuid &uMachineId);55 54 56 55 public: 57 56 58 UIVMActivity OverviewWidget(EmbedTo enmEmbedding, UIActionPool *pActionPool,57 UIVMActivityListWidget(EmbedTo enmEmbedding, UIActionPool *pActionPool, 59 58 bool fShowToolbar = true, QWidget *pParent = 0); 60 QMenu *columnVisiblityToggleMenu() const;61 59 QMenu *menu() const; 62 60 … … 78 76 private slots: 79 77 80 void sltHandleDataUpdate();81 void sltToggleColumnSelectionMenu(bool fChecked);82 void sltHandleColumnAction(bool fChecked);83 void sltHandleHostStatsUpdate(const UIVMActivityOverviewHostStats &stats);84 void sltHandleTableContextMenuRequest(const QPoint &pos);85 void sltHandleShowVMActivityMonitor();86 void sltHandleTableSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);87 void sltNotRunningVMVisibility(bool fShow);88 void sltSaveSettings();89 void sltClearCOMData();90 78 91 79 private: 92 80 93 void setColumnVisible(int iColumnId, bool fVisible);94 bool columnVisible(int iColumnId) const;95 void updateModelColumVisibilityCache();96 void computeMinimumColumnWidths();97 81 98 82 /** @name Prepare/cleanup cascade. … … 117 101 * @{ */ 118 102 QIToolBar *m_pToolBar; 119 UIVMActivityOverviewTableView *m_pTableView;120 UIActivityOverviewProxyModel *m_pProxyModel;121 UIActivityOverviewModel *m_pModel;122 103 QMenu *m_pColumnVisibilityToggleMenu; 123 /* The key is the column id (VMActivityOverviewColumn) and value is column title. */124 QMap<int, QString> m_columnTitles;125 /* The key is the column id (VMActivityOverviewColumn) and value is true if the column is visible. */126 QMap<int, bool> m_columnVisible;127 UIVMActivityOverviewHostStatsWidget *m_pHostStatsWidget;128 QAction *m_pVMActivityMonitorAction;129 104 /** @} */ 130 105 /** Indicates if this widget's host tool is current tool. */ 131 106 bool m_fIsCurrentTool; 132 int m_iSortIndicatorWidth;133 bool m_fShowNotRunningVMs;134 107 }; 135 108 136 class UIVMActivityOverviewFactory : public QIManagerDialogFactory137 {138 public:139 109 140 UIVMActivityOverviewFactory(UIActionPool *pActionPool = 0); 141 142 protected: 143 144 virtual void create(QIManagerDialog *&pDialog, QWidget *pCenterWidget) /* override */; 145 UIActionPool *m_pActionPool; 146 }; 147 148 class UIVMActivityOverviewDialog : public QIWithRetranslateUI<QIManagerDialog> 149 { 150 Q_OBJECT; 151 152 private: 153 154 UIVMActivityOverviewDialog(QWidget *pCenterWidget, UIActionPool *pActionPool); 155 156 virtual void retranslateUi() /* override */; 157 158 /** @name Prepare/cleanup cascade. 159 * @{ */ 160 virtual void configure() /* override */; 161 virtual void configureCentralWidget() /* override */; 162 virtual void configureButtonBox() /* override */; 163 virtual void finalize() /* override */; 164 /** @} */ 165 166 /** @name Widget stuff. 167 * @{ */ 168 virtual UIVMActivityOverviewWidget *widget() /* override */; 169 /** @} */ 170 171 /** @name Action related variables. 172 * @{ */ 173 UIActionPool *m_pActionPool; 174 /** @} */ 175 friend class UIVMActivityOverviewFactory; 176 }; 177 178 #endif /* !FEQT_INCLUDED_SRC_activity_overview_UIVMActivityOverviewWidget_h */ 110 #endif /* !FEQT_INCLUDED_SRC_activity_overview_UIVMActivityListWidget_h */
Note:
See TracChangeset
for help on using the changeset viewer.