2026-04-06 00:20:51 -05:00

2015 lines
64 KiB
C++

#include <Client/AxScript/AxElementWrappers.h>
#include <Client/AxScript/AxScriptEngine.h>
#include <Client/AxScript/AxScriptManager.h>
#include <Agent/Agent.h>
#include <Utils/CustomElements.h>
#include <Utils/NonBlockingDialogs.h>
#include <QJSEngine>
#include <QJsonObject>
#include <QJsonDocument>
#include <QFrame>
#include <QDateEdit>
#include <QDialog>
#include <QMenu>
/// MENU
AxActionWrapper::AxActionWrapper(const QString& text, const QJSValue& handler, QJSEngine* engine, QObject* parent) : AbstractAxMenuItem(parent), handler(handler), engine(engine) { pAction = new QAction(text, this); }
QAction* AxActionWrapper::action() const { return this->pAction; }
void AxActionWrapper::setContext(QVariantList context)
{
disconnect(pAction, nullptr, this, nullptr);
connect(pAction, &QAction::triggered, this, [this, context]() { triggerWithContext(context); }, Qt::QueuedConnection);
}
void AxActionWrapper::triggerWithContext(const QVariantList& arg) const
{
if (!handler.isCallable())
return;
QJSValue jsContext = engine->toScriptValue(arg);
if (this->handler.isCallable())
this->handler.call({ jsContext });
}
AxSeparatorWrapper::AxSeparatorWrapper(QObject* parent) : AbstractAxMenuItem(parent)
{
pAction = new QAction(this);
pAction->setSeparator(true);
}
QAction* AxSeparatorWrapper::action() const { return this->pAction; }
void AxSeparatorWrapper::setContext(QVariantList context) {}
AxMenuWrapper::AxMenuWrapper(const QString& title, QObject* parent) : AbstractAxMenuItem(parent) { pMenu = new QMenu(title); }
QMenu* AxMenuWrapper::menu() const { return this->pMenu; }
void AxMenuWrapper::setContext(const QVariantList context)
{
for (auto item : items)
item->setContext(context);
}
void AxMenuWrapper::addItem(AbstractAxMenuItem* axItem)
{
items.append(axItem);
if (auto* wrapper1 = dynamic_cast<AxSeparatorWrapper*>(axItem)) {
this->pMenu->addAction(wrapper1->action());
}
else if (auto* wrapper2 = dynamic_cast<AxActionWrapper*>(axItem)) {
this->pMenu->addAction(wrapper2->action());
}
else if (auto* wrapper3 = dynamic_cast<AxMenuWrapper*>(axItem)) {
this->pMenu->addMenu(wrapper3->menu());
}
}
/// LAYOUT
AxBoxLayoutWrapper::AxBoxLayoutWrapper(const QBoxLayout::Direction dir, QObject* parent) : QObject(parent) { boxLayout = new QBoxLayout(dir); }
QBoxLayout* AxBoxLayoutWrapper::layout() const { return boxLayout; }
void AxBoxLayoutWrapper::addWidget(QObject* wrapper) const
{
if (auto* formElement = dynamic_cast<AbstractAxVisualElement*>(wrapper))
boxLayout->addWidget(formElement->widget());
else if (auto* spacerElement = qobject_cast<AxSpacerWrapper*>(wrapper))
boxLayout->addItem(spacerElement->widget());
}
/// GRID LAYOUT
AxGridLayoutWrapper::AxGridLayoutWrapper(QObject* parent) : QObject(parent) { gridLayout = new QGridLayout(); }
QGridLayout* AxGridLayoutWrapper::layout() const { return gridLayout; }
void AxGridLayoutWrapper::addWidget(QObject* wrapper, const int row, const int col, const int rowSpan, const int colSpan) const
{
if (auto* formElement = dynamic_cast<AbstractAxVisualElement*>(wrapper))
gridLayout->addWidget(formElement->widget(), row, col, rowSpan, colSpan);
else if (auto* spacerElement = qobject_cast<AxSpacerWrapper*>(wrapper))
gridLayout->addItem(spacerElement->widget(), row, col, rowSpan, colSpan);
}
/// LINE
AxLineWrapper::AxLineWrapper(const QFrame::Shape dir, QObject* parent) : QObject(parent)
{
line = new QFrame();
line->setFrameShape(dir);
if (dir == QFrame::VLine)
line->setMinimumHeight(25);
else
line->setMinimumWidth(25);
}
QFrame* AxLineWrapper::widget() const { return line; }
/// SPACER
AxSpacerWrapper::AxSpacerWrapper(const int w, const int h, const QSizePolicy::Policy hData, const QSizePolicy::Policy vData, QObject* parent) : QObject(parent) { spacer = new QSpacerItem(w, h, hData, vData); }
QSpacerItem* AxSpacerWrapper::widget() const { return spacer; }
/// TEXTLINE
AxTextLineWrapper::AxTextLineWrapper(QLineEdit* edit, QObject* parent) : QObject(parent), lineedit(edit)
{
connect(lineedit, &QLineEdit::textChanged, this, &AxTextLineWrapper::textChanged);
connect(lineedit, &QLineEdit::textEdited, this, &AxTextLineWrapper::textEdited);
connect(lineedit, &QLineEdit::returnPressed, this, &AxTextLineWrapper::returnPressed);
connect(lineedit, &QLineEdit::editingFinished, this, &AxTextLineWrapper::editingFinished);
}
QVariant AxTextLineWrapper::jsonMarshal() const { return lineedit->text(); }
void AxTextLineWrapper::jsonUnmarshal(const QVariant& value) { lineedit->setText(value.toString()); }
QLineEdit* AxTextLineWrapper::widget() const { return lineedit; }
QString AxTextLineWrapper::text() const { return lineedit->text(); }
void AxTextLineWrapper::setText(const QString& text) const { lineedit->setText(text); }
void AxTextLineWrapper::setPlaceholder(const QString& text) const { lineedit->setPlaceholderText(text); }
void AxTextLineWrapper::setReadOnly(const bool &readonly) const { lineedit->setReadOnly(readonly); }
/// COMBO
AxComboBoxWrapper::AxComboBoxWrapper(QComboBox* comboBox, QObject* parent) : QObject(parent), comboBox(comboBox)
{
connect(comboBox, &QComboBox::currentTextChanged, this, &AxComboBoxWrapper::currentTextChanged);
connect(comboBox, &QComboBox::currentIndexChanged, this, &AxComboBoxWrapper::currentIndexChanged);
}
QVariant AxComboBoxWrapper::jsonMarshal() const { return comboBox->currentText(); }
void AxComboBoxWrapper::jsonUnmarshal(const QVariant& value)
{
int index = comboBox->findText(value.toString());
if (index != -1)
comboBox->setCurrentIndex(index);
}
QComboBox * AxComboBoxWrapper::widget() const { return comboBox; }
void AxComboBoxWrapper::addItem(const QString& text) const { comboBox->addItem(text); }
void AxComboBoxWrapper::addItems(const QJSValue& array) const
{
if (!array.isArray())
return;
QStringList items;
const int length = array.property("length").toInt();
for (int i = 0; i < length; ++i) {
QJSValue val = array.property(i);
items << val.toString();
}
comboBox->addItems(items);
}
void AxComboBoxWrapper::setItems(const QJSValue &array) const
{
if (!array.isArray())
return;
QStringList items;
const int length = array.property("length").toInt();
for (int i = 0; i < length; ++i) {
QJSValue val = array.property(i);
items << val.toString();
}
comboBox->clear();
comboBox->addItems(items);
}
void AxComboBoxWrapper::clear() const { comboBox->clear(); }
QString AxComboBoxWrapper::currentText() const { return comboBox->currentText(); }
int AxComboBoxWrapper::currentIndex() const { return comboBox->currentIndex(); }
void AxComboBoxWrapper::setCurrentIndex(const int index) const { comboBox->setCurrentIndex(index); }
/// SPIN
AxSpinBoxWrapper::AxSpinBoxWrapper(QSpinBox* spin, QObject* parent) : QObject(parent), spin(spin) {
connect(spin, &QSpinBox::valueChanged, this, &AxSpinBoxWrapper::valueChanged);
}
QVariant AxSpinBoxWrapper::jsonMarshal() const { return spin->value(); }
void AxSpinBoxWrapper::jsonUnmarshal(const QVariant& value) { spin->setValue(value.toInt()); }
QSpinBox* AxSpinBoxWrapper::widget() const { return spin; }
int AxSpinBoxWrapper::value() const { return spin->value(); }
void AxSpinBoxWrapper::setValue(const int value) const { spin->setValue(value); }
void AxSpinBoxWrapper::setRange(const int min, const int max) const { spin->setRange(min, max); }
/// DATE
AxDateEditWrapper::AxDateEditWrapper(QDateEdit* edit, const QString &format, QObject* parent) : QObject(parent), dateedit(edit)
{
edit->setCalendarPopup(true);
edit->setDisplayFormat(format);
}
QVariant AxDateEditWrapper::jsonMarshal() const { return dateString(); }
void AxDateEditWrapper::jsonUnmarshal(const QVariant& value) { setDateString(value.toString()); }
QDateEdit* AxDateEditWrapper::widget() const { return dateedit; }
QString AxDateEditWrapper::dateString() const { return dateedit->date().toString( dateedit->displayFormat()); }
void AxDateEditWrapper::setDateString(const QString& date) const { dateedit->setDate(QDate::fromString(date, dateedit->displayFormat())); }
/// TIME
AxTimeEditWrapper::AxTimeEditWrapper(QTimeEdit* edit, const QString &format, QObject* parent) : QObject(parent), timeedit(edit)
{
timeedit->setDisplayFormat(format);
}
QVariant AxTimeEditWrapper::jsonMarshal() const { return timeString(); }
void AxTimeEditWrapper::jsonUnmarshal(const QVariant& value) { setTimeString(value.toString()); }
QTimeEdit * AxTimeEditWrapper::widget() const { return timeedit; }
QString AxTimeEditWrapper::timeString() const { return timeedit->time().toString(timeedit->displayFormat()); }
void AxTimeEditWrapper::setTimeString(const QString& time) const { timeedit->setTime(QTime::fromString(time, timeedit->displayFormat())); }
/// TEXTMULTI
AxTextMultiWrapper::AxTextMultiWrapper(QPlainTextEdit* edit, QObject* parent) : QObject(parent), textedit(edit) {}
QVariant AxTextMultiWrapper::jsonMarshal() const { return text(); }
void AxTextMultiWrapper::jsonUnmarshal(const QVariant& value) { setText(value.toString()); }
QPlainTextEdit * AxTextMultiWrapper::widget() const { return textedit; }
QString AxTextMultiWrapper::text() const { return textedit->toPlainText(); }
void AxTextMultiWrapper::setText(const QString& text) const { textedit->setPlainText(text); }
void AxTextMultiWrapper::appendText(const QString &text) const { textedit->appendPlainText(text); }
void AxTextMultiWrapper::setPlaceholder(const QString& text) const { textedit->setPlaceholderText(text); }
void AxTextMultiWrapper::setReadOnly(const bool &readonly) const { textedit->setReadOnly(readonly); }
/// CHECK
AxCheckBoxWrapper::AxCheckBoxWrapper(QCheckBox* box, QObject* parent) : QObject(parent), check(box)
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
connect(check, &QCheckBox::checkStateChanged, this, &AxCheckBoxWrapper::stateChanged);
#else
connect(check, &QCheckBox::stateChanged, this, &AxCheckBoxWrapper::stateChanged);
#endif
}
QVariant AxCheckBoxWrapper::jsonMarshal() const { return isChecked(); }
void AxCheckBoxWrapper::jsonUnmarshal(const QVariant& value) { setChecked(value.toBool()); }
QCheckBox * AxCheckBoxWrapper::widget() const { return check; }
bool AxCheckBoxWrapper::isChecked() const { return check->isChecked(); }
void AxCheckBoxWrapper::setChecked(const bool checked) const { check->setChecked(checked); }
void AxSelectorFile::setPlaceholder(const QString& text) const { lineEdit->setPlaceholderText(text); }
/// LABEL
AxLabelWrapper::AxLabelWrapper(QLabel* label, QObject* parent) : QObject(parent), label(label) {}
QLabel* AxLabelWrapper::widget() const { return label; }
void AxLabelWrapper::setText(const QString& text) const { label->setText(text); }
QString AxLabelWrapper::text() const { return label->text(); }
/// TAB
AxTabWrapper::AxTabWrapper(QTabWidget* tabs, QObject* parent) : QObject(parent), tabs(tabs) {}
QTabWidget* AxTabWrapper::widget() const { return tabs; }
void AxTabWrapper::addTab(QObject* wrapper, const QString &title) const
{
if (auto* formElement = dynamic_cast<AbstractAxVisualElement*>(wrapper))
tabs->addTab(formElement->widget(), title);
}
/// TABLE
AxTableWidgetWrapper::AxTableWidgetWrapper(const QJSValue &headers, QTableView* tableView, QJSEngine* jsEngine, QObject* parent) : QObject(parent), table(tableView), engine(jsEngine) {
model = new QStandardItemModel(this);
table->setModel(model);
connect(model, &QStandardItemModel::itemChanged, this, [this](QStandardItem* item) {
Q_EMIT cellChanged(item->row(), item->column());
});
connect(table, &QTableView::clicked, this, [this](const QModelIndex &index) {
Q_EMIT cellClicked(index.row(), index.column());
});
connect(table, &QTableView::doubleClicked, this, [this](const QModelIndex &index) {
Q_EMIT cellDoubleClicked(index.row(), index.column());
});
table->setHorizontalHeader(new BoldHeaderView(Qt::Horizontal, table));
table->setAlternatingRowColors( true );
table->setAutoFillBackground( false );
table->setShowGrid( false );
table->setSortingEnabled( true );
table->setWordWrap( true );
table->setCornerButtonEnabled( true );
table->setSelectionBehavior( QAbstractItemView::SelectRows );
table->setFocusPolicy( Qt::NoFocus );
table->horizontalHeader()->setSectionResizeMode( QHeaderView::Stretch );
table->horizontalHeader()->setCascadingSectionResizes( true );
table->horizontalHeader()->setHighlightSections( false );
table->verticalHeader()->setVisible( false );
table->setItemDelegate(new PaddingDelegate(table));
this->setColumns(headers);
}
QTableView* AxTableWidgetWrapper::widget() const { return table; }
QVariant AxTableWidgetWrapper::jsonMarshal() const
{
QJsonArray rowsArray;
for (int row = 0; row < model->rowCount(); ++row) {
QJsonArray rowArray;
for (int col = 0; col < model->columnCount(); ++col) {
auto item = model->item(row, col);
rowArray.append(item ? item->text() : QString());
}
rowsArray.append(rowArray);
}
return rowsArray;
}
void AxTableWidgetWrapper::jsonUnmarshal(const QVariant& value)
{
QJsonArray rowsArray = QJsonDocument::fromJson(value.toByteArray()).array();
model->setRowCount(rowsArray.size());
for (int row = 0; row < rowsArray.size(); ++row) {
QJsonArray rowArray = rowsArray[row].toArray();
if (model->columnCount() < rowArray.size())
model->setColumnCount(rowArray.size());
for (int col = 0; col < rowArray.size(); ++col) {
QStandardItem* item = model->item(row, col);
if (!item) {
item = new QStandardItem();
model->setItem(row, col, item);
}
item->setText(rowArray[col].toString());
}
}
}
void AxTableWidgetWrapper::addColumn(const QString &header) const
{
int column = model->columnCount()+1;
model->setColumnCount(column);
model->setHorizontalHeaderItem(column-1, new QStandardItem(header));
}
void AxTableWidgetWrapper::setColumns(const QJSValue &headers) const
{
if (!headers.isArray())
return;
const int length = headers.property("length").toInt();
model->setColumnCount(length);
for (int i = 0; i < length; ++i) {
QJSValue val = headers.property(i);
model->setHorizontalHeaderItem(i, new QStandardItem(val.toString()));
}
}
void AxTableWidgetWrapper::addItem(const QJSValue &items) const
{
if (!items.isArray())
return;
if( model->rowCount() < 1 )
model->setRowCount( 1 );
else
model->setRowCount( model->rowCount() + 1 );
bool isSortingEnabled = table->isSortingEnabled();
table->setSortingEnabled( false );
const int length = items.property("length").toInt();
for (int i = 0; i < model->columnCount(); i++ ) {
QString text = "";
if (i < length)
text = items.property(i).toString();
model->setItem( model->rowCount() - 1, i, new QStandardItem(text) );
}
table->setSortingEnabled( isSortingEnabled );
}
int AxTableWidgetWrapper::rowCount() const { return model->rowCount(); }
int AxTableWidgetWrapper::columnCount() const { return model->columnCount(); }
void AxTableWidgetWrapper::setRowCount(const int rows) { model->setRowCount(rows); }
void AxTableWidgetWrapper::setColumnCount(const int cols) { model->setColumnCount(cols); }
int AxTableWidgetWrapper::currentRow() const { return table->currentIndex().row(); }
int AxTableWidgetWrapper::currentColumn() const { return table->currentIndex().column(); }
void AxTableWidgetWrapper::setSortingEnabled(const bool enable) { table->setSortingEnabled(enable); }
void AxTableWidgetWrapper::resizeToContent(const int column) { table->horizontalHeader()->setSectionResizeMode(column, QHeaderView::ResizeToContents); }
QString AxTableWidgetWrapper::text(const int row, const int column) const { return model->item(row, column)->text(); }
void AxTableWidgetWrapper::setText(const int row, const int column, const QString &text) const { model->item(row, column)->setText(text); }
void AxTableWidgetWrapper::setReadOnly(const bool read)
{
for(int rowIndex = 0; rowIndex < model->rowCount(); rowIndex++) {
for(int columnIndex = 0; columnIndex < model->columnCount(); columnIndex++) {
auto item = model->item(rowIndex, columnIndex);
if (item) {
if (read)
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
else
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
}
}
}
void AxTableWidgetWrapper::hideColumn(const int column) { table->hideColumn(column); }
void AxTableWidgetWrapper::setHeadersVisible(const bool enable) { table->horizontalHeader()->setVisible(enable); }
void AxTableWidgetWrapper::setColumnAlign(const int column, const QString &align)
{
int iAlign= Qt::AlignLeft | Qt::AlignVCenter;
if (align == "center")
iAlign = Qt::AlignCenter;
else if (align == "right")
iAlign = Qt::AlignRight | Qt::AlignVCenter;
for(int rowIndex = 0; rowIndex < model->rowCount(); rowIndex++) {
model->item(rowIndex, column)->setTextAlignment(static_cast<Qt::AlignmentFlag>(iAlign));
}
}
void AxTableWidgetWrapper::clear()
{
QSignalBlocker blocker(table->selectionModel());
model->removeRows(0, model->rowCount());
}
QJSValue AxTableWidgetWrapper::selectedRows()
{
QSet<int> rowSet;
for( int rowIndex = 0 ; rowIndex < model->rowCount() ; rowIndex++ ) {
if ( table->selectionModel()->isSelected(model->index(rowIndex, 0)) )
rowSet.insert(rowIndex);
}
QJSValue jsArray = engine->newArray(rowSet.size());
int i = 0;
for (int row : rowSet) {
jsArray.setProperty(i++, row);
}
return jsArray;
}
/// LIST
class CompactListDelegate : public QStyledItemDelegate {
public:
using QStyledItemDelegate::QStyledItemDelegate;
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override {
QLineEdit* editor = new QLineEdit(parent);
editor->setContentsMargins(0, 0, 0, 0);
return editor;
}
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override {
return QStyledItemDelegate::sizeHint(option, index);
}
};
AxListWidgetWrapper::AxListWidgetWrapper(QWidget* container, QListWidget* widget, QPushButton* btnAdd, QPushButton* btnRemove, QJSEngine* engine, QObject* parent)
: QObject(parent), container(container), list(widget), btnAdd(btnAdd), btnRemove(btnRemove), engine(engine)
{
list->setObjectName("AxCompactList");
list->setAlternatingRowColors(true);
list->setSelectionMode(QAbstractItemView::ExtendedSelection);
list->setEditTriggers(QAbstractItemView::DoubleClicked);
list->setItemDelegate(new CompactListDelegate(list));
list->setSpacing(0);
list->setContextMenuPolicy(Qt::CustomContextMenu);
connect(list, &QWidget::customContextMenuRequested, this, &AxListWidgetWrapper::showContextMenu);
connect(list, &QListWidget::currentTextChanged, this, &AxListWidgetWrapper::currentTextChanged);
connect(list, &QListWidget::currentRowChanged, this, &AxListWidgetWrapper::currentRowChanged);
connect(list, &QListWidget::itemClicked, this, [this](const QListWidgetItem* item) { if (item) Q_EMIT itemClickedText(item->text()); });
connect(list, &QListWidget::itemDoubleClicked, this, [this](const QListWidgetItem* item) { if (item) Q_EMIT itemDoubleClickedText(item->text()); });
btnAdd->setVisible(false);
btnRemove->setVisible(false);
connect(btnAdd, &QPushButton::clicked, this, &AxListWidgetWrapper::onAddClicked);
connect(btnRemove, &QPushButton::clicked, this, &AxListWidgetWrapper::onRemoveClicked);
}
QVariant AxListWidgetWrapper::jsonMarshal() const
{
QVariantList listData;
for (int i = 0; i < list->count(); ++i) {
QListWidgetItem* item = list->item(i);
if (item && item->text() != "")
listData << item->text();
}
return listData;
}
void AxListWidgetWrapper::jsonUnmarshal(const QVariant& value)
{
list->clear();
const QVariantList items = value.toList();
for (const QVariant& v : items) {
list->addItem(v.toString());
}
}
QWidget* AxListWidgetWrapper::widget() const { return container; }
QJSValue AxListWidgetWrapper::items()
{
QJSValue jsArray = engine->newArray(list->count());
for (int i = 0; i < list->count(); ++i) {
QListWidgetItem* item = list->item(i);
if (item)
jsArray.setProperty(i, item->text());
}
return jsArray;
}
void AxListWidgetWrapper::addItem(const QString& text)
{
QListWidgetItem* item = new QListWidgetItem(text);
if (readonly)
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
else
item->setFlags(item->flags() | Qt::ItemIsEditable);
list->addItem(item);
}
void AxListWidgetWrapper::addItems(const QJSValue &items)
{
if (!items.isArray())
return;
const int length = items.property("length").toInt();
for (int i = 0; i < length; i++ ) {
QString text = items.property(i).toString();
QListWidgetItem* item = new QListWidgetItem(text);
if (readonly)
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
else
item->setFlags(item->flags() | Qt::ItemIsEditable);
list->addItem(item);
}
}
void AxListWidgetWrapper::removeItem(const int index) { delete list->takeItem(index); }
QString AxListWidgetWrapper::itemText(const int index) const
{
QListWidgetItem* item = list->item(index);
return item ? item->text() : QString();
}
void AxListWidgetWrapper::setItemText(const int index, const QString& text)
{
QListWidgetItem* item = list->item(index);
if (item)
item->setText(text);
}
void AxListWidgetWrapper::clear() { list->clear(); }
int AxListWidgetWrapper::count() const { return list->count(); }
int AxListWidgetWrapper::currentRow() const { return list->currentRow(); }
void AxListWidgetWrapper::setCurrentRow(const int row) { list->setCurrentRow(row); }
QJSValue AxListWidgetWrapper::selectedRows() const
{
QList<QListWidgetItem*> items = list->selectedItems();
QJSValue array = engine->newArray(items.size());
for (int i = 0; i < items.size(); ++i) {
array.setProperty(i, list->row(items[i]));
}
return array;
}
void AxListWidgetWrapper::setReadOnly(const bool readonly)
{
this->readonly = readonly;
for (int i = 0; i < list->count(); ++i) {
QListWidgetItem* item = list->item(i);
if (this->readonly)
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
else
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
}
void AxListWidgetWrapper::setDragDropEnabled(const bool enabled)
{
if (enabled) {
list->setDragDropMode(QAbstractItemView::InternalMove);
list->setDefaultDropAction(Qt::MoveAction);
} else {
list->setDragDropMode(QAbstractItemView::NoDragDrop);
}
}
void AxListWidgetWrapper::setMenuEnabled(const bool enabled)
{
this->menuEnabled = enabled;
if (enabled) {
list->setContextMenuPolicy(Qt::CustomContextMenu);
connect(list, &QWidget::customContextMenuRequested, this, &AxListWidgetWrapper::showContextMenu);
} else {
list->setContextMenuPolicy(Qt::DefaultContextMenu);
disconnect(list, &QWidget::customContextMenuRequested, this, &AxListWidgetWrapper::showContextMenu);
}
}
void AxListWidgetWrapper::showContextMenu(const QPoint &pos)
{
QMenu menu(list);
QAction* addAction = menu.addAction("Add");
QAction* removeAction = menu.addAction("Remove");
QAction* selected = menu.exec(list->viewport()->mapToGlobal(pos));
if (selected == addAction) {
onAddClicked();
} else if (selected == removeAction) {
onRemoveClicked();
}
}
void AxListWidgetWrapper::setButtonsEnabled(const bool enabled)
{
btnAdd->setVisible(enabled);
btnRemove->setVisible(enabled);
}
void AxListWidgetWrapper::onAddClicked()
{
addItem("");
list->setCurrentRow(list->count() - 1);
list->editItem(list->item(list->count() - 1));
}
void AxListWidgetWrapper::onRemoveClicked()
{
QList<QListWidgetItem*> selectedItems = list->selectedItems();
for (QListWidgetItem* item : selectedItems)
delete item;
}
/// BUTTON
AxButtonWrapper::AxButtonWrapper(QPushButton* btn, QObject* parent) : QObject(parent), button(btn) {
connect(button, &QPushButton::clicked, this, &AxButtonWrapper::clicked);
}
QPushButton* AxButtonWrapper::widget() const { return button; }
/// GROUPBOX
AxGroupBoxWrapper::AxGroupBoxWrapper(const bool checkable, QGroupBox* box, QObject *parent) : QObject(parent), groupBox(box)
{
groupBox->setCheckable(checkable);
groupBox->setLayout(new QHBoxLayout());
connect(groupBox, &QGroupBox::clicked, this, &AxGroupBoxWrapper::clicked);
}
QVariant AxGroupBoxWrapper::jsonMarshal() const { return groupBox->isChecked(); }
void AxGroupBoxWrapper::jsonUnmarshal(const QVariant &value) { groupBox->setChecked(value.toBool()); }
QGroupBox* AxGroupBoxWrapper::widget() const { return groupBox; }
void AxGroupBoxWrapper::setTitle(const QString &title) { groupBox->setTitle(title); }
bool AxGroupBoxWrapper::isCheckable() const { return groupBox->isCheckable(); }
void AxGroupBoxWrapper::setCheckable(const bool checkable) { groupBox->setCheckable(checkable); }
bool AxGroupBoxWrapper::isChecked() const { return groupBox->isChecked(); }
void AxGroupBoxWrapper::setChecked(const bool checked) { groupBox->setChecked(checked); }
void AxGroupBoxWrapper::setPanel(QObject* panel) const
{
if (auto* widget = dynamic_cast<AbstractAxVisualElement*>(panel)) {
delete groupBox->layout();
QHBoxLayout* layout = new QHBoxLayout();
layout->setContentsMargins(1,1,1,1);
layout->addWidget(widget->widget());
groupBox->setLayout(layout);
}
}
/// SCROLLAREA
AxScrollAreaWrapper::AxScrollAreaWrapper(QScrollArea* area, QObject* parent) : QObject(parent), scrollArea(area) { scrollArea->setWidgetResizable(true); }
QScrollArea* AxScrollAreaWrapper::widget() const { return scrollArea; }
void AxScrollAreaWrapper::setPanel(QObject* panel) const
{
if (auto* widget = dynamic_cast<AbstractAxVisualElement*>(panel))
scrollArea->setWidget(widget->widget());
}
void AxScrollAreaWrapper::setWidgetResizable(const bool resizable) { scrollArea->setWidgetResizable(resizable); }
/// SPLITTER
AxSplitterWrapper::AxSplitterWrapper(QSplitter* splitter, QObject *parent) : QObject(parent), splitter(splitter)
{
splitter->setHandleWidth(3);
connect(splitter, &QSplitter::splitterMoved, this, &AxSplitterWrapper::splitterMoved);
}
QSplitter* AxSplitterWrapper::widget() const { return splitter; }
void AxSplitterWrapper::addPage(QObject *w)
{
if (auto* widget = dynamic_cast<AbstractAxVisualElement*>(w))
return splitter->addWidget(widget->widget());
}
void AxSplitterWrapper::setSizes(const QVariantList &sizes)
{
QList<int> list;
for (const QVariant& v : sizes)
list << v.toInt();
splitter->setSizes(list);
}
/// STACK
AxStackedWidgetWrapper::AxStackedWidgetWrapper(QStackedWidget* widget, QObject *parent): QObject(parent), stack(widget) {
connect(stack, &QStackedWidget::currentChanged, this, &AxStackedWidgetWrapper::currentChanged);
}
QStackedWidget* AxStackedWidgetWrapper::widget() const { return stack; }
int AxStackedWidgetWrapper::addPage(QObject* page)
{
if (auto* widget = dynamic_cast<AbstractAxVisualElement*>(page))
return stack->addWidget(widget->widget());
return -1;
}
int AxStackedWidgetWrapper::insertPage(const int index, QObject *page)
{
if (auto* widget = dynamic_cast<AbstractAxVisualElement*>(page))
return stack->insertWidget(index, widget->widget());
return -1;
}
void AxStackedWidgetWrapper::removePage(const int index)
{
if (auto* page = stack->widget(index))
stack->removeWidget(page);
}
void AxStackedWidgetWrapper::setCurrentIndex(const int index) { stack->setCurrentIndex(index); }
int AxStackedWidgetWrapper::currentIndex() const { return stack->currentIndex(); }
int AxStackedWidgetWrapper::count() const { return stack->count(); }
/// PANEL
AxPanelWrapper::AxPanelWrapper(QWidget* w, QObject* parent) : QObject(parent), panel(w) {}
QWidget* AxPanelWrapper::widget() const { return panel; }
void AxPanelWrapper::setLayout(QObject* layoutWrapper) const
{
if (auto* grid = qobject_cast<AxGridLayoutWrapper*>(layoutWrapper))
panel->setLayout(grid->layout());
else if (auto* box = qobject_cast<AxBoxLayoutWrapper*>(layoutWrapper))
panel->setLayout(box->layout());
}
/// CONTAINER
AxContainerWrapper::AxContainerWrapper(QJSEngine* jsEngine, QObject* parent) : QObject(parent), engine(jsEngine) {}
void AxContainerWrapper::put(const QString& id, QObject* wrapper) { widgets[id] = wrapper; }
QObject* AxContainerWrapper::get(const QString &id) { return widgets[id]; }
bool AxContainerWrapper::contains(const QString &id) const { return widgets.contains(id); }
void AxContainerWrapper::remove(const QString& id)
{
if (widgets.contains(id)) {
widgets[id]->deleteLater(); /// ToDo: ???
widgets.remove(id);
}
}
QString AxContainerWrapper::toJson()
{
QJsonObject json;
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
auto* formElement = dynamic_cast<AbstractAxElement*>(it.value());
if (!formElement)
continue;
QJsonValue value = QJsonValue::fromVariant(formElement->jsonMarshal());
json.insert(it.key(), value);
}
QJsonDocument doc(json);
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
}
void AxContainerWrapper::fromJson(const QString& jsonString)
{
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8(), &error);
if (error.error != QJsonParseError::NoError || !doc.isObject())
return;
QJsonObject obj = doc.object();
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
auto* formElement = dynamic_cast<AbstractAxElement*>(it.value());
if (!formElement)
continue;
QString key = it.key();
if (obj.contains(key))
formElement->jsonUnmarshal(obj.value(key).toVariant());
}
}
QJSValue AxContainerWrapper::toProperty()
{
QJSValue result = engine->newObject();
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
auto* formElement = dynamic_cast<AbstractAxElement*>(it.value());
if (!formElement)
continue;
result.setProperty(it.key(), formElement->jsonMarshal().toString());
}
return result;
}
void AxContainerWrapper::fromProperty(const QJSValue &obj)
{
if (!obj.isObject())
return;
for (auto it = widgets.begin(); it != widgets.end(); ++it) {
auto* formElement = dynamic_cast<AbstractAxElement*>(it.value());
if (!formElement)
continue;
QString key = it.key();
if (obj.hasProperty(key))
formElement->jsonUnmarshal(obj.property(key).toString());
}
}
/// DIALOG
AxDialogWrapper::AxDialogWrapper(const QString& title, QWidget* parent) : QObject(parent)
{
dialog = new QDialog(parent);
dialog->setWindowTitle(title);
dialog->setProperty("Main", "base");
layout = new QVBoxLayout(dialog);
buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
layout->addWidget(buttons);
dialog->setLayout(layout);
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
}
void AxDialogWrapper::setLayout(QObject* layoutWrapper)
{
if (userLayout) {
layout->removeItem(userLayout);
delete userLayout;
userLayout = nullptr;
}
if (auto* grid = qobject_cast<AxGridLayoutWrapper*>(layoutWrapper))
userLayout = grid->layout();
else if (auto* box = qobject_cast<AxBoxLayoutWrapper*>(layoutWrapper))
userLayout = box->layout();
if (userLayout)
layout->insertLayout(0, userLayout);
}
void AxDialogWrapper::setSize(const int w, const int h ) const { dialog->resize(w, h); }
bool AxDialogWrapper::exec() const { return dialog->exec() == QDialog::Accepted; }
void AxDialogWrapper::close() const { dialog->close(); }
void AxDialogWrapper::setButtonsText(const QString &ok_text, const QString &cancel_text) const
{
QPushButton *okButton = buttons->button(QDialogButtonBox::Ok);
if (okButton) {
okButton->setText(ok_text);
}
QPushButton *cancelButton = buttons->button(QDialogButtonBox::Cancel);
if (cancelButton) {
cancelButton->setText(cancel_text);
}
}
#include <UI/Widgets/AdaptixWidget.h>
#include <Client/AuthProfile.h>
AxExtDialogWrapper::AxExtDialogWrapper(AdaptixWidget* w, const QString& title) : QObject(nullptr)
{
adaptixWidget = w;
QString project = w->GetProfile()->GetProject();
dialogId = title + "-" + project;
dialogTitle = title;
dialog = new QDialog();
dialog->setWindowTitle(title);
dialog->setProperty("Main", "base");
layout = new QVBoxLayout(dialog);
buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
layout->addWidget(buttons);
dialog->setLayout(layout);
connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject);
if (adaptixWidget) {
adaptixWidget->AddExtDock(dialogId, title, [this]() {
show();
});
}
}
AxExtDialogWrapper::~AxExtDialogWrapper()
{
if (adaptixWidget)
adaptixWidget->RemoveExtDock(dialogId);
if (dialog) {
dialog->close();
dialog->deleteLater();
}
}
void AxExtDialogWrapper::setLayout(QObject* layoutWrapper)
{
if (userLayout) {
layout->removeItem(userLayout);
delete userLayout;
userLayout = nullptr;
}
if (auto* grid = qobject_cast<AxGridLayoutWrapper*>(layoutWrapper))
userLayout = grid->layout();
else if (auto* box = qobject_cast<AxBoxLayoutWrapper*>(layoutWrapper))
userLayout = box->layout();
if (userLayout)
layout->insertLayout(0, userLayout);
}
void AxExtDialogWrapper::setSize(const int w, const int h) const { dialog->resize(w, h); }
bool AxExtDialogWrapper::exec() const { return dialog->exec() == QDialog::Accepted; }
void AxExtDialogWrapper::show() const { dialog->show(); }
void AxExtDialogWrapper::close() const { dialog->close(); }
void AxExtDialogWrapper::setButtonsText(const QString &ok_text, const QString &cancel_text) const
{
QPushButton *okButton = buttons->button(QDialogButtonBox::Ok);
if (okButton) {
okButton->setText(ok_text);
}
QPushButton *cancelButton = buttons->button(QDialogButtonBox::Cancel);
if (cancelButton) {
cancelButton->setText(cancel_text);
}
}
/// FILE SELECTOR
AxSelectorFile::AxSelectorFile(QLineEdit* edit, QObject* parent) : QObject(parent), lineEdit(edit)
{
lineEdit->setReadOnly(true);
auto action = lineEdit->addAction(QIcon(":/icons/folder"), QLineEdit::TrailingPosition);
connect(action, &QAction::triggered, this, &AxSelectorFile::onSelectFile);
}
QLineEdit* AxSelectorFile::widget() const { return lineEdit; }
QVariant AxSelectorFile::jsonMarshal() const { return content; }
void AxSelectorFile::jsonUnmarshal(const QVariant& value)
{
content = value.toString();
lineEdit->setText("Selected...");
}
void AxSelectorFile::onSelectFile()
{
NonBlockingDialogs::getOpenFileName(lineEdit, "Select a file", "", "All Files (*.*)",
[this](const QString& selectedFile) {
if (selectedFile.isEmpty())
return;
lineEdit->setText(selectedFile);
QFile file(selectedFile);
if (!file.open(QIODevice::ReadOnly))
return;
QByteArray fileData = file.readAll();
file.close();
content = QString::fromUtf8(fileData.toBase64());
});
}
/// SELECTOR CREDENTIALS
AxDialogCreds::AxDialogCreds(const QJSValue &headers, const QVector<CredentialData> &vecCreds, QWidget *parent)
{
this->setProperty("Main", "base");
tableView = new QTableView(this);
tableView->setAlternatingRowColors(true);
tableView->setShowGrid(false);
tableView->setSortingEnabled(true);
tableView->setWordWrap(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
tableView->setFocusPolicy(Qt::NoFocus);
tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
tableView->horizontalHeader()->setCascadingSectionResizes(true);
tableView->horizontalHeader()->setHighlightSections(false);
tableView->verticalHeader()->setVisible(false);
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableModel = new AxCredsTableModel(this);
proxyModel = new AxCredsFilterProxyModel(this);
proxyModel->setSourceModel(tableModel);
tableView->setModel(proxyModel);
chooseButton = new QPushButton("Choose", this);
spacer_1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
spacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
bottomLayout = new QHBoxLayout();
bottomLayout->addItem(spacer_1);
bottomLayout->addWidget(chooseButton);
bottomLayout->addItem(spacer_2);
searchWidget = new QWidget(this);
searchLineEdit = new QLineEdit(searchWidget);
searchLineEdit->setPlaceholderText("filter");
hideButton = new ClickableLabel("X");
hideButton->setCursor(Qt::PointingHandCursor);
searchLayout = new QHBoxLayout(searchWidget);
searchLayout->setContentsMargins(0, 0, 0, 0);
searchLayout->setSpacing(4);
searchLayout->addWidget(searchLineEdit);
searchLayout->addWidget(hideButton);
mainLayout = new QVBoxLayout();
mainLayout->addWidget(searchWidget);
mainLayout->addWidget(tableView);
mainLayout->addLayout(bottomLayout);
setLayout(mainLayout);
connect(searchLineEdit, &QLineEdit::textEdited, this, &AxDialogCreds::handleSearch);
connect(chooseButton, &QPushButton::clicked, this, &AxDialogCreds::onClicked);
connect(hideButton, &ClickableLabel::clicked, this, &AxDialogCreds::clearSearch);
QVector<QString> headerLabels;
QVector<QString> fieldKeys;
const int length = headers.property("length").toInt();
for (int i = 0; i < length; ++i) {
QString val = headers.property(i).toString();
if (FIELD_MAP_CREDS.contains(val)) {
headerLabels.append(FIELD_MAP_CREDS[val]);
fieldKeys.append(val);
}
}
headerLabels.append("CredId");
fieldKeys.append("id");
tableModel->setHeaders(headerLabels, fieldKeys);
tableModel->setData(vecCreds);
int lastCol = headerLabels.size() - 1;
tableView->hideColumn(lastCol);
if (headerLabels.size() > 2) {
for (int i = 0; i < headerLabels.size() - 2; ++i) {
tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
}
}
QVector<CredentialData> AxDialogCreds::data() { return selectedData; }
void AxDialogCreds::onClicked()
{
selectedData.clear();
QModelIndexList selected = tableView->selectionModel()->selectedRows();
for (const auto& proxyIndex : selected) {
QModelIndex sourceIndex = proxyModel->mapToSource(proxyIndex);
if (sourceIndex.isValid()) {
selectedData.append(tableModel->getCredential(sourceIndex.row()));
}
}
this->accept();
}
void AxDialogCreds::handleSearch()
{
proxyModel->setFilterText(searchLineEdit->text());
}
void AxDialogCreds::clearSearch()
{
searchLineEdit->clear();
handleSearch();
}
AxSelectorCreds::AxSelectorCreds(const QJSValue &headers, AxScriptEngine* jsEngine, QWidget* parent) : QObject(parent), scriptEngine(jsEngine)
{
auto vecCreds = scriptEngine->manager()->GetCredentials();
dialog = new AxDialogCreds(headers, vecCreds);
dialog->setWindowTitle("Choose credentials");
}
void AxSelectorCreds::setSize(const int w, const int h ) const { dialog->resize(w, h); }
QJSValue AxSelectorCreds::exec() const
{
QVector<CredentialData> vecCreds;
if (dialog->exec() == QDialog::Accepted) {
vecCreds = dialog->data();
}
QVariantList list;
for (auto cred : vecCreds) {
QVariantMap map;
map["id"] = cred.CredId;
map["username"] = cred.Username;
map["password"] = cred.Password;
map["realm"] = cred.Realm;
map["type"] = cred.Type;
map["tag"] = cred.Tag;
map["date"] = cred.Date;
map["storage"] = cred.Storage;
map["agent_id"] = cred.AgentId;
map["host"] = cred.Host;
list.append(map);
}
return this->scriptEngine->engine()->toScriptValue(list);
}
void AxSelectorCreds::close() const { dialog->close(); }
/// SELECTOR AGENTS
AxDialogAgents::AxDialogAgents(const QJSValue &headers, const QVector<AgentData> &vecAgents, QWidget *parent)
{
this->setProperty("Main", "base");
tableView = new QTableView(this);
tableView->setAlternatingRowColors(true);
tableView->setShowGrid(false);
tableView->setSortingEnabled(true);
tableView->setWordWrap(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
tableView->setFocusPolicy(Qt::NoFocus);
tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
tableView->horizontalHeader()->setCascadingSectionResizes(true);
tableView->horizontalHeader()->setHighlightSections(false);
tableView->verticalHeader()->setVisible(false);
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableModel = new AxAgentsTableModel(this);
proxyModel = new AxAgentsFilterProxyModel(this);
proxyModel->setSourceModel(tableModel);
tableView->setModel(proxyModel);
chooseButton = new QPushButton("Choose", this);
spacer_1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
spacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
bottomLayout = new QHBoxLayout();
bottomLayout->addItem(spacer_1);
bottomLayout->addWidget(chooseButton);
bottomLayout->addItem(spacer_2);
searchWidget = new QWidget(this);
searchLineEdit = new QLineEdit(searchWidget);
searchLineEdit->setPlaceholderText("filter");
hideButton = new ClickableLabel("X");
hideButton->setCursor(Qt::PointingHandCursor);
searchLayout = new QHBoxLayout(searchWidget);
searchLayout->setContentsMargins(0, 0, 0, 0);
searchLayout->setSpacing(4);
searchLayout->addWidget(searchLineEdit);
searchLayout->addWidget(hideButton);
mainLayout = new QVBoxLayout();
mainLayout->addWidget(searchWidget);
mainLayout->addWidget(tableView);
mainLayout->addLayout(bottomLayout);
setLayout(mainLayout);
connect(searchLineEdit, &QLineEdit::textEdited, this, &AxDialogAgents::handleSearch);
connect(chooseButton, &QPushButton::clicked, this, &AxDialogAgents::onClicked);
connect(hideButton, &ClickableLabel::clicked, this, &AxDialogAgents::clearSearch);
QVector<QString> headerLabels;
QVector<QString> fieldKeys;
const int length = headers.property("length").toInt();
for (int i = 0; i < length; ++i) {
QString val = headers.property(i).toString();
if (FIELD_MAP_AGENTS.contains(val)) {
headerLabels.append(FIELD_MAP_AGENTS[val]);
fieldKeys.append(val);
}
}
headerLabels.append("Agent ID");
fieldKeys.append("id");
tableModel->setHeaders(headerLabels, fieldKeys);
tableModel->setData(vecAgents);
int lastCol = headerLabels.size() - 1;
tableView->hideColumn(lastCol);
if (headerLabels.size() > 2) {
for (int i = 0; i < headerLabels.size() - 2; ++i) {
tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
}
}
QVector<AgentData> AxDialogAgents::data() { return selectedData; }
void AxDialogAgents::onClicked()
{
selectedData.clear();
QModelIndexList selected = tableView->selectionModel()->selectedRows();
for (const auto& proxyIndex : selected) {
QModelIndex sourceIndex = proxyModel->mapToSource(proxyIndex);
if (sourceIndex.isValid()) {
selectedData.append(tableModel->getAgent(sourceIndex.row()));
}
}
this->accept();
}
void AxDialogAgents::handleSearch()
{
proxyModel->setFilterText(searchLineEdit->text());
}
void AxDialogAgents::clearSearch()
{
searchLineEdit->clear();
handleSearch();
}
AxSelectorAgents::AxSelectorAgents(const QJSValue &headers, AxScriptEngine* jsEngine, QWidget* parent) : QObject(parent), scriptEngine(jsEngine)
{
QVector<AgentData> vecAgents;
auto agents = scriptEngine->manager()->GetAgents().values();
for (auto agent : agents)
vecAgents.append(agent->data);
dialog = new AxDialogAgents(headers, vecAgents);
dialog->setWindowTitle("Choose agent");
}
void AxSelectorAgents::setSize(const int w, const int h ) const { dialog->resize(w, h); }
QJSValue AxSelectorAgents::exec() const
{
QVector<AgentData> vecAgents;
if (dialog->exec() == QDialog::Accepted) {
vecAgents = dialog->data();
}
QVariantList list;
for (auto agentData : vecAgents) {
QString username = agentData.Username;
if ( agentData.Elevated )
username = "* " + username;
if ( !agentData.Impersonated.isEmpty() )
username += " [" + agentData.Impersonated + "]";
QString process = QString("%1 (%2)").arg(agentData.Process).arg(agentData.Arch);
QString os = "unknown";
if (agentData.Os == OS_WINDOWS) os = "windows";
else if (agentData.Os == OS_LINUX) os = "linux";
else if (agentData.Os == OS_MAC) os = "macos";
QVariantMap map;
map["id"] = agentData.Id;
map["type"] = agentData.Name;
map["listener"] = agentData.Listener;
map["external_ip"] = agentData.ExternalIP;
map["internal_ip"] = agentData.InternalIP;
map["domain"] = agentData.Domain;
map["computer"] = agentData.Computer;
map["username"] = username;
map["process"] = process;
map["pid"] = agentData.Pid;
map["tid"] = agentData.Tid;
map["os"] = os;
map["tags"] = agentData.Tags;
list.append(map);
}
return this->scriptEngine->engine()->toScriptValue(list);
}
void AxSelectorAgents::close() const { dialog->close(); }
/// SELECTOR LISTENERS
AxDialogListeners::AxDialogListeners(const QJSValue &headers, const QVector<ListenerData> &vecListeners, QWidget *parent)
{
this->setProperty("Main", "base");
tableView = new QTableView(this);
tableView->setAlternatingRowColors(true);
tableView->setShowGrid(false);
tableView->setSortingEnabled(true);
tableView->setWordWrap(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
tableView->setFocusPolicy(Qt::NoFocus);
tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
tableView->horizontalHeader()->setCascadingSectionResizes(true);
tableView->horizontalHeader()->setHighlightSections(false);
tableView->verticalHeader()->setVisible(false);
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableModel = new AxListenersTableModel(this);
proxyModel = new AxListenersFilterProxyModel(this);
proxyModel->setSourceModel(tableModel);
tableView->setModel(proxyModel);
chooseButton = new QPushButton("Choose", this);
spacer_1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
spacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
bottomLayout = new QHBoxLayout();
bottomLayout->addItem(spacer_1);
bottomLayout->addWidget(chooseButton);
bottomLayout->addItem(spacer_2);
searchWidget = new QWidget(this);
searchLineEdit = new QLineEdit(searchWidget);
searchLineEdit->setPlaceholderText("filter");
hideButton = new ClickableLabel("X");
hideButton->setCursor(Qt::PointingHandCursor);
searchLayout = new QHBoxLayout(searchWidget);
searchLayout->setContentsMargins(0, 0, 0, 0);
searchLayout->setSpacing(4);
searchLayout->addWidget(searchLineEdit);
searchLayout->addWidget(hideButton);
mainLayout = new QVBoxLayout();
mainLayout->addWidget(searchWidget);
mainLayout->addWidget(tableView);
mainLayout->addLayout(bottomLayout);
setLayout(mainLayout);
connect(searchLineEdit, &QLineEdit::textEdited, this, &AxDialogListeners::handleSearch);
connect(chooseButton, &QPushButton::clicked, this, &AxDialogListeners::onClicked);
connect(hideButton, &ClickableLabel::clicked, this, &AxDialogListeners::clearSearch);
QVector<QString> headerLabels;
QVector<QString> fieldKeys;
const int length = headers.property("length").toInt();
for (int i = 0; i < length; ++i) {
QString val = headers.property(i).toString();
if (FIELD_MAP_LISTENERS.contains(val)) {
headerLabels.append(FIELD_MAP_LISTENERS[val]);
fieldKeys.append(val);
}
}
headerLabels.append("Name");
fieldKeys.append("name");
tableModel->setHeaders(headerLabels, fieldKeys);
tableModel->setData(vecListeners);
int lastCol = headerLabels.size() - 1;
tableView->hideColumn(lastCol);
if (headerLabels.size() > 2) {
for (int i = 0; i < headerLabels.size() - 2; ++i) {
tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
}
}
QVector<ListenerData> AxDialogListeners::data() { return selectedData; }
void AxDialogListeners::onClicked()
{
selectedData.clear();
QModelIndexList selected = tableView->selectionModel()->selectedRows();
for (const auto& proxyIndex : selected) {
QModelIndex sourceIndex = proxyModel->mapToSource(proxyIndex);
if (sourceIndex.isValid()) {
selectedData.append(tableModel->getListener(sourceIndex.row()));
}
}
this->accept();
}
void AxDialogListeners::handleSearch()
{
proxyModel->setFilterText(searchLineEdit->text());
}
void AxDialogListeners::clearSearch()
{
searchLineEdit->clear();
handleSearch();
}
AxSelectorListeners::AxSelectorListeners(const QJSValue &headers, AxScriptEngine* jsEngine, QWidget* parent) : QObject(parent), scriptEngine(jsEngine)
{
auto vecListeners = scriptEngine->manager()->GetListeners();
dialog = new AxDialogListeners(headers, vecListeners);
dialog->setWindowTitle("Choose listener");
}
void AxSelectorListeners::setSize(const int w, const int h ) const { dialog->resize(w, h); }
QJSValue AxSelectorListeners::exec() const
{
QVector<ListenerData> vecListeners;
if (dialog->exec() == QDialog::Accepted) {
vecListeners = dialog->data();
}
QVariantList list;
for (auto listener : vecListeners) {
QVariantMap map;
map["name"] = listener.Name;
map["type"] = listener.ListenerType;
map["protocol"] = listener.ListenerProtocol;
map["bind_host"] = listener.BindHost;
map["bind_port"] = listener.BindPort;
map["agent_addr"] = listener.AgentAddresses;
map["status"] = listener.Status;
map["date"] = listener.Date;
list.append(map);
}
return this->scriptEngine->engine()->toScriptValue(list);
}
void AxSelectorListeners::close() const { dialog->close(); }
/// SELECTOR TARGETS
AxDialogTargets::AxDialogTargets(const QJSValue &headers, const QVector<TargetData> &vecTargets, QWidget *parent)
{
this->setProperty("Main", "base");
tableView = new QTableView(this);
tableView->setAlternatingRowColors(true);
tableView->setShowGrid(false);
tableView->setSortingEnabled(true);
tableView->setWordWrap(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
tableView->setFocusPolicy(Qt::NoFocus);
tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
tableView->horizontalHeader()->setCascadingSectionResizes(true);
tableView->horizontalHeader()->setHighlightSections(false);
tableView->verticalHeader()->setVisible(false);
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableModel = new AxTargetsTableModel(this);
proxyModel = new AxTargetsFilterProxyModel(this);
proxyModel->setSourceModel(tableModel);
tableView->setModel(proxyModel);
chooseButton = new QPushButton("Choose", this);
spacer_1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
spacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
bottomLayout = new QHBoxLayout();
bottomLayout->addItem(spacer_1);
bottomLayout->addWidget(chooseButton);
bottomLayout->addItem(spacer_2);
searchWidget = new QWidget(this);
searchLineEdit = new QLineEdit(searchWidget);
searchLineEdit->setPlaceholderText("filter");
hideButton = new ClickableLabel("X");
hideButton->setCursor(Qt::PointingHandCursor);
searchLayout = new QHBoxLayout(searchWidget);
searchLayout->setContentsMargins(0, 0, 0, 0);
searchLayout->setSpacing(4);
searchLayout->addWidget(searchLineEdit);
searchLayout->addWidget(hideButton);
mainLayout = new QVBoxLayout();
mainLayout->addWidget(searchWidget);
mainLayout->addWidget(tableView);
mainLayout->addLayout(bottomLayout);
setLayout(mainLayout);
connect(searchLineEdit, &QLineEdit::textEdited, this, &AxDialogTargets::handleSearch);
connect(chooseButton, &QPushButton::clicked, this, &AxDialogTargets::onClicked);
connect(hideButton, &ClickableLabel::clicked, this, &AxDialogTargets::clearSearch);
QVector<QString> headerLabels;
QVector<QString> fieldKeys;
const int length = headers.property("length").toInt();
for (int i = 0; i < length; ++i) {
QString val = headers.property(i).toString();
if (FIELD_MAP_TARGETS.contains(val)) {
headerLabels.append(FIELD_MAP_TARGETS[val]);
fieldKeys.append(val);
}
}
headerLabels.append("Target ID");
fieldKeys.append("id");
tableModel->setHeaders(headerLabels, fieldKeys);
tableModel->setData(vecTargets);
int lastCol = headerLabels.size() - 1;
tableView->hideColumn(lastCol);
if (headerLabels.size() > 2) {
for (int i = 0; i < headerLabels.size() - 2; ++i) {
tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
}
}
QVector<TargetData> AxDialogTargets::data() { return selectedData; }
void AxDialogTargets::onClicked()
{
selectedData.clear();
QModelIndexList selected = tableView->selectionModel()->selectedRows();
for (const auto& proxyIndex : selected) {
QModelIndex sourceIndex = proxyModel->mapToSource(proxyIndex);
if (sourceIndex.isValid()) {
selectedData.append(tableModel->getTarget(sourceIndex.row()));
}
}
this->accept();
}
void AxDialogTargets::handleSearch()
{
proxyModel->setFilterText(searchLineEdit->text());
}
void AxDialogTargets::clearSearch()
{
searchLineEdit->clear();
handleSearch();
}
AxSelectorTargets::AxSelectorTargets(const QJSValue &headers, AxScriptEngine* jsEngine, QWidget* parent) : QObject(parent), scriptEngine(jsEngine)
{
auto vecTargets = scriptEngine->manager()->GetTargets();
dialog = new AxDialogTargets(headers, vecTargets);
dialog->setWindowTitle("Choose target");
}
void AxSelectorTargets::setSize(const int w, const int h ) const { dialog->resize(w, h); }
QJSValue AxSelectorTargets::exec() const
{
QVector<TargetData> vecTargets;
if (dialog->exec() == QDialog::Accepted) {
vecTargets = dialog->data();
}
QVariantList list;
for (auto target : vecTargets) {
QString os = "unknown";
if (target.Os == OS_WINDOWS) os = "windows";
else if (target.Os == OS_LINUX) os = "linux";
else if (target.Os == OS_MAC) os = "macos";
QVariantMap map;
map["id"] = target.TargetId;
map["computer"] = target.Computer;
map["domain"] = target.Domain;
map["address"] = target.Address;
map["tag"] = target.Tag;
map["os"] = os;
map["os_desc"] = target.OsDesc;
map["info"] = target.Info;
map["date"] = target.Date;
map["alive"] = target.Alive;
list.append(map);
}
return this->scriptEngine->engine()->toScriptValue(list);
}
void AxSelectorTargets::close() const { dialog->close(); }
/// SELECTOR DOWNLOADS
AxDialogDownloads::AxDialogDownloads(const QJSValue &headers, const QVector<DownloadData> &vecDownloads, QWidget *parent)
{
this->setProperty("Main", "base");
tableView = new QTableView(this);
tableView->setAlternatingRowColors(true);
tableView->setShowGrid(false);
tableView->setSortingEnabled(true);
tableView->setWordWrap(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
tableView->setFocusPolicy(Qt::NoFocus);
tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
tableView->horizontalHeader()->setCascadingSectionResizes(true);
tableView->horizontalHeader()->setHighlightSections(false);
tableView->verticalHeader()->setVisible(false);
tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
tableModel = new AxDownloadsTableModel(this);
proxyModel = new AxDownloadsFilterProxyModel(this);
proxyModel->setSourceModel(tableModel);
tableView->setModel(proxyModel);
chooseButton = new QPushButton("Choose", this);
spacer_1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
spacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Maximum);
bottomLayout = new QHBoxLayout();
bottomLayout->addItem(spacer_1);
bottomLayout->addWidget(chooseButton);
bottomLayout->addItem(spacer_2);
searchWidget = new QWidget(this);
searchLineEdit = new QLineEdit(searchWidget);
searchLineEdit->setPlaceholderText("filter");
hideButton = new ClickableLabel("X");
hideButton->setCursor(Qt::PointingHandCursor);
searchLayout = new QHBoxLayout(searchWidget);
searchLayout->setContentsMargins(0, 0, 0, 0);
searchLayout->setSpacing(4);
searchLayout->addWidget(searchLineEdit);
searchLayout->addWidget(hideButton);
mainLayout = new QVBoxLayout();
mainLayout->addWidget(searchWidget);
mainLayout->addWidget(tableView);
mainLayout->addLayout(bottomLayout);
setLayout(mainLayout);
connect(searchLineEdit, &QLineEdit::textEdited, this, &AxDialogDownloads::handleSearch);
connect(chooseButton, &QPushButton::clicked, this, &AxDialogDownloads::onClicked);
connect(hideButton, &ClickableLabel::clicked, this, &AxDialogDownloads::clearSearch);
QVector<QString> headerLabels;
QVector<QString> fieldKeys;
const int length = headers.property("length").toInt();
for (int i = 0; i < length; ++i) {
QString val = headers.property(i).toString();
if (FIELD_MAP_DOWNLOADS.contains(val)) {
headerLabels.append(FIELD_MAP_DOWNLOADS[val]);
fieldKeys.append(val);
}
}
headerLabels.append("File ID");
fieldKeys.append("id");
tableModel->setHeaders(headerLabels, fieldKeys);
tableModel->setData(vecDownloads);
int lastCol = headerLabels.size() - 1;
tableView->hideColumn(lastCol);
if (headerLabels.size() > 2) {
for (int i = 0; i < headerLabels.size() - 2; ++i) {
tableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::ResizeToContents);
}
}
}
QVector<DownloadData> AxDialogDownloads::data() { return selectedData; }
void AxDialogDownloads::onClicked()
{
selectedData.clear();
QModelIndexList selected = tableView->selectionModel()->selectedRows();
for (const auto& proxyIndex : selected) {
QModelIndex sourceIndex = proxyModel->mapToSource(proxyIndex);
if (sourceIndex.isValid()) {
selectedData.append(tableModel->getDownload(sourceIndex.row()));
}
}
this->accept();
}
void AxDialogDownloads::handleSearch()
{
proxyModel->setFilterText(searchLineEdit->text());
}
void AxDialogDownloads::clearSearch()
{
searchLineEdit->clear();
handleSearch();
}
AxSelectorDownloads::AxSelectorDownloads(const QJSValue &headers, AxScriptEngine* jsEngine, QWidget* parent) : QObject(parent), scriptEngine(jsEngine)
{
auto mapDownloads = scriptEngine->manager()->GetDownloads();
QVector<DownloadData> vecDownloads;
for (const auto& download : mapDownloads)
vecDownloads.append(download);
dialog = new AxDialogDownloads(headers, vecDownloads);
dialog->setWindowTitle("Choose download");
}
void AxSelectorDownloads::setSize(const int w, const int h ) const { dialog->resize(w, h); }
QJSValue AxSelectorDownloads::exec() const
{
QVector<DownloadData> vecDownloads;
if (dialog->exec() == QDialog::Accepted) {
vecDownloads = dialog->data();
}
QVariantList list;
for (auto download : vecDownloads) {
QString state;
switch (download.State) {
case DOWNLOAD_STATE_RUNNING: state = "running"; break;
case DOWNLOAD_STATE_STOPPED: state = "stopped"; break;
case DOWNLOAD_STATE_FINISHED: state = "finished"; break;
default: state = "canceled"; break;
}
QVariantMap map;
map["id"] = download.FileId;
map["agent_id"] = download.AgentId;
map["agent_name"] = download.AgentName;
map["user"] = download.User;
map["computer"] = download.Computer;
map["filename"] = download.Filename;
map["total_size"] = download.TotalSize;
map["recv_size"] = download.RecvSize;
map["state"] = state;
map["date"] = download.Date;
list.append(map);
}
return this->scriptEngine->engine()->toScriptValue(list);
}
void AxSelectorDownloads::close() const { dialog->close(); }
/// DOCK WIDGET
#include <UI/Widgets/AdaptixWidget.h>
#include <Client/AuthProfile.h>
#include <MainAdaptix.h>
#include <UI/MainUI.h>
AxDockWrapper::AxDockWrapper(AdaptixWidget* w, const QString& id, const QString& title, const QString& location): DockTab(title, w->GetProfile()->GetProject())
{
adaptixWidget = w;
QString project = w->GetProfile()->GetProject();
contentWidget = new QWidget();
contentWidget->setProperty("Main", "base");
dockWidget->setWidget(contentWidget);
dockId = id + "-" + project;
dockTitle = title;
if (adaptixWidget) {
adaptixWidget->AddExtDock(dockId, title, [this]() {
show();
});
}
if (location == "top") {
w->PlaceDock(w->get_dockTop() , dockWidget);
dockWidget->toggleAction()->trigger();
}
else if (location == "bottom") {
w->PlaceDock(w->get_dockBottom() , dockWidget);
dockWidget->toggleAction()->trigger();
}
else {
dockWidget->open();
}
connect(dockWidget, &KDDockWidgets::QtWidgets::DockWidget::isOpenChanged, this, [this](bool open) {
if (!open) {
Q_EMIT hidden();
} else {
Q_EMIT shown();
}
});
}
AxDockWrapper::~AxDockWrapper()
{
if (adaptixWidget)
adaptixWidget->RemoveExtDock(dockId);
if (dockWidget) {
dockWidget->close();
dockWidget->deleteLater();
}
}
void AxDockWrapper::setLayout(QObject* layoutWrapper)
{
if (auto* lw = dynamic_cast<AbstractAxLayout*>(layoutWrapper)) {
if (contentWidget->layout())
delete contentWidget->layout();
contentWidget->setLayout(lw->layout());
}
}
void AxDockWrapper::setSize(const int w, const int h) const
{
if (contentWidget)
contentWidget->resize(w, h);
}
void AxDockWrapper::show()
{
if (!dockWidget)
return;
if ( !dockWidget->isOpen() )
dockWidget->toggleAction()->trigger();
}
void AxDockWrapper::hide()
{
if (dockWidget)
dockWidget->close();
}
void AxDockWrapper::close()
{
hide();
Q_EMIT closed();
}
bool AxDockWrapper::isVisible() const
{
return dockWidget && dockWidget->isOpen();
}
void AxDockWrapper::setTitle(const QString& title)
{
dockTitle = title;
if (dockWidget)
dockWidget->setTitle(title);
}