462 lines
13 KiB
C++
462 lines
13 KiB
C++
|
|
/**
|
|||
|
|
* @file SubmitWorkflowDialog.cpp
|
|||
|
|
* @date 2014-12-10
|
|||
|
|
*/
|
|||
|
|
#include "SubmitWorkflowDialog.h"
|
|||
|
|
#include "PaiLabel.h"
|
|||
|
|
#include "PaiProgressBar.h"
|
|||
|
|
#include "PaiPushButton.h"
|
|||
|
|
#include "PaiRadioButton.h"
|
|||
|
|
#include "PaiNameLineEdit.h"
|
|||
|
|
|
|||
|
|
#include "PaiCollapsibleWidget.h"
|
|||
|
|
#include "error.h"
|
|||
|
|
|
|||
|
|
#include <QVBoxLayout>
|
|||
|
|
#include <QHBoxLayout>
|
|||
|
|
#include <QGridLayout>
|
|||
|
|
#include <QSpacerItem>
|
|||
|
|
#include <QLabel>
|
|||
|
|
#include <QDebug>
|
|||
|
|
#include <QTableWidget>
|
|||
|
|
#include <QRadioButton>
|
|||
|
|
#include <QHeaderView>
|
|||
|
|
#include <QStackedWidget>
|
|||
|
|
#include <QButtonGroup>
|
|||
|
|
|
|||
|
|
using namespace pai::gui;
|
|||
|
|
|
|||
|
|
SubmitWorkflowDialog::SubmitWorkflowDialog(QWidget *pParent) :
|
|||
|
|
PaiDialog(pParent),
|
|||
|
|
m_pTable(NULL),
|
|||
|
|
m_priority(pai::ios::job::Normal),
|
|||
|
|
m_currentSQueue("")
|
|||
|
|
{
|
|||
|
|
//布局1区
|
|||
|
|
QLabel *pText = new QLabel("Select queue type:",this);
|
|||
|
|
PaiRadioButton *pNRadioBtn = new PaiRadioButton("Normal queue", this);
|
|||
|
|
pNRadioBtn->setChecked(true);
|
|||
|
|
PaiRadioButton *pSRadioBtn = new PaiRadioButton("Special queue", this);
|
|||
|
|
//设置互斥
|
|||
|
|
QButtonGroup *pGroup = new QButtonGroup(this);
|
|||
|
|
pGroup->addButton(pNRadioBtn);
|
|||
|
|
pGroup->addButton(pSRadioBtn);
|
|||
|
|
pGroup->setExclusive(true);
|
|||
|
|
|
|||
|
|
connect(pNRadioBtn,SIGNAL(toggled(bool)),this,SLOT(ToggleNormalRadio(bool)));
|
|||
|
|
connect(pSRadioBtn,SIGNAL(toggled(bool)),this,SLOT(ToggleSpecialRadio(bool)));
|
|||
|
|
|
|||
|
|
QHBoxLayout *pRadioHLayout = new QHBoxLayout();
|
|||
|
|
pRadioHLayout->addWidget(pNRadioBtn);
|
|||
|
|
pRadioHLayout->addWidget(pSRadioBtn);
|
|||
|
|
pRadioHLayout->addStretch();
|
|||
|
|
|
|||
|
|
//一条线
|
|||
|
|
QFrame *pLineOne = new QFrame(this);
|
|||
|
|
pLineOne->setFrameShape(QFrame::HLine);
|
|||
|
|
pLineOne->setFrameShadow(QFrame::Sunken);
|
|||
|
|
|
|||
|
|
QVBoxLayout *pRadioVLayout = new QVBoxLayout();
|
|||
|
|
pRadioVLayout->addWidget(pText);
|
|||
|
|
pRadioVLayout->addLayout(pRadioHLayout);
|
|||
|
|
pRadioVLayout->addWidget(pLineOne);
|
|||
|
|
//布局2区
|
|||
|
|
m_pStack = new QStackedWidget(this);
|
|||
|
|
m_pCpuWgt = new QWidget(this);
|
|||
|
|
m_pSpecialCpuWgt = new QWidget(this);
|
|||
|
|
m_pStack->addWidget(m_pCpuWgt);
|
|||
|
|
m_pStack->addWidget(m_pSpecialCpuWgt);
|
|||
|
|
m_pStack->setCurrentWidget(m_pCpuWgt);
|
|||
|
|
m_pStack->setMinimumHeight(155);
|
|||
|
|
m_pStack->setMinimumWidth(155);
|
|||
|
|
//布局3区
|
|||
|
|
m_pStorage = new QWidget(this);
|
|||
|
|
|
|||
|
|
//一条线
|
|||
|
|
QFrame *pLineTwo = new QFrame(this);
|
|||
|
|
pLineTwo->setFrameShape(QFrame::HLine);
|
|||
|
|
pLineTwo->setFrameShadow(QFrame::Sunken);
|
|||
|
|
//布局4区
|
|||
|
|
QLabel *pJNText = new QLabel("Job Name:",this);
|
|||
|
|
m_pJobNameEdit = new PaiNameLineEdit(this);
|
|||
|
|
PaiLabel *pMaxLenMsg = new PaiLabel(this);
|
|||
|
|
m_priorityCheckBox = new QCheckBox("Submit with high priority",this);
|
|||
|
|
connect(m_priorityCheckBox,SIGNAL(stateChanged(int)),this,SLOT(SetPriority(int)));
|
|||
|
|
QVBoxLayout *pBoxLayout = new QVBoxLayout();
|
|||
|
|
pBoxLayout->addWidget(pJNText);
|
|||
|
|
pBoxLayout->addWidget(m_pJobNameEdit);
|
|||
|
|
pBoxLayout->addWidget(pMaxLenMsg);
|
|||
|
|
pBoxLayout->addWidget(m_priorityCheckBox);
|
|||
|
|
pBoxLayout->addWidget(pLineTwo);
|
|||
|
|
pBoxLayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
|||
|
|
m_pJobNameEdit->SetPromptLabel(pMaxLenMsg);
|
|||
|
|
m_pJobNameEdit->setMinimumWidth(350);
|
|||
|
|
//布局5区
|
|||
|
|
m_pContinuePBtn = new PaiPushButton(tr("&Continue"), this);
|
|||
|
|
m_pCancelPBtn = new PaiPushButton(tr("&Cancel"), this);
|
|||
|
|
|
|||
|
|
QHBoxLayout *pBtnHLayout = new QHBoxLayout();
|
|||
|
|
pBtnHLayout->addStretch();
|
|||
|
|
pBtnHLayout->addWidget(m_pContinuePBtn);
|
|||
|
|
pBtnHLayout->addWidget(m_pCancelPBtn);
|
|||
|
|
//总布局
|
|||
|
|
QVBoxLayout *pMainLayout = new QVBoxLayout(GetContainer());
|
|||
|
|
pMainLayout->addLayout(pRadioVLayout);
|
|||
|
|
pMainLayout->addWidget(m_pStack);
|
|||
|
|
pMainLayout->addWidget(m_pStorage);
|
|||
|
|
pMainLayout->addLayout(pBoxLayout);
|
|||
|
|
pMainLayout->addLayout(pBtnHLayout);
|
|||
|
|
|
|||
|
|
connect(m_pContinuePBtn, SIGNAL(clicked()), this, SLOT(accept()));
|
|||
|
|
connect(m_pCancelPBtn, SIGNAL(clicked()), this, SLOT(reject()));
|
|||
|
|
//绘制特殊队列的2区
|
|||
|
|
SetSpecialCpuWidget();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SubmitWorkflowDialog::~SubmitWorkflowDialog()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SetPriority(int checked)
|
|||
|
|
{
|
|||
|
|
if(checked)
|
|||
|
|
{
|
|||
|
|
m_priority = pai::ios::job::High;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
m_priority = pai::ios::job::Normal;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pai::ios::job::JobPriority SubmitWorkflowDialog::GetPriority()
|
|||
|
|
{
|
|||
|
|
return m_priority;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::ClearCpuWidget()
|
|||
|
|
{
|
|||
|
|
delete m_pCpuWgt->layout();
|
|||
|
|
|
|||
|
|
QObjectList objects = m_pCpuWgt->children();
|
|||
|
|
foreach(QObject *pObj, objects)
|
|||
|
|
{
|
|||
|
|
pObj->setParent(NULL);
|
|||
|
|
delete pObj;
|
|||
|
|
}
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QString SubmitWorkflowDialog::GetQueueName()
|
|||
|
|
{
|
|||
|
|
return m_currentSQueue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SetJobName(const QString& jobName)
|
|||
|
|
{
|
|||
|
|
if(m_pJobNameEdit && !jobName.isEmpty())
|
|||
|
|
{
|
|||
|
|
m_pJobNameEdit->setFocus();
|
|||
|
|
m_pJobNameEdit->setText(jobName);
|
|||
|
|
m_pJobNameEdit->selectAll();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QWidget* SubmitWorkflowDialog::AddItemWidget(const ResItem& item, PaiLabel *pIcon)
|
|||
|
|
{
|
|||
|
|
if(item.queueName.isEmpty())
|
|||
|
|
{
|
|||
|
|
return new QWidget();
|
|||
|
|
}
|
|||
|
|
//item主标题
|
|||
|
|
PaiLabel *pMainTitleLabel = new PaiLabel(item.mainTitle, this);
|
|||
|
|
pMainTitleLabel->setObjectName("MainTitleLabel");
|
|||
|
|
QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|||
|
|
sizePolicy.setHorizontalStretch(0);
|
|||
|
|
sizePolicy.setVerticalStretch(0);
|
|||
|
|
sizePolicy.setHeightForWidth(pMainTitleLabel->sizePolicy().hasHeightForWidth());
|
|||
|
|
pMainTitleLabel->setSizePolicy(sizePolicy);
|
|||
|
|
|
|||
|
|
QHBoxLayout *pMainTitleHLayout = new QHBoxLayout();
|
|||
|
|
pMainTitleHLayout->addWidget(pIcon);
|
|||
|
|
pMainTitleHLayout->addWidget(pMainTitleLabel);
|
|||
|
|
|
|||
|
|
|
|||
|
|
//一条分割线
|
|||
|
|
QFrame *pLine = new QFrame(this);
|
|||
|
|
pLine->setFrameShape(QFrame::HLine);
|
|||
|
|
pLine->setFrameShadow(QFrame::Sunken);
|
|||
|
|
//当前展示的Widget
|
|||
|
|
QWidget *pItemWidget = new QWidget();
|
|||
|
|
pItemWidget->setObjectName("itemWidget");
|
|||
|
|
QVBoxLayout *pItemVLayout = new QVBoxLayout(pItemWidget);
|
|||
|
|
pItemVLayout->setContentsMargins(0, 0, 0, 0);
|
|||
|
|
pItemVLayout->addLayout(pMainTitleHLayout);
|
|||
|
|
pItemVLayout->addWidget(pLine);
|
|||
|
|
return pItemWidget;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SetCpuWidget()
|
|||
|
|
{
|
|||
|
|
//清理上次的布局
|
|||
|
|
ClearCpuWidget();
|
|||
|
|
|
|||
|
|
//在容器上布局当前item的Widget
|
|||
|
|
QVBoxLayout *pPanelLayout = new QVBoxLayout(m_pCpuWgt);
|
|||
|
|
pPanelLayout->setContentsMargins(0, 0 ,0, 0);
|
|||
|
|
pPanelLayout->addItem(new QSpacerItem(40, 25, QSizePolicy::Expanding, QSizePolicy::Minimum));
|
|||
|
|
|
|||
|
|
ResItem item = m_cpuItem;
|
|||
|
|
PaiLabel *pIconLabel = new PaiLabel(this);
|
|||
|
|
pIconLabel->setPixmap(QPixmap(":/cpu.png"));
|
|||
|
|
m_currentSQueue = item.queueName;
|
|||
|
|
pPanelLayout->addWidget(AddItemWidget(item, pIconLabel));
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QString SubmitWorkflowDialog::GetJobName()
|
|||
|
|
{
|
|||
|
|
if(m_pJobNameEdit)
|
|||
|
|
{
|
|||
|
|
return m_pJobNameEdit->text();
|
|||
|
|
}
|
|||
|
|
return QString("");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::UpdateContinueBtn(const QString& name)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::ToggleNormalRadio(bool toggled)
|
|||
|
|
{
|
|||
|
|
//如果普通队列radioButton被选中
|
|||
|
|
if(toggled)
|
|||
|
|
{
|
|||
|
|
//作业优先级checkBox使能,并且显示普通队列的item的Widget
|
|||
|
|
m_priorityCheckBox->setEnabled(true);
|
|||
|
|
m_pStack->setCurrentWidget(m_pCpuWgt);
|
|||
|
|
SetPriority(m_priorityCheckBox->isChecked());
|
|||
|
|
m_currentSQueue = m_cpuItem.queueName;
|
|||
|
|
//设置continue是否可用
|
|||
|
|
UpdateContinueBtn(m_currentSQueue);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::ToggleSpecialRadio(bool toggled)
|
|||
|
|
{
|
|||
|
|
//如果特殊队列radioButton被选中
|
|||
|
|
if(toggled)
|
|||
|
|
{
|
|||
|
|
//作业优先级checkBox非使能,并且显示特殊队列的item的Widget
|
|||
|
|
m_priorityCheckBox->setEnabled(false);
|
|||
|
|
m_pStack->setCurrentWidget(m_pSpecialCpuWgt);
|
|||
|
|
m_priority = pai::ios::job::Normal;
|
|||
|
|
|
|||
|
|
//如果特殊队列数量不为0
|
|||
|
|
if(m_pTable && m_pTable->rowCount() > 0)
|
|||
|
|
{
|
|||
|
|
QRadioButton *pRadioButton = dynamic_cast<QRadioButton*>(m_pTable->cellWidget(0,0));
|
|||
|
|
if(pRadioButton)
|
|||
|
|
{
|
|||
|
|
pRadioButton->setChecked(true);
|
|||
|
|
m_currentSQueue = m_pTable->item(0,1)->text();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
m_currentSQueue = "";
|
|||
|
|
}
|
|||
|
|
//设置continue按钮状态
|
|||
|
|
UpdateContinueBtn(m_currentSQueue);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SelectCurrentRow(bool toggled)
|
|||
|
|
{
|
|||
|
|
//如果radioButton被选中
|
|||
|
|
if(toggled)
|
|||
|
|
{
|
|||
|
|
//停止循环标志
|
|||
|
|
bool stop = false;
|
|||
|
|
for(int col = 0; col < m_pTable->columnCount(); ++col)
|
|||
|
|
{
|
|||
|
|
for(int row = 0; row < m_pTable->rowCount(); ++row)
|
|||
|
|
{
|
|||
|
|
QRadioButton *pRadioButton = dynamic_cast<QRadioButton*>(m_pTable->cellWidget(row,col));
|
|||
|
|
if(pRadioButton && pRadioButton->isChecked())
|
|||
|
|
{
|
|||
|
|
//如果是当前选中radioButton
|
|||
|
|
if(sender() == pRadioButton)
|
|||
|
|
{
|
|||
|
|
m_pTable->selectRow(row);
|
|||
|
|
m_currentSQueue = m_pTable->item(row,col+1)->text();
|
|||
|
|
m_pExtendCtrl->SetLabelText("<a><font color=#CC6600>"+m_currentSQueue+"</font></a>",m_currentSQueue);
|
|||
|
|
//设置continue按钮状态
|
|||
|
|
UpdateContinueBtn(m_currentSQueue);
|
|||
|
|
stop = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if(stop)
|
|||
|
|
{
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SelectCurrentRadioBtn()
|
|||
|
|
{
|
|||
|
|
QList<QTableWidgetItem *>items = m_pTable->selectedItems();
|
|||
|
|
if(items.count() > 0)
|
|||
|
|
{
|
|||
|
|
int selectRow = items[0]->row();
|
|||
|
|
for(int col = 0; col < m_pTable->columnCount(); ++col)
|
|||
|
|
{
|
|||
|
|
QRadioButton *pRadioButton = dynamic_cast<QRadioButton*>(m_pTable->cellWidget(selectRow,col));
|
|||
|
|
if(pRadioButton && !pRadioButton->isChecked())
|
|||
|
|
{
|
|||
|
|
pRadioButton->setChecked(true);
|
|||
|
|
//更新continue按钮的状态
|
|||
|
|
UpdateContinueBtn(m_pTable->item(selectRow,col+1)->text());
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SubmitWorkflowDialog::ResItem SubmitWorkflowDialog::GetCurrentItem(const QString& name)
|
|||
|
|
{
|
|||
|
|
SubmitWorkflowDialog::ResItem resItem;
|
|||
|
|
for(int i = 0; i < m_items.count(); ++i)
|
|||
|
|
{
|
|||
|
|
if(m_items[i].queueName == name)
|
|||
|
|
{
|
|||
|
|
resItem = m_items[i];
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return resItem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SetSpecialCpuWidget()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SubmitWorkflowDialog::ResItem SubmitWorkflowDialog::GetSpecialQueueResItem(const QString& name)
|
|||
|
|
{
|
|||
|
|
ResItem cpuItem;
|
|||
|
|
|
|||
|
|
return cpuItem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SetCpuItem(const ResItem& item)
|
|||
|
|
{
|
|||
|
|
m_cpuItem = item;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SetStorageItem(const ResItem& item)
|
|||
|
|
{
|
|||
|
|
m_storageItem = item;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SetStorageWidget()
|
|||
|
|
{
|
|||
|
|
QVBoxLayout *pStorageLayout = new QVBoxLayout(m_pStorage);
|
|||
|
|
pStorageLayout->setContentsMargins(0, 0 ,0, 0);
|
|||
|
|
|
|||
|
|
ResItem item = m_storageItem;
|
|||
|
|
PaiLabel *pIconLabel = new PaiLabel(this);
|
|||
|
|
QPixmap storage(":/storage.png");
|
|||
|
|
pIconLabel->setPixmap(storage.scaled(48,48,Qt::KeepAspectRatio));
|
|||
|
|
|
|||
|
|
pStorageLayout->addWidget(AddItemWidget(item, pIconLabel));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::ExpandAllSpecilaQueue()
|
|||
|
|
{
|
|||
|
|
QWidget *pWgt = m_pSpecialCpuWgt->findChild<QWidget *>("itemWidget");
|
|||
|
|
if(pWgt)
|
|||
|
|
{
|
|||
|
|
pWgt->hide();
|
|||
|
|
}
|
|||
|
|
update();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::CollapseAllSpecilaQueue()
|
|||
|
|
{
|
|||
|
|
if(m_pExtendCtrl)
|
|||
|
|
{
|
|||
|
|
m_pExtendCtrl->SetLabelText("<a><font color=#000000>"+m_currentSQueue+"</font></a>",m_currentSQueue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QWidget *pWgt = m_pSpecialCpuWgt->findChild<QWidget *>("itemWidget");
|
|||
|
|
if(pWgt)
|
|||
|
|
{
|
|||
|
|
ResItem item = GetCurrentItem(m_currentSQueue);
|
|||
|
|
|
|||
|
|
PaiLabel *pMainTitleLabel = m_pSpecialCpuWgt->findChild<PaiLabel *>("MainTitleLabel");
|
|||
|
|
if(pMainTitleLabel)
|
|||
|
|
{
|
|||
|
|
pMainTitleLabel->setText(item.mainTitle);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PaiProgressBar *pResPrgsBar = m_pSpecialCpuWgt->findChild<PaiProgressBar *>("ResPrgsBar");
|
|||
|
|
if(pResPrgsBar)
|
|||
|
|
{
|
|||
|
|
int perc = 0;
|
|||
|
|
if(item.total != 0)
|
|||
|
|
{
|
|||
|
|
perc = (int)(100.0 * item.used / item.total);
|
|||
|
|
}
|
|||
|
|
pResPrgsBar->setValue(perc > 100 ? 100 : perc);
|
|||
|
|
pResPrgsBar->SetErrorState(item.required > (item.total - item.used));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PaiLabel *pTotalLabel = m_pSpecialCpuWgt->findChild<PaiLabel *>("TotalLabel");
|
|||
|
|
if(pTotalLabel)
|
|||
|
|
{
|
|||
|
|
pTotalLabel->setText(item.totalTitle);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PaiLabel *pFreeTitleLabel = m_pSpecialCpuWgt->findChild<PaiLabel *>("FreeTitleLabel");
|
|||
|
|
if(pFreeTitleLabel)
|
|||
|
|
{
|
|||
|
|
pFreeTitleLabel->setText(item.freeTitle);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PaiLabel *pUsedTitleLabel = m_pSpecialCpuWgt->findChild<PaiLabel *>("UsedTitleLabel");
|
|||
|
|
if(pUsedTitleLabel)
|
|||
|
|
{
|
|||
|
|
pUsedTitleLabel->setText(item.usedTitle);
|
|||
|
|
}
|
|||
|
|
pWgt->show();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
QList<SubmitWorkflowDialog::ResItem> SubmitWorkflowDialog::GetSpecialQueueResItems()
|
|||
|
|
{
|
|||
|
|
QList<SubmitWorkflowDialog::ResItem> items;
|
|||
|
|
|
|||
|
|
|
|||
|
|
return items;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SubmitWorkflowDialog::SetWidgets()
|
|||
|
|
{
|
|||
|
|
SetCpuWidget();
|
|||
|
|
SetStorageWidget();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|