576 lines
19 KiB
C++
576 lines
19 KiB
C++
#include <Agent/Agent.h>
|
|
#include <UI/Widgets/ConsoleWidget.h>
|
|
#include <UI/Widgets/TasksWidget.h>
|
|
#include <UI/Widgets/AdaptixWidget.h>
|
|
#include <Client/Settings.h>
|
|
#include <Client/AuthProfile.h>
|
|
#include <Client/AxScript/AxScriptManager.h>
|
|
#include <Utils/FontManager.h>
|
|
#include <MainAdaptix.h>
|
|
|
|
|
|
TaskOutputWidget::TaskOutputWidget() { this->createUI(); }
|
|
|
|
TaskOutputWidget::~TaskOutputWidget() = default;
|
|
|
|
void TaskOutputWidget::createUI()
|
|
{
|
|
inputMessage = new QLineEdit(this);
|
|
inputMessage->setReadOnly(true);
|
|
inputMessage->setStyleSheet("background-color: #151515; color: #BEBEBE; border: 1px solid #2A2A2A; padding: 4px; border-radius: 4px;");
|
|
inputMessage->setFont( FontManager::instance().getFont("Hack") );
|
|
|
|
outputTextEdit = new QTextEdit(this);
|
|
outputTextEdit->setReadOnly(true);
|
|
outputTextEdit->setWordWrapMode(QTextOption::WrapAnywhere);
|
|
outputTextEdit->setStyleSheet("background-color: #151515; color: #BEBEBE; border: 1px solid #2A2A2A; border-radius: 4px;");
|
|
|
|
mainGridLayout = new QGridLayout(this );
|
|
mainGridLayout->setVerticalSpacing(4 );
|
|
mainGridLayout->setContentsMargins(0, 0, 0, 4 );
|
|
mainGridLayout->addWidget( inputMessage, 0, 0, 1, 1 );
|
|
mainGridLayout->addWidget( outputTextEdit, 1, 0, 1, 1 );
|
|
|
|
this->setLayout(mainGridLayout);
|
|
}
|
|
|
|
void TaskOutputWidget::SetConten(const QString &message, const QString &text) const
|
|
{
|
|
if( message.isEmpty() )
|
|
inputMessage->clear();
|
|
else
|
|
inputMessage->setText(TrimmedEnds(message).toHtmlEscaped());
|
|
|
|
if ( text.isEmpty() )
|
|
outputTextEdit->clear();
|
|
else
|
|
outputTextEdit->setText( TrimmedEnds(text) );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TasksWidget::TasksWidget( AdaptixWidget* w )
|
|
{
|
|
this->adaptixWidget = w;
|
|
|
|
this->createUI();
|
|
|
|
taskOutputConsole = new TaskOutputWidget();
|
|
|
|
dockWidgetTable = new KDDockWidgets::QtWidgets::DockWidget( + "Tasks:Dock-" + w->GetProfile()->GetProject(), KDDockWidgets::DockWidgetOption_None, KDDockWidgets::LayoutSaverOption::None);
|
|
dockWidgetTable->setTitle("Tasks");
|
|
dockWidgetTable->setWidget(this);
|
|
dockWidgetTable->setIcon(QIcon( ":/icons/job" ), KDDockWidgets::IconPlace::TabBar);
|
|
|
|
dockWidgetOutput = new KDDockWidgets::QtWidgets::DockWidget( + "Task Output:Dock-" + w->GetProfile()->GetProject(), KDDockWidgets::DockWidgetOption_None, KDDockWidgets::LayoutSaverOption::None);
|
|
dockWidgetOutput->setTitle("Task Output");
|
|
dockWidgetOutput->setWidget(taskOutputConsole);
|
|
dockWidgetOutput->setIcon(QIcon( ":/icons/job" ), KDDockWidgets::IconPlace::TabBar);
|
|
|
|
connect(tableView, &QTableView::customContextMenuRequested, this, &TasksWidget::handleTasksMenu);
|
|
connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this](const QItemSelection &selected, const QItemSelection &deselected){
|
|
Q_UNUSED(selected)
|
|
Q_UNUSED(deselected)
|
|
if (!inputFilter->hasFocus())
|
|
tableView->setFocus();
|
|
});
|
|
|
|
connect(tableView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &TasksWidget::onTableItemSelection);
|
|
connect(inputFilter, &QLineEdit::textChanged, this, &TasksWidget::onFilterChanged);
|
|
connect(inputFilter, &QLineEdit::returnPressed, this, [this]() { proxyModel->setTextFilter(inputFilter->text()); });
|
|
connect(comboAgent, &QComboBox::currentTextChanged, this, &TasksWidget::onFilterChanged);
|
|
connect(comboType, &QComboBox::currentTextChanged, this, &TasksWidget::onFilterChanged);
|
|
connect(comboStatus, &QComboBox::currentTextChanged, this, &TasksWidget::onFilterChanged);
|
|
connect(hideButton, &ClickableLabel::clicked, this, &TasksWidget::toggleSearchPanel);
|
|
|
|
shortcutSearch = new QShortcut(QKeySequence("Ctrl+F"), this);
|
|
shortcutSearch->setContext(Qt::WidgetWithChildrenShortcut);
|
|
connect(shortcutSearch, &QShortcut::activated, this, &TasksWidget::toggleSearchPanel);
|
|
|
|
auto shortcutEsc = new QShortcut(QKeySequence(Qt::Key_Escape), inputFilter);
|
|
shortcutEsc->setContext(Qt::WidgetShortcut);
|
|
connect(shortcutEsc, &QShortcut::activated, this, [this]() { searchWidget->setVisible(false); });
|
|
}
|
|
|
|
TasksWidget::~TasksWidget()
|
|
{
|
|
if (dockWidgetTable) {
|
|
dockWidgetTable->setWidget(nullptr);
|
|
delete dockWidgetTable;
|
|
dockWidgetTable = nullptr;
|
|
}
|
|
if (dockWidgetOutput) {
|
|
dockWidgetOutput->setWidget(nullptr);
|
|
delete dockWidgetOutput;
|
|
dockWidgetOutput = nullptr;
|
|
}
|
|
}
|
|
|
|
KDDockWidgets::QtWidgets::DockWidget* TasksWidget::dockTasks() { return this->dockWidgetTable; }
|
|
|
|
KDDockWidgets::QtWidgets::DockWidget * TasksWidget::dockTasksOutput() { return this->dockWidgetOutput; }
|
|
|
|
void TasksWidget::SetUpdatesEnabled(const bool enabled)
|
|
{
|
|
if (!enabled) {
|
|
bufferingEnabled = true;
|
|
} else {
|
|
bufferingEnabled = false;
|
|
flushPendingTasks();
|
|
}
|
|
|
|
if (proxyModel)
|
|
proxyModel->setDynamicSortFilter(enabled);
|
|
if (tableView)
|
|
tableView->setSortingEnabled(enabled);
|
|
|
|
tableView->setUpdatesEnabled(enabled);
|
|
taskOutputConsole->setUpdatesEnabled(enabled);
|
|
}
|
|
|
|
void TasksWidget::flushPendingTasks()
|
|
{
|
|
if (pendingTasks.isEmpty())
|
|
return;
|
|
|
|
tasksModel->add(pendingTasks);
|
|
|
|
QSet<QString> agents;
|
|
for (const auto& task : pendingTasks)
|
|
agents.insert(task.AgentId);
|
|
|
|
for (const QString& agentId : agents) {
|
|
if (comboAgent->findText(agentId) == -1)
|
|
comboAgent->addItem(agentId);
|
|
}
|
|
|
|
pendingTasks.clear();
|
|
}
|
|
|
|
void TasksWidget::createUI()
|
|
{
|
|
auto horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
|
|
searchWidget = new QWidget(this);
|
|
searchWidget->setVisible(false);
|
|
|
|
inputFilter = new QLineEdit(searchWidget);
|
|
inputFilter->setPlaceholderText("filter: (adm | user) & cmd");
|
|
inputFilter->setMaximumWidth(250);
|
|
|
|
autoSearchCheck = new QCheckBox("auto", searchWidget);
|
|
autoSearchCheck->setChecked(true);
|
|
autoSearchCheck->setToolTip("Auto search on text change. If unchecked, press Enter to search.");
|
|
|
|
comboAgent = new QComboBox(searchWidget);
|
|
comboAgent->setMinimumWidth(120);
|
|
comboAgent->setEditable(true);
|
|
comboAgent->setInsertPolicy(QComboBox::NoInsert);
|
|
comboAgent->addItem("All agents");
|
|
|
|
comboType = new QComboBox(searchWidget);
|
|
comboType->setMinimumWidth(100);
|
|
comboType->addItem("All types");
|
|
|
|
comboStatus = new QComboBox(searchWidget);
|
|
comboStatus->setMinimumWidth(100);
|
|
comboStatus->addItems(QStringList() << "Any status" << "Hosted" << "Running" << "Success" << "Error" << "Canceled");
|
|
|
|
hideButton = new ClickableLabel(" x ");
|
|
hideButton->setCursor(Qt::PointingHandCursor);
|
|
|
|
searchLayout = new QHBoxLayout(searchWidget);
|
|
searchLayout->setContentsMargins(0, 4, 0, 0);
|
|
searchLayout->setSpacing(4);
|
|
searchLayout->addWidget(inputFilter);
|
|
searchLayout->addWidget(autoSearchCheck);
|
|
searchLayout->addSpacing(8);
|
|
searchLayout->addWidget(comboAgent);
|
|
searchLayout->addSpacing(8);
|
|
searchLayout->addWidget(comboType);
|
|
searchLayout->addSpacing(8);
|
|
searchLayout->addWidget(comboStatus);
|
|
searchLayout->addSpacing(8);
|
|
searchLayout->addWidget(hideButton);
|
|
searchLayout->addSpacerItem(horizontalSpacer);
|
|
|
|
tasksModel = new TasksTableModel(this);
|
|
proxyModel = new TasksFilterProxyModel(this);
|
|
proxyModel->setSourceModel(tasksModel);
|
|
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
|
|
|
tableView = new QTableView(this );
|
|
tableView->setModel(proxyModel);
|
|
tableView->setHorizontalHeader(new BoldHeaderView(Qt::Horizontal, tableView));
|
|
tableView->setContextMenuPolicy( Qt::CustomContextMenu );
|
|
tableView->setAutoFillBackground( false );
|
|
tableView->setShowGrid( false );
|
|
tableView->setSortingEnabled( true );
|
|
tableView->setWordWrap( true );
|
|
tableView->setCornerButtonEnabled( true );
|
|
tableView->setSelectionBehavior( QAbstractItemView::SelectRows );
|
|
tableView->setFocusPolicy( Qt::NoFocus );
|
|
tableView->setAlternatingRowColors( true );
|
|
tableView->horizontalHeader()->setSectionResizeMode( QHeaderView::ResizeToContents );
|
|
tableView->horizontalHeader()->setCascadingSectionResizes( true );
|
|
tableView->horizontalHeader()->setHighlightSections( false );
|
|
tableView->verticalHeader()->setVisible( false );
|
|
tableView->verticalHeader()->setSectionResizeMode( QHeaderView::ResizeToContents );
|
|
|
|
tableView->sortByColumn(TC_StartTime, Qt::AscendingOrder);
|
|
|
|
tableView->horizontalHeader()->setSectionResizeMode( TC_CommandLine, QHeaderView::Stretch );
|
|
tableView->horizontalHeader()->setSectionResizeMode( TC_Output, QHeaderView::Stretch );
|
|
|
|
tableView->setItemDelegate(new PaddingDelegate(tableView));
|
|
tableView->setItemDelegateForColumn(TC_CommandLine, new WrapAnywhereDelegate(tableView));
|
|
tableView->setItemDelegateForColumn(TC_Output, new WrapAnywhereDelegate(tableView));
|
|
|
|
this->UpdateColumnsVisible();
|
|
|
|
mainGridLayout = new QGridLayout(this);
|
|
mainGridLayout->setContentsMargins( 0, 0, 0, 0);
|
|
mainGridLayout->setVerticalSpacing(4);
|
|
mainGridLayout->setHorizontalSpacing(8);
|
|
|
|
mainGridLayout->addWidget( searchWidget, 0, 0, 1, 1 );
|
|
mainGridLayout->addWidget( tableView, 1, 0, 1, 1 );
|
|
|
|
this->setLayout(mainGridLayout);
|
|
}
|
|
|
|
|
|
|
|
void TasksWidget::AddTaskItem(TaskData newTask)
|
|
{
|
|
if ( adaptixWidget->TasksMap.contains(newTask.TaskId) )
|
|
return;
|
|
|
|
newTask.Status = "Hosted";
|
|
if (newTask.Completed) {
|
|
if ( newTask.MessageType == CONSOLE_OUT_ERROR || newTask.MessageType == CONSOLE_OUT_LOCAL_ERROR ) {
|
|
newTask.Status = "Error";
|
|
}
|
|
else if ( newTask.MessageType == CONSOLE_OUT_INFO || newTask.MessageType == CONSOLE_OUT_LOCAL_INFO ) {
|
|
newTask.Status = "Canceled";
|
|
}
|
|
else {
|
|
newTask.Status = "Success";
|
|
}
|
|
}
|
|
else if (newTask.TaskType == 4) {
|
|
newTask.Status = "Running";
|
|
}
|
|
adaptixWidget->TasksMap[newTask.TaskId] = newTask;
|
|
|
|
if (bufferingEnabled) {
|
|
pendingTasks.append(newTask);
|
|
} else {
|
|
tasksModel->add(newTask);
|
|
|
|
if (comboAgent->findText(newTask.AgentId) == -1)
|
|
comboAgent->addItem(newTask.AgentId);
|
|
|
|
if (adaptixWidget->IsSynchronized())
|
|
this->UpdateColumnsSize();
|
|
}
|
|
}
|
|
|
|
void TasksWidget::UpdateTaskItem(const QString &taskId, const TaskData &task) const
|
|
{
|
|
tasksModel->update(taskId, task);
|
|
}
|
|
|
|
void TasksWidget::RemoveTaskItem(const QString &taskId) const
|
|
{
|
|
if ( !adaptixWidget->TasksMap.contains((taskId)))
|
|
return;
|
|
|
|
TaskData task = adaptixWidget->TasksMap[taskId];
|
|
QString agentId = task.AgentId;
|
|
|
|
adaptixWidget->TasksMap.remove(taskId);
|
|
|
|
tasksModel->remove(taskId);
|
|
}
|
|
|
|
void TasksWidget::RemoveAgentTasksItem(const QString &agentId) const
|
|
{
|
|
for (auto key : adaptixWidget->TasksMap.keys()) {
|
|
TaskData task = adaptixWidget->TasksMap[key];
|
|
if (task.AgentId == agentId) {
|
|
adaptixWidget->TasksMap.remove(key);
|
|
|
|
tasksModel->remove(task.TaskId);
|
|
}
|
|
}
|
|
|
|
int index = comboAgent->findText(agentId);
|
|
if (index != -1)
|
|
comboAgent->removeItem(index);
|
|
|
|
tableView->reset();
|
|
}
|
|
|
|
void TasksWidget::SetAgentFilter(const QString &agentId)
|
|
{
|
|
this->searchWidget->setVisible(true);
|
|
this->showPanel = true;
|
|
this->comboAgent->setCurrentText(agentId);
|
|
|
|
this->onFilterChanged();
|
|
}
|
|
|
|
void TasksWidget::UpdateColumnsVisible() const
|
|
{
|
|
for(int i = 0; i < 11; i++) {
|
|
if (GlobalClient->settings->data.TasksTableColumns[i])
|
|
tableView->showColumn(i);
|
|
else
|
|
tableView->hideColumn(i);
|
|
}
|
|
}
|
|
|
|
void TasksWidget::UpdateColumnsSize() const
|
|
{
|
|
tableView->resizeColumnToContents(TC_Client);
|
|
tableView->resizeColumnToContents(TC_User);
|
|
tableView->resizeColumnToContents(TC_Computer);
|
|
tableView->resizeColumnToContents(TC_Result);
|
|
}
|
|
|
|
void TasksWidget::Clear() const
|
|
{
|
|
adaptixWidget->TasksMap.clear();
|
|
|
|
taskOutputConsole->SetConten("", "");
|
|
|
|
tasksModel->clear();
|
|
comboAgent->clear();
|
|
comboAgent->addItem("All agents");
|
|
comboType->clear();
|
|
comboType->addItem("All types");
|
|
comboStatus->setCurrentIndex(0);
|
|
inputFilter->clear();
|
|
}
|
|
|
|
|
|
|
|
/// SLOTS
|
|
|
|
void TasksWidget::toggleSearchPanel()
|
|
{
|
|
if (this->showPanel) {
|
|
this->showPanel = false;
|
|
this->searchWidget->setVisible(false);
|
|
}
|
|
else {
|
|
this->showPanel = true;
|
|
this->searchWidget->setVisible(true);
|
|
inputFilter->setFocus();
|
|
}
|
|
}
|
|
|
|
void TasksWidget::handleTasksMenu( const QPoint &pos )
|
|
{
|
|
QModelIndex index = tableView->indexAt(pos);
|
|
if (!index.isValid()) return;
|
|
|
|
bool cancel = false;
|
|
bool job_running = false;
|
|
bool remove = false;
|
|
|
|
QStringList taskIds;
|
|
QModelIndexList selectedRows = tableView->selectionModel()->selectedRows();
|
|
for (const QModelIndex &proxyIndex : selectedRows) {
|
|
QModelIndex sourceIndex = proxyModel->mapToSource(proxyIndex);
|
|
if (!sourceIndex.isValid()) continue;
|
|
|
|
QString result = tasksModel->data(tasksModel->index(sourceIndex.row(), TC_Result), Qt::DisplayRole).toString();
|
|
QString type = tasksModel->data(tasksModel->index(sourceIndex.row(), TC_TaskType), Qt::DisplayRole).toString();
|
|
QString taskId = tasksModel->data(tasksModel->index(sourceIndex.row(), TC_TaskId), Qt::DisplayRole).toString();
|
|
taskIds.append(taskId);
|
|
|
|
if ( result == "Hosted" )
|
|
cancel = true;
|
|
else if (result == "Running" && type == "JOB")
|
|
job_running = true;
|
|
else
|
|
remove = true;
|
|
}
|
|
|
|
auto ctxMenu = QMenu();
|
|
ctxMenu.addAction("Copy taskID", this, &TasksWidget::actionCopyTaskId);
|
|
ctxMenu.addAction("Copy commandLine", this, &TasksWidget::actionCopyCmd);
|
|
ctxMenu.addSeparator();
|
|
ctxMenu.addAction("Agent console", this, &TasksWidget::actionOpenConsole);
|
|
ctxMenu.addSeparator();
|
|
|
|
int taskCount = adaptixWidget->ScriptManager->AddMenuTask(&ctxMenu, "Tasks", taskIds);
|
|
int jobCount = 0;
|
|
if (job_running)
|
|
jobCount = adaptixWidget->ScriptManager->AddMenuTask(&ctxMenu, "TasksJob", taskIds);
|
|
if (taskCount + jobCount > 0)
|
|
ctxMenu.addSeparator();
|
|
|
|
if (cancel)
|
|
ctxMenu.addAction("Cancel", this, &TasksWidget::actionCancel);
|
|
if (remove)
|
|
ctxMenu.addAction("Delete task", this, &TasksWidget::actionDelete);
|
|
|
|
ctxMenu.exec(tableView->viewport()->mapToGlobal(pos));
|
|
}
|
|
|
|
void TasksWidget::onTableItemSelection(const QModelIndex ¤t, const QModelIndex &previous) const
|
|
{
|
|
Q_UNUSED(previous);
|
|
|
|
auto idx = tableView->currentIndex();
|
|
if (!idx.isValid())
|
|
return;
|
|
|
|
QString taskId = proxyModel->index(idx.row(), TC_TaskId).data().toString();
|
|
if (taskId.isEmpty())
|
|
return;
|
|
|
|
if (!adaptixWidget->TasksMap.contains(taskId))
|
|
return;
|
|
|
|
TaskData taskData = adaptixWidget->TasksMap[taskId];
|
|
taskOutputConsole->SetConten(taskData.Message, taskData.Output);
|
|
adaptixWidget->LoadTasksOutput();
|
|
}
|
|
|
|
void TasksWidget::onFilterChanged() const
|
|
{
|
|
auto *f = qobject_cast<TasksFilterProxyModel *>(proxyModel);
|
|
if (!f) return;
|
|
|
|
f->setAgentFilter(comboAgent->currentText());
|
|
f->setTypeFilter(comboType->currentText());
|
|
f->setStatusFilter(comboStatus->currentText());
|
|
if (autoSearchCheck->isChecked()) {
|
|
f->setTextFilter(inputFilter->text());
|
|
}
|
|
UpdateColumnsSize();
|
|
}
|
|
|
|
void TasksWidget::UpdateFilterComboBoxes() const
|
|
{
|
|
QSet<QString> agents;
|
|
QSet<QString> types;
|
|
|
|
for (const auto& task : adaptixWidget->TasksMap) {
|
|
if (!task.AgentId.isEmpty())
|
|
agents.insert(task.AgentId);
|
|
QString typeStr = task.TaskType == 1 ? "TASK" :
|
|
task.TaskType == 3 ? "JOB" :
|
|
task.TaskType == 4 ? "TUNNEL" : "unknown";
|
|
types.insert(typeStr);
|
|
}
|
|
|
|
QString currentAgent = comboAgent->currentText();
|
|
QString currentType = comboType->currentText();
|
|
|
|
comboAgent->blockSignals(true);
|
|
comboType->blockSignals(true);
|
|
|
|
comboAgent->clear();
|
|
comboAgent->addItem("All agents");
|
|
QStringList agentList = agents.values();
|
|
agentList.sort();
|
|
comboAgent->addItems(agentList);
|
|
|
|
comboType->clear();
|
|
comboType->addItem("All types");
|
|
QStringList typeList = types.values();
|
|
typeList.sort();
|
|
comboType->addItems(typeList);
|
|
|
|
int agentIdx = comboAgent->findText(currentAgent);
|
|
if (agentIdx >= 0)
|
|
comboAgent->setCurrentIndex(agentIdx);
|
|
else
|
|
comboAgent->setCurrentText(currentAgent);
|
|
|
|
int typeIdx = comboType->findText(currentType);
|
|
if (typeIdx >= 0)
|
|
comboType->setCurrentIndex(typeIdx);
|
|
else
|
|
comboType->setCurrentText(currentType);
|
|
|
|
comboAgent->blockSignals(false);
|
|
comboType->blockSignals(false);
|
|
}
|
|
|
|
void TasksWidget::actionCopyTaskId() const
|
|
{
|
|
auto idx = tableView->currentIndex();
|
|
if (idx.isValid()) {
|
|
QString taskId = proxyModel->index(idx.row(), TC_TaskId).data().toString();
|
|
QApplication::clipboard()->setText(taskId);
|
|
}
|
|
}
|
|
|
|
void TasksWidget::actionCopyCmd() const
|
|
{
|
|
auto idx = tableView->currentIndex();
|
|
if (idx.isValid()) {
|
|
QString cmdLine = proxyModel->index(idx.row(), TC_CommandLine).data().toString();
|
|
QApplication::clipboard()->setText(cmdLine);
|
|
}
|
|
}
|
|
|
|
void TasksWidget::actionOpenConsole() const
|
|
{
|
|
auto idx = tableView->currentIndex();
|
|
if (idx.isValid()) {
|
|
QString agentId = proxyModel->index(idx.row(), TC_AgentId).data().toString();
|
|
adaptixWidget->LoadConsoleUI(agentId);
|
|
}
|
|
}
|
|
|
|
void TasksWidget::actionCancel() const
|
|
{
|
|
QMap<QString, QStringList> agentTasks;
|
|
|
|
QModelIndexList selectedRows = tableView->selectionModel()->selectedRows();
|
|
for (const QModelIndex &proxyIndex : selectedRows) {
|
|
QModelIndex sourceIndex = proxyModel->mapToSource(proxyIndex);
|
|
if (!sourceIndex.isValid()) continue;
|
|
|
|
QString agentId = tasksModel->data(tasksModel->index(sourceIndex.row(), TC_AgentId), Qt::DisplayRole).toString();
|
|
QString taskId = tasksModel->data(tasksModel->index(sourceIndex.row(), TC_TaskId), Qt::DisplayRole).toString();
|
|
if (!agentId.isEmpty() && !taskId.isEmpty())
|
|
agentTasks[agentId].append(taskId);
|
|
}
|
|
|
|
for (auto it = agentTasks.begin(); it != agentTasks.end(); ++it) {
|
|
if (adaptixWidget->AgentsMap.contains(it.key()))
|
|
adaptixWidget->AgentsMap[it.key()]->TasksCancel(it.value());
|
|
}
|
|
}
|
|
|
|
void TasksWidget::actionDelete() const
|
|
{
|
|
QMap<QString, QStringList> agentTasks;
|
|
|
|
QModelIndexList selectedRows = tableView->selectionModel()->selectedRows();
|
|
for (const QModelIndex &proxyIndex : selectedRows) {
|
|
QModelIndex sourceIndex = proxyModel->mapToSource(proxyIndex);
|
|
if (!sourceIndex.isValid()) continue;
|
|
|
|
QString agentId = tasksModel->data(tasksModel->index(sourceIndex.row(), TC_AgentId), Qt::DisplayRole).toString();
|
|
QString taskId = tasksModel->data(tasksModel->index(sourceIndex.row(), TC_TaskId), Qt::DisplayRole).toString();
|
|
if (!agentId.isEmpty() && !taskId.isEmpty())
|
|
agentTasks[agentId].append(taskId);
|
|
}
|
|
|
|
for (auto it = agentTasks.begin(); it != agentTasks.end(); ++it) {
|
|
if (adaptixWidget->AgentsMap.contains(it.key()))
|
|
adaptixWidget->AgentsMap[it.key()]->TasksDelete(it.value());
|
|
}
|
|
}
|