Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,72 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
#
|
||||
|
||||
SET(opm_edit_gui_SRCS
|
||||
acl_dialog.cpp
|
||||
acl_dialog.h
|
||||
acl_dialog_model.cpp
|
||||
acl_dialog_model.h
|
||||
|
||||
operator_dialog.cpp
|
||||
operator_dialog.h
|
||||
operator_edit_dialog.cpp
|
||||
operator_edit_dialog.h
|
||||
operator_edit_visible_parties_model.cpp
|
||||
operator_edit_visible_parties_model.h
|
||||
|
||||
group_model.cpp
|
||||
group_model.h
|
||||
group_edit_dialog.cpp
|
||||
group_edit_dialog.h
|
||||
group_edit_member_of_model.cpp
|
||||
group_edit_member_of_model.h
|
||||
|
||||
preset_dialog.cpp
|
||||
preset_dialog.h
|
||||
|
||||
opm_edit_gui_plugin.cpp
|
||||
opm_edit_gui_plugin.h
|
||||
|
||||
CustomViews/opm_group.cpp
|
||||
CustomViews/opm_group.h
|
||||
CustomViews/opm_operator.cpp
|
||||
CustomViews/opm_operator.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(opm_edit_gui_SRCS
|
||||
acl_dialog.ui
|
||||
operator_dialog.ui
|
||||
operator_edit_dialog.ui
|
||||
preset_dialog.ui
|
||||
group_edit_dialog.ui
|
||||
CustomViews/opm_group.ui
|
||||
CustomViews/opm_operator.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS OpmEditGuiPlugin MODULE ${opm_edit_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(OpmEditGuiPlugin
|
||||
OpmChangePasswordGui
|
||||
NGLLogger
|
||||
nglwidgets
|
||||
ExmDataPluginInterface
|
||||
OpmDataPluginInterface
|
||||
PpmDataPluginInterface
|
||||
FlmDataPluginInterface
|
||||
OpmGuiPluginInterface
|
||||
Qt5::Widgets
|
||||
LtsWidgets
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsDataView
|
||||
LtsUtilsGuiDds
|
||||
LtsUtilsSettings
|
||||
LtsPrinting
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(OpmEditGuiPlugin)
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for OPM Group
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2016-04-08
|
||||
*/
|
||||
|
||||
#include "opm_group.h"
|
||||
#include "ui_opm_group.h"
|
||||
|
||||
#include "group_model.h"
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
CustomViewGroup::CustomViewGroup(QWidget *parent)
|
||||
: AbstractDisplayWidget(parent)
|
||||
, m_ui(new Ui::CustomViewGroup)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
CustomViewGroup::~CustomViewGroup()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool CustomViewGroup::init(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid())
|
||||
return false;
|
||||
|
||||
m_ui->lbName->setText(rowData(idx, OperatorManagement::GroupModel::Name).toString());
|
||||
m_ui->lbInfo->setText(rowData(idx, OperatorManagement::GroupModel::Info).toString());
|
||||
return true;
|
||||
}
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for OPM Group
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2016-04-08
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewer/LtsDataView/abstract_display_widget.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CustomViewGroup;
|
||||
}
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
class CustomViewGroup final : public LtsDataView::AbstractDisplayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomViewGroup(QWidget *parent = nullptr);
|
||||
~CustomViewGroup();
|
||||
bool init(const QModelIndex &idx) override;
|
||||
|
||||
private:
|
||||
Ui::CustomViewGroup* m_ui;
|
||||
|
||||
};
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CustomViewGroup</class>
|
||||
<widget class="QWidget" name="CustomViewGroup">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>300</width>
|
||||
<height>74</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbName">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbInfo">
|
||||
<property name="text">
|
||||
<string notr="true">Info</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for OPM Operator
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2016-04-08
|
||||
*/
|
||||
|
||||
#include "opm_operator.h"
|
||||
#include "ui_opm_operator.h"
|
||||
|
||||
#include "operator_dialog.h"
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
CustomViewOperator::CustomViewOperator(QWidget *parent)
|
||||
: AbstractDisplayWidget(parent)
|
||||
, m_ui(new Ui::CustomViewOperator)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->lbImage->setScaledContents(true);
|
||||
}
|
||||
|
||||
CustomViewOperator::~CustomViewOperator()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool CustomViewOperator::init(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid())
|
||||
return false;
|
||||
|
||||
m_ui->lbName->setText(rowData(idx, OperatorManagement::OperatorManagementDialogModel::Name).toString());
|
||||
m_ui->lbInfo->setText(rowData(idx, OperatorManagement::OperatorManagementDialogModel::Description).toString());
|
||||
QPixmap pm(rowData(idx, OperatorManagement::OperatorManagementDialogModel::Image).value<QPixmap>());
|
||||
m_ui->lbImage->setPixmap(pm.scaled(m_ui->lbImage->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
return true;
|
||||
}
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for OPM Operator
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2016-04-08
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewer/LtsDataView/abstract_display_widget.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CustomViewOperator;
|
||||
}
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
class CustomViewOperator final : public LtsDataView::AbstractDisplayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomViewOperator(QWidget *parent = nullptr);
|
||||
~CustomViewOperator();
|
||||
bool init(const QModelIndex &idx) override;
|
||||
|
||||
private:
|
||||
Ui::CustomViewOperator* m_ui;
|
||||
|
||||
};
|
||||
} // namespace OperatorManagement
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CustomViewOperator</class>
|
||||
<widget class="QWidget" name="CustomViewOperator">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>319</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<widget class="QLabel" name="lbImage">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Image</string>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbInfo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Info</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManagement - Operator/User Overview Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Patric Karwat, SLSE, 2016-04-20
|
||||
*/
|
||||
|
||||
#include "acl_dialog.h"
|
||||
#include "ui_acl_dialog.h"
|
||||
|
||||
|
||||
namespace OperatorManagement {
|
||||
|
||||
AclDialog::AclDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_model(nullptr)
|
||||
, m_ui(new Ui::AclDialog)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_logger(getLogger("AclDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
}
|
||||
|
||||
AclDialog::~AclDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void AclDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("ACL Edit"));
|
||||
}
|
||||
|
||||
bool AclDialog::init(const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Ftc> &ftc)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
|
||||
m_model = new AclDialogModel(this);
|
||||
m_model->initModel(dtc, ftc);
|
||||
m_ui->tvACL->setModel(m_model);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OpeartorManagement - ACL Overview Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Patric Karwat, SLSE, 2016-04-20
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "acl_dialog_model.h"
|
||||
|
||||
#include <OperatorManagement/opm_ftc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <OperatorManagement/logger.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
namespace Ui {
|
||||
class AclDialog;
|
||||
}
|
||||
namespace OperatorManagement
|
||||
{
|
||||
class AclDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AclDialog(QWidget *parent = nullptr);
|
||||
~AclDialog();
|
||||
bool init(const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Ftc> &ftc);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
|
||||
AclDialogModel *m_model;
|
||||
Ui::AclDialog *m_ui;
|
||||
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<OperatorManagement::Interface::Ftc> m_ftc;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AclDialog</class>
|
||||
<widget class="QWidget" name="AclDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>674</width>
|
||||
<height>285</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Show ACL</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeView" name="tvACL">
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManagement - ACL Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Patric Karwat, SLSE, 2016-04-20
|
||||
*/
|
||||
|
||||
|
||||
#include "acl_dialog_model.h"
|
||||
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
//---------------------------------
|
||||
// AclDialogModel
|
||||
//---------------------------------
|
||||
AclDialogModel::AclDialogModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<OperatorManagement::AccessControlLevel>({tr("Name"),
|
||||
tr("Info")},
|
||||
parent)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_logger(getLogger("AccessControlLevelDialogModel"))
|
||||
{}
|
||||
|
||||
AclDialogModel::~AclDialogModel()
|
||||
{}
|
||||
|
||||
bool AclDialogModel::initModel(const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Ftc> &ftc)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
|
||||
connect(m_dtc.get(), &OperatorManagement::Interface::Dtc::accessControlLevelChanged,
|
||||
this, &AclDialogModel::onDataChanged);
|
||||
m_dtc->accessControlLevels([this](const OperatorManagement::AccessControlLevel &acl) { insertRow(acl); });
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVariant AclDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole || !indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const OperatorManagement::AccessControlLevel &acl = m_vecData.at(index.row());
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
return QString::fromStdString(acl.name());
|
||||
case 1:
|
||||
return QString::fromStdString(acl.description());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManagement - ACL Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Patric Karwat, SLSE, 2016-04-20
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OperatorManagement/opm_ftc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <OperatorManagement/logger.h>
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
// --------------------------------------------------------
|
||||
// AclDialogModel
|
||||
// --------------------------------------------------------
|
||||
class AclDialogModel final : public LtsWidgets::LtsAbstractTableModel<OperatorManagement::AccessControlLevel>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AclDialogModel(QObject *parent = nullptr);
|
||||
~AclDialogModel();
|
||||
|
||||
bool initModel(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc);
|
||||
|
||||
QVariant data(const QModelIndex &, int) const override final;
|
||||
|
||||
private:
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<OperatorManagement::Interface::Ftc> m_ftc;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManagement - Operator Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "group_edit_dialog.h"
|
||||
#include "ui_group_edit_dialog.h"
|
||||
|
||||
#include "group_edit_member_of_model.h"
|
||||
|
||||
#include <QMenu>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <OperatorManagement/opm_translation.h>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
GroupEditDialog::GroupEditDialog(QWidget *parent)
|
||||
: LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_ui(new Ui::GroupEditDialog)
|
||||
, m_operatorId(0)
|
||||
, m_rolePresetId(0)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_model(nullptr)
|
||||
, m_logger(getLogger("GroupEditDialog"))
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
void GroupEditDialog::init(const Group &group,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Ftc> &ftc,
|
||||
const int operatorId)
|
||||
{
|
||||
m_group = group;
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
m_operatorId = operatorId;
|
||||
|
||||
m_ui->leName->setText(QString::fromStdString(group.name()));
|
||||
m_ui->leDescription->setText(QString::fromStdString(group.description()));
|
||||
|
||||
m_ui->cbRoles->addItem(tr("---"), 0);
|
||||
auto cbGroup = [this](const Group &group)
|
||||
{
|
||||
if (group.type() == GroupType_def::PresetGroup)
|
||||
m_ui->cbRoles->addItem(OperatorManagement::trGroupName(group.name()), group.id());
|
||||
};
|
||||
dtc->groups(cbGroup);
|
||||
|
||||
User user(m_dtc->user(m_operatorId));
|
||||
int rolePresetId = user.rolePresetId().is_set() ? user.rolePresetId().get() : m_rolePresetId;
|
||||
m_ui->cbRoles->setCurrentIndex(m_ui->cbRoles->findData(rolePresetId));
|
||||
|
||||
if (m_group.type() == GroupType_def::OperatorGroup)
|
||||
{
|
||||
m_ui->leName->setEnabled(false);
|
||||
m_ui->leDescription->setEnabled(false);
|
||||
}
|
||||
|
||||
if (m_group.type() == GroupType_def::PresetGroup && m_group.id() != 0)
|
||||
m_ui->leName->setEnabled(false);
|
||||
|
||||
connect(m_ui->pbLoadPreset, &QPushButton::clicked, this, &GroupEditDialog::onPbPresetClicked);
|
||||
|
||||
// create model, as its only needed for editable groups
|
||||
m_model = new MembershipModel(this, m_dtc);
|
||||
m_model->init(group.isMemberOf());
|
||||
connect(m_model, &MembershipModel::dataChanged, this, &GroupEditDialog::slotChangesMade);
|
||||
m_ui->dvMemberOf->setModel(m_model);
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
m_ui->dvMemberOf->setRootIsDecorated(true);
|
||||
m_ui->dvMemberOf->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_ui->dvMemberOf, &LtsDataView::LtsDataView::customContextMenuRequested, this, &GroupEditDialog::onContextMenuRequested);
|
||||
#endif
|
||||
|
||||
if (m_group.type() == GroupType_def::PresetGroup) // Preset
|
||||
setOnlineHelpFilename(QStringLiteral("Administrator-Presets"));
|
||||
else if (m_group.type() == GroupType_def::OperatorGroup) // Privileges
|
||||
setOnlineHelpFilename(QStringLiteral("Administrator-Operators"));
|
||||
}
|
||||
|
||||
void GroupEditDialog::setRolePresetId(int presetGroupId)
|
||||
{
|
||||
m_rolePresetId = presetGroupId;
|
||||
m_ui->cbRoles->setCurrentIndex(m_ui->cbRoles->findData(presetGroupId));
|
||||
}
|
||||
|
||||
void GroupEditDialog::onGroupChangeMembershipsReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
// Update m_group with new values
|
||||
// the reply arrives after the LTS_User is updated
|
||||
m_group = m_dtc->group(replyObject.id());
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void GroupEditDialog::onGroupCreateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_group = m_dtc->group(replyObject.id());
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
GroupEditDialog::~GroupEditDialog() { delete m_ui; }
|
||||
|
||||
void GroupEditDialog::retranslate()
|
||||
{
|
||||
if (m_group.type() == GroupType_def::PresetGroup)
|
||||
translate(m_ui, OperatorManagement::trGroupName(m_group.name()), m_group.id() < 1, tr("Preset"));
|
||||
else if (m_group.type() == GroupType_def::OperatorGroup)
|
||||
translate(m_ui, OperatorManagement::trGroupName(m_group.name()), m_group.id() < 1, tr("Privileges"));
|
||||
}
|
||||
|
||||
// SLOTS:
|
||||
bool GroupEditDialog::apply()
|
||||
{
|
||||
std::vector<int> memberOf = m_model->checkStateForGroups(Qt::Checked);
|
||||
|
||||
if (memberOf.empty())
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("An operator must have at least one right"));
|
||||
return false;
|
||||
}
|
||||
|
||||
std::sort(memberOf.begin(), memberOf.end());
|
||||
|
||||
std::vector<int> oldGroups = m_group.isMemberOf();
|
||||
std::sort(oldGroups.begin(), oldGroups.end());
|
||||
|
||||
const User &user(m_dtc->user(m_operatorId));
|
||||
const int rolePresetId = user.rolePresetId().is_set() ? user.rolePresetId().get() : 0;
|
||||
|
||||
if (oldGroups == memberOf && m_ui->cbRoles->currentData().toInt() == rolePresetId)
|
||||
return true;
|
||||
|
||||
if (m_group.id() == 0)
|
||||
{
|
||||
if (m_group.type() == GroupType_def::OperatorGroup)
|
||||
{
|
||||
emit newGroups(memberOf, m_ui->cbRoles->currentData().toInt());
|
||||
return true;
|
||||
}
|
||||
else // Preset Group
|
||||
{
|
||||
const std::string name = m_ui->leName->text().toStdString();
|
||||
const std::string description = m_ui->leDescription->text().toStdString();
|
||||
GroupCreateRequest req(name, description, GroupType_def::PresetGroup, false, memberOf);
|
||||
m_requestHelper->addRequest([this, req]() { return m_ftc->groupCreateRequest(req, this); });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_group.description() != m_ui->leDescription->text().toStdString())
|
||||
{
|
||||
m_requestHelper->addRequest(
|
||||
[this]()
|
||||
{
|
||||
const std::string name = m_ui->leName->text().toStdString();
|
||||
const std::string description = m_ui->leDescription->text().toStdString();
|
||||
GroupChangeNameRequest req(m_group.id(), name, description);
|
||||
return m_ftc->groupChangeNameRequest(req, this);
|
||||
});
|
||||
}
|
||||
const int rolePresetId = m_operatorId ? m_ui->cbRoles->currentData().toInt() : 0;
|
||||
GroupChangeMembersRequest req(m_group.id(), memberOf, LtsUtils::toOptional(rolePresetId), LtsUtils::toOptional(m_operatorId));
|
||||
|
||||
m_requestHelper->addRequest([this, req]() { return m_ftc->groupChangeMembershipsRequest(req, this); });
|
||||
}
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void GroupEditDialog::onPbPresetClicked()
|
||||
{
|
||||
int contextGroupId = m_ui->cbRoles->currentData().toInt();
|
||||
m_model->setCheckStateForGroups(m_dtc->group(contextGroupId).isMemberOf());
|
||||
}
|
||||
|
||||
void GroupEditDialog::onContextMenuRequested(const QPoint &position)
|
||||
{
|
||||
QMenu menu(m_ui->dvMemberOf);
|
||||
menu.addAction(tr("Select All"), this, &GroupEditDialog::onSelectAllRights);
|
||||
menu.addAction(tr("Unselect All"), this, &GroupEditDialog::onUnselectAllRights);
|
||||
menu.exec(m_ui->dvMemberOf->mapToGlobal(position));
|
||||
}
|
||||
|
||||
void GroupEditDialog::onSelectAllRights() { m_model->selectAll(); }
|
||||
|
||||
void GroupEditDialog::onUnselectAllRights() { m_model->unselectAll(); }
|
||||
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManagement - Operator Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <OperatorManagement/logger.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <OperatorManagement/opm_ftc.h>
|
||||
|
||||
#include <QVector>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class GroupEditDialog;
|
||||
}
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
|
||||
class MembershipModel;
|
||||
|
||||
class GroupEditDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
, protected Interface::Ftc::GroupChangeMembershipsReplyHandler
|
||||
, protected Interface::Ftc::GroupCreateReplyHandler
|
||||
, protected Interface::Ftc::GroupChangeNameReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GroupEditDialog(QWidget *parent = nullptr);
|
||||
~GroupEditDialog();
|
||||
|
||||
// If initialized with a group that has id==0, this class will emit the new Groups as a signal. Otherwise
|
||||
// it will call the groupChangeMembership-FTC itself
|
||||
void init(const Group &group, const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<Interface::Ftc> &ftc, const int operatorId = 0);
|
||||
void setRolePresetId(int presetGroupId);
|
||||
|
||||
void onGroupChangeMembershipsReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
void onGroupCreateReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onGroupChangeNameReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
bool apply() override;
|
||||
|
||||
private slots:
|
||||
void onPbPresetClicked();
|
||||
void onContextMenuRequested(const QPoint &position);
|
||||
void onSelectAllRights();
|
||||
void onUnselectAllRights();
|
||||
|
||||
signals:
|
||||
void newGroups(const std::vector<int> &groupIds, const int presetGroupId);
|
||||
|
||||
private:
|
||||
Ui::GroupEditDialog *m_ui;
|
||||
Group m_group;
|
||||
int m_operatorId;
|
||||
int m_rolePresetId;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
MembershipModel *m_model;
|
||||
LOGGER_T m_logger;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
};
|
||||
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GroupEditDialog</class>
|
||||
<widget class="QWidget" name="GroupEditDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>886</width>
|
||||
<height>685</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Group Edit</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="leName"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QPushButton" name="pbLoadPreset">
|
||||
<property name="text">
|
||||
<string>Load</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxInfo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Info:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="leDescription"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblMemberOf">
|
||||
<property name="text">
|
||||
<string>Member Of:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="6">
|
||||
<widget class="LtsDataView::LtsDataView" name="dvMemberOf">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="lbxPreset">
|
||||
<property name="text">
|
||||
<string>Preset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbRoles"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>leName</tabstop>
|
||||
<tabstop>leDescription</tabstop>
|
||||
<tabstop>pbLoadPreset</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+452
@@ -0,0 +1,452 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManagement - Group Edit member of model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Philipp Dassow, SLST, 2017-09-26
|
||||
*/
|
||||
|
||||
#include "group_edit_member_of_model.h"
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <LtsUtilsCore/dds_vector.h>
|
||||
#include <QCoreApplication>
|
||||
#include <QSet>
|
||||
#include <QVector>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
|
||||
QDataStream &operator<<(QDataStream &ds, const Group &gp)
|
||||
{
|
||||
ds << gp.id()
|
||||
<< QString::fromStdString(gp.name())
|
||||
<< QString::fromStdString(gp.description())
|
||||
<< LtsUtils::convert<QVector<int32_t>>(gp.aclAllow())
|
||||
<< LtsUtils::convert<QVector<int32_t>>(gp.aclDeny())
|
||||
<< gp.type().underlying()
|
||||
<< gp.isDeleted()
|
||||
<< gp.isHidden()
|
||||
<< LtsUtils::convert<QVector<int32_t>>(gp.isMemberOf());
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &ds, Group &gp)
|
||||
{
|
||||
int id;
|
||||
QString name, description;
|
||||
bool isDeleted, isHidden, isOperatorGroup;
|
||||
int type;
|
||||
QVector<int32_t> aclAllow, aclDeny, isMemberOf;
|
||||
ds >> id
|
||||
>> name
|
||||
>> description
|
||||
>> aclAllow
|
||||
>> aclDeny
|
||||
>> type
|
||||
>> isDeleted
|
||||
>> isHidden
|
||||
>> isMemberOf
|
||||
>> isOperatorGroup;
|
||||
|
||||
gp.id(id);
|
||||
gp.name(name.toStdString());
|
||||
gp.description(description.toStdString());
|
||||
LtsUtils::convert(aclAllow, gp.aclAllow());
|
||||
LtsUtils::convert(aclDeny, gp.aclDeny());
|
||||
gp.type(static_cast<GroupType::inner_enum>(type));
|
||||
gp.isDeleted(isDeleted);
|
||||
gp.isHidden(isHidden);
|
||||
LtsUtils::convert(isMemberOf, gp.isMemberOf());
|
||||
|
||||
return ds;
|
||||
}
|
||||
|
||||
class CheckedTreeItem final : public NGLTreeItem
|
||||
{
|
||||
public:
|
||||
using NGLTreeItem::NGLTreeItem;
|
||||
|
||||
bool bIsChecked = false;
|
||||
};
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
MembershipModel::MembershipModel(QObject *parent,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc)
|
||||
: NGLTreeModel(parent,
|
||||
new CheckedTreeItem(QVariant()),
|
||||
{tr("Name"), tr("Description"), tr("Is Hidden"), tr("Type")}
|
||||
)
|
||||
, m_dtc(dtc)
|
||||
, m_bRowsAreCheckable(true)
|
||||
{
|
||||
qRegisterMetaTypeStreamOperators<Group>();
|
||||
|
||||
QSet<int> disabledFunctionality;
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
|
||||
//--- aes ---
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableAirSupport")).toBool())
|
||||
disabledFunctionality += 0x20b0000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableBiologicalContamination")).toBool())
|
||||
disabledFunctionality += 0x2010000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableChemicalContamination")).toBool())
|
||||
disabledFunctionality += 0x2010100;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableBorderlines")).toBool())
|
||||
disabledFunctionality += 0x2090000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableChargeAdministration")).toBool())
|
||||
disabledFunctionality += 0x2060000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableDangerAreas")).toBool())
|
||||
disabledFunctionality += 0x2050000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableAreaExplosionArtillery")).toBool())
|
||||
disabledFunctionality += 0x2020000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableAreaExplosionMortar")).toBool())
|
||||
disabledFunctionality += 0x2020100;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableSingleExplosionArtillery")).toBool())
|
||||
disabledFunctionality += 0x2020200;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableSingleExplosionMortar")).toBool())
|
||||
disabledFunctionality += 0x2020300;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableExplosionCluster")).toBool())
|
||||
disabledFunctionality += 0x2020600;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableFunctionalAreas")).toBool())
|
||||
disabledFunctionality += 0x2070000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableMineAreas")).toBool())
|
||||
disabledFunctionality += 0x2040000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableMineAreasResetDusMines")).toBool())
|
||||
disabledFunctionality += 0x2040003;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableMineCorridors")).toBool())
|
||||
disabledFunctionality += 0x2080000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableNuclearContaminations")).toBool())
|
||||
disabledFunctionality += 0x2030000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableTechnicalAreas")).toBool())
|
||||
disabledFunctionality += 0x20a0000;
|
||||
if (!ps->value(QStringLiteral("aes"), QStringLiteral("enableGasPipes")).toBool())
|
||||
disabledFunctionality += 0x2100000;
|
||||
|
||||
|
||||
//--- avm ---
|
||||
if (!ps->value(QStringLiteral("avm"), QStringLiteral("enableAudioVideoManagement")).toBool())
|
||||
disabledFunctionality += 0x5010000;
|
||||
if (!ps->value(QStringLiteral("avm"), QStringLiteral("enableVideoImport")).toBool())
|
||||
disabledFunctionality += 0x5010100;
|
||||
if (!ps->value(QStringLiteral("avm"), QStringLiteral("enableAudioVideoPlaybacks")).toBool())
|
||||
disabledFunctionality += 0x5010003;
|
||||
if (!ps->value(QStringLiteral("avm"), QStringLiteral("enableCombatNetRadioEdit")).toBool())
|
||||
disabledFunctionality += 0x5020000;
|
||||
if (!ps->value(QStringLiteral("avm"), QStringLiteral("enableCombatNetRadioFrequencyPlanningEdit")).toBool())
|
||||
disabledFunctionality += 0x5020100;
|
||||
if (!ps->value(QStringLiteral("avm"), QStringLiteral("enableElectronicWarfareMeasures")).toBool())
|
||||
disabledFunctionality += 0x5030000;
|
||||
if (!ps->value(QStringLiteral("avm"), QStringLiteral("enableMobileVideoSystem")).toBool())
|
||||
disabledFunctionality += 0x5040000;
|
||||
|
||||
//--- cod ---
|
||||
if (!ps->value(QStringLiteral("cod"), QStringLiteral("enableCodificationTables")).toBool())
|
||||
disabledFunctionality += 0x8010000;
|
||||
if (!ps->value(QStringLiteral("cod"), QStringLiteral("enableShowCodificationTableBLUFOR")).toBool())
|
||||
disabledFunctionality += 0x8010100;
|
||||
if (!ps->value(QStringLiteral("cod"), QStringLiteral("enableShowCodificationTableOPFOR")).toBool())
|
||||
disabledFunctionality += 0x8010200;
|
||||
|
||||
//--- esm ---
|
||||
if (!ps->value(QStringLiteral("esm"), QStringLiteral("enableEffectShowManagement")).toBool())
|
||||
disabledFunctionality += 0x31010000;
|
||||
|
||||
//--- evl ---
|
||||
if (!ps->value(QStringLiteral("evl"), QStringLiteral("enableEvaluationsElements")).toBool())
|
||||
disabledFunctionality += 0xa010000;
|
||||
if (!ps->value(QStringLiteral("evl"), QStringLiteral("enableEvaluations")).toBool())
|
||||
disabledFunctionality += 0xa010100;
|
||||
|
||||
//--- exm ---
|
||||
if (!ps->value(QStringLiteral("exm"), QStringLiteral("enableEditPhases")).toBool())
|
||||
disabledFunctionality += 0xc010200;
|
||||
|
||||
//--- flt ---
|
||||
if (!ps->value(QStringLiteral("flt"), QStringLiteral("enableAES_FilterEdit")).toBool())
|
||||
disabledFunctionality += 0x31010000;
|
||||
|
||||
//--- gim ---
|
||||
if (!ps->value(QStringLiteral("gim"), QStringLiteral("enableIED_Pairing")).toBool())
|
||||
disabledFunctionality += 0x3010000;
|
||||
|
||||
//--- gna ---
|
||||
if (!ps->value(QStringLiteral("gna"), QStringLiteral("enableGuezNasat")).toBool())
|
||||
disabledFunctionality += 0x33010000;
|
||||
|
||||
//--- mdm ---
|
||||
if (!ps->value(QStringLiteral("mdm"), QStringLiteral("enableEditStaticMeteoData")).toBool())
|
||||
disabledFunctionality += 0x16020000;
|
||||
if (!ps->value(QStringLiteral("mdm"), QStringLiteral("enableShowMeteoDataStations")).toBool())
|
||||
disabledFunctionality += 0x16010000;
|
||||
|
||||
//--- msg ---
|
||||
if (!ps->value(QStringLiteral("msg"), QStringLiteral("enableMessages")).toBool())
|
||||
disabledFunctionality += 0x15010000;
|
||||
|
||||
//--- opm ---
|
||||
if (!ps->value(QStringLiteral("opm"), QStringLiteral("enableShutdownWorkstations")).toBool())
|
||||
disabledFunctionality += 0x19020002;
|
||||
|
||||
//--- ore ---
|
||||
if (!ps->value(QStringLiteral("ore"), QStringLiteral("enableOnlineReports")).toBool())
|
||||
disabledFunctionality += 0x2e010000;
|
||||
|
||||
//--- ppm ---
|
||||
if (!ps->value(QStringLiteral("ppm"), QStringLiteral("enableSupportParticipantsOrganise")).toBool())
|
||||
disabledFunctionality += 0x1b010002;
|
||||
if (!ps->value(QStringLiteral("ppm"), QStringLiteral("enableSupportParticipantsEdit")).toBool())
|
||||
disabledFunctionality += 0x1b010003;
|
||||
if (!ps->value(QStringLiteral("ppm"), QStringLiteral("enableMSDL_ImExport")).toBool())
|
||||
disabledFunctionality += 0x1b060000;
|
||||
|
||||
//--- rep ---
|
||||
if (!ps->value(QStringLiteral("rep"), QStringLiteral("enableReports")).toBool())
|
||||
disabledFunctionality += 0x1f010000;
|
||||
|
||||
//--- pws ---
|
||||
if (!ps->value(QStringLiteral("pws"), QStringLiteral("enableProjection")).toBool())
|
||||
disabledFunctionality += 0x32010000;
|
||||
|
||||
//--- smo ---
|
||||
if (!ps->value(QStringLiteral("smo"), QStringLiteral("enableEquipmentErrorRegistration")).toBool())
|
||||
disabledFunctionality += 0x2c010006;
|
||||
if (!ps->value(QStringLiteral("smo"), QStringLiteral("enableHandgrenadeAndMineSearchShow")).toBool())
|
||||
disabledFunctionality += 0x2c010006;
|
||||
|
||||
NGLTreeModel::resetModel();
|
||||
|
||||
// Insert All visible Groups
|
||||
auto cbGroup = [this, disabledFunctionality](const Group &group)
|
||||
{
|
||||
if (group.type() == GroupType_def::StandardGroup)
|
||||
{
|
||||
if (disabledFunctionality.contains(group.id()) || group.isHidden())
|
||||
return;
|
||||
CheckedTreeItem *item = static_cast<CheckedTreeItem *>(createItem(QVariant::fromValue(group), QIcon()));
|
||||
getRootItem()->appendChild(item);
|
||||
}
|
||||
};
|
||||
dtc->groups(cbGroup);
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
const auto children = getRootItem()->children();
|
||||
for (NGLTreeItem *opGroupItem : children)
|
||||
{
|
||||
const std::vector<int32_t> isMemberOf = opGroupItem->data().value<Group>().isMemberOf();
|
||||
auto cbGroup2 = [this, &isMemberOf, opGroupItem] (const Group &group)
|
||||
{
|
||||
if (group.type() == GroupType_def::AclGroup && contains(isMemberOf, group.id()))
|
||||
opGroupItem->appendChild(createItem(QVariant::fromValue(group), QIcon()));
|
||||
};
|
||||
dtc->groups(cbGroup2);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool MembershipModel::contains(const std::vector<int32_t>&isMemberOf, int grpId)
|
||||
{
|
||||
for (int id : isMemberOf)
|
||||
{
|
||||
if (id == grpId)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant MembershipModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole && role != Qt::CheckStateRole)
|
||||
return NGLTreeModel::data(index, role);
|
||||
|
||||
CheckedTreeItem *item = static_cast<CheckedTreeItem *>(privateData(index));
|
||||
|
||||
if (role == Qt::CheckStateRole)
|
||||
{
|
||||
Group group = getGroupData(index);
|
||||
if (!m_bRowsAreCheckable || index.column() != 0 || group.type() != GroupType_def::StandardGroup)
|
||||
return NGLTreeModel::data(index, role);
|
||||
|
||||
return item->bIsChecked ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
|
||||
if (item->data().canConvert<Group>())
|
||||
{
|
||||
Group grp = item->data().value<Group>();
|
||||
switch (index.column())
|
||||
{
|
||||
case ColName:
|
||||
return QCoreApplication::translate("OperatorRights", grp.name().c_str());
|
||||
case ColDescription:
|
||||
return QCoreApplication::translate("OperatorRights", grp.description().c_str());
|
||||
case ColIsAclGroup:
|
||||
return grp.type().underlying();
|
||||
case ColIsHidden:
|
||||
return grp.isHidden() ? tr("Yes") : tr("No");
|
||||
}
|
||||
}
|
||||
return NGLTreeModel::data(index, role);
|
||||
}
|
||||
|
||||
void MembershipModel::init(int groupId)
|
||||
{
|
||||
init(m_dtc->group(groupId).isMemberOf());
|
||||
}
|
||||
|
||||
void MembershipModel::init(const std::vector<int> &groupIds)
|
||||
{
|
||||
setCheckStateForGroups(groupIds);
|
||||
}
|
||||
|
||||
bool MembershipModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (role != Qt::CheckStateRole || index.column() != 0 || !index.isValid())
|
||||
return NGLTreeModel::setData(index, value, role);
|
||||
if (!value.canConvert<bool>())
|
||||
return false;
|
||||
CheckedTreeItem *item = static_cast<CheckedTreeItem *>(privateData(index));
|
||||
if (item->bIsChecked != value.toBool())
|
||||
{
|
||||
item->bIsChecked = value.toBool();
|
||||
emit dataChanged(index, index, {role});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::ItemFlags MembershipModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Group group = getGroupData(index);
|
||||
auto ret = NGLTreeModel::flags(index);
|
||||
if (m_bRowsAreCheckable && index.column() == 0 && group.type() == GroupType_def::StandardGroup)
|
||||
ret |= Qt::ItemIsUserCheckable;
|
||||
|
||||
// // can not drag the whole tree, also we allow only dragging the first column
|
||||
// if (index.column() != 0 || !index.parent().isValid())
|
||||
// ret &= ~Qt::ItemIsDragEnabled;
|
||||
// // drop also only on first column
|
||||
// if (index.column() != 0)
|
||||
// ret &= ~Qt::ItemIsDropEnabled;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int MembershipModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
int count = NGLTreeModel::columnCount(parent);
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
count -= 2;
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
Group MembershipModel::getGroupData(const QModelIndex &idx) const
|
||||
{
|
||||
return privateData(idx)->data().value<Group>();
|
||||
}
|
||||
|
||||
void MembershipModel::setRowsCheckable(bool bCheckable)
|
||||
{
|
||||
if (m_bRowsAreCheckable == bCheckable)
|
||||
return;
|
||||
m_bRowsAreCheckable = bCheckable;
|
||||
// onReinitModel(m_partyId); // TODO: not really needed, only invalidate first column
|
||||
}
|
||||
|
||||
|
||||
std::vector<int> MembershipModel::checkStateForGroups(Qt::CheckState cs)
|
||||
{
|
||||
if (m_rootItem->childCount() < 1)
|
||||
return {};
|
||||
|
||||
CheckedTreeItem *item = static_cast<CheckedTreeItem *>(m_rootItem);
|
||||
return checkState(item, cs);
|
||||
}
|
||||
|
||||
bool MembershipModel::setCheckStateForGroups(const std::vector<int> &groupIds)
|
||||
{
|
||||
if (m_rootItem->childCount() < 1)
|
||||
return false;
|
||||
setChecked(static_cast<CheckedTreeItem *>(m_rootItem),groupIds);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<int> MembershipModel::checkState(CheckedTreeItem *parentItem, Qt::CheckState cs) const
|
||||
{
|
||||
std::vector<int> ret;
|
||||
if ((parentItem->bIsChecked && cs == Qt::Checked) ||
|
||||
(!parentItem->bIsChecked && cs == Qt::Unchecked))
|
||||
ret.push_back(groupIdFromItem(parentItem));
|
||||
|
||||
for (int i = 0; i < parentItem->childCount(); ++i)
|
||||
{
|
||||
const auto c = checkState(static_cast<CheckedTreeItem *>(parentItem->child(i)), cs);
|
||||
ret.insert(ret.end(), c.begin(), c.end());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MembershipModel::setChecked(CheckedTreeItem *parentItem, const std::vector<int> &checkedGroups)
|
||||
{
|
||||
for (int i = 0; i < parentItem->childCount(); ++i)
|
||||
{
|
||||
CheckedTreeItem *item = static_cast<CheckedTreeItem *>(parentItem->child(i));
|
||||
const auto newState = LtsUtils::isInVector(checkedGroups, groupIdFromItem(item));
|
||||
if (item->bIsChecked != newState)
|
||||
{
|
||||
item->bIsChecked = newState;
|
||||
const QModelIndex idx = indexFromItem(item);
|
||||
emit dataChanged(idx, idx, {Qt::CheckStateRole});
|
||||
}
|
||||
setChecked(item, checkedGroups);
|
||||
}
|
||||
}
|
||||
|
||||
int MembershipModel::groupIdFromItem(NGLTreeItem *item) const
|
||||
{
|
||||
return item->data().value<Group>().id();
|
||||
}
|
||||
|
||||
NGLTreeItem *MembershipModel::createItem(const QVariant &data, const QIcon &icon) const
|
||||
{
|
||||
return new CheckedTreeItem(data, icon);
|
||||
}
|
||||
|
||||
void MembershipModel::selectAll()
|
||||
{
|
||||
if (m_rootItem->childCount() < 1)
|
||||
return;
|
||||
select(static_cast<CheckedTreeItem *>(m_rootItem), true);
|
||||
return;
|
||||
}
|
||||
|
||||
void MembershipModel::select(CheckedTreeItem *parentItem, bool selectValue)
|
||||
{
|
||||
for (int i = 0; i < parentItem->childCount(); ++i)
|
||||
{
|
||||
CheckedTreeItem *item = static_cast<CheckedTreeItem *>(parentItem->child(i));
|
||||
if (item->bIsChecked != selectValue)
|
||||
{
|
||||
item->bIsChecked = selectValue;
|
||||
const QModelIndex idx = indexFromItem(item);
|
||||
emit dataChanged(idx, idx, {Qt::CheckStateRole});
|
||||
}
|
||||
select(item, selectValue);
|
||||
}
|
||||
}
|
||||
|
||||
void MembershipModel::unselectAll()
|
||||
{
|
||||
if (m_rootItem->childCount() < 1)
|
||||
return;
|
||||
select(static_cast<CheckedTreeItem *>(m_rootItem), false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManagement - Group Edit member of model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Philipp Dassow, SLST, 2017-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/OperatorManagement/Data/opm_data_plugin.h>
|
||||
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
class CheckedTreeItem;
|
||||
|
||||
class MembershipModel : public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum Columns
|
||||
{
|
||||
ColName,
|
||||
ColDescription,
|
||||
ColIsHidden,
|
||||
ColIsAclGroup
|
||||
};
|
||||
|
||||
public:
|
||||
explicit MembershipModel(QObject *parent,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc
|
||||
);
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
|
||||
Group getGroupData(const QModelIndex &idx) const;
|
||||
|
||||
void setRowsCheckable(bool bCheckable);
|
||||
bool rowsCheckable() const { return m_bRowsAreCheckable; }
|
||||
|
||||
std::vector<int> checkStateForGroups(Qt::CheckState cs);
|
||||
bool setCheckStateForGroups(const std::vector<int> &groupIds);
|
||||
void selectAll();
|
||||
void unselectAll();
|
||||
|
||||
void init(int groupId);
|
||||
void init(const std::vector<int> &groupIds);
|
||||
private:
|
||||
std::vector<int> checkState(CheckedTreeItem *parentItem, Qt::CheckState cs) const;
|
||||
void setChecked(CheckedTreeItem *parentItem, const std::vector<int> &checkedGroups);
|
||||
void select(CheckedTreeItem *parentItem, bool selectValue);
|
||||
int groupIdFromItem(NGLTreeItem *item) const;
|
||||
|
||||
NGLTreeItem *createItem(const QVariant &data, const QIcon &icon) const override;
|
||||
|
||||
private:
|
||||
const std::shared_ptr<Interface::Dtc> &m_dtc;
|
||||
bool m_bRowsAreCheckable;
|
||||
static bool contains(const std::vector<int32_t>&isMemberOf, int grpId);
|
||||
};
|
||||
}
|
||||
Q_DECLARE_METATYPE(OperatorManagement::Group)
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManagement - Group Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "group_model.h"
|
||||
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <OperatorManagement/opm_translation.h>
|
||||
#include <QIcon>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
//---------------------------------
|
||||
// GroupModel
|
||||
//---------------------------------
|
||||
GroupModel::GroupModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<OperatorManagement::Group>({tr("Name"),
|
||||
tr("Info"),
|
||||
tr("Id")},
|
||||
parent)
|
||||
, m_dtc(nullptr)
|
||||
, m_hideHidden(false)
|
||||
, m_logger(getLogger("GroupManagementDialogModel"))
|
||||
{}
|
||||
|
||||
GroupModel::~GroupModel()
|
||||
{}
|
||||
|
||||
bool GroupModel::initModel(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
bool hideHidden)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
m_hideHidden = hideHidden;
|
||||
|
||||
connect(m_dtc.get(), &OperatorManagement::Interface::Dtc::groupChanged,
|
||||
this, &GroupModel::onDataChanged);
|
||||
m_dtc->groups([this](const OperatorManagement::Group &group) {
|
||||
if (group.type() == GroupType_def::PresetGroup)
|
||||
insertRow(group);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVariant GroupModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole && role != Qt::DecorationRole)
|
||||
return QVariant();
|
||||
|
||||
if (!indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const OperatorManagement::Group &group = m_vecData.at(index.row());
|
||||
|
||||
if (role == Qt::DecorationRole && index.column() == 0)
|
||||
{
|
||||
if (group.type() == GroupType::OperatorGroup)
|
||||
return QIcon(QLatin1String("icon:list-add-user.svg"));
|
||||
if (group.type() == GroupType::AclGroup)
|
||||
return QIcon(QLatin1String("icon:define_teams.svg"));
|
||||
return QIcon(QLatin1String("icon:display_oc_evaluations.svg"));
|
||||
}
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case Name:
|
||||
return OperatorManagement::trGroupName(group.name());
|
||||
case Info:
|
||||
return OperatorManagement::trGroupDescription(group.description());
|
||||
case Id:
|
||||
return group.id();
|
||||
//return QVariant(DTG::toStringMSec(group.lastChanged()));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManagement - Group Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <OperatorManagement/logger.h>
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
// --------------------------------------------------------
|
||||
// GroupModel
|
||||
// --------------------------------------------------------
|
||||
class GroupModel final : public LtsWidgets::LtsAbstractTableModel<OperatorManagement::Group>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
Name,
|
||||
Info,
|
||||
Id
|
||||
};
|
||||
|
||||
explicit GroupModel(QObject *parent = nullptr);
|
||||
~GroupModel();
|
||||
|
||||
bool initModel(const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc,
|
||||
bool hideHidden = true);
|
||||
|
||||
QVariant data(const QModelIndex &, int) const override final;
|
||||
protected:
|
||||
bool isFiltered(const Group &data, DataModification modType) const override
|
||||
{
|
||||
if (m_hideHidden && data.isHidden())
|
||||
return true;
|
||||
return LtsWidgets::LtsAbstractTableModel<OperatorManagement::Group>::isFiltered(data, modType);
|
||||
}
|
||||
private:
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtc;
|
||||
bool m_hideHidden;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManagement - Operator/User Overview Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "operator_dialog.h"
|
||||
#include "ui_operator_dialog.h"
|
||||
|
||||
#include "operator_edit_dialog.h"
|
||||
#include "CustomViews/opm_operator.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
|
||||
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <QTreeView>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
OperatorDialog::OperatorDialog(const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_model(nullptr)
|
||||
, m_ui(new Ui::OperatorDialog)
|
||||
, m_ftc(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_logger(getLogger("OperatorDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &OperatorDialog::onAddOperator);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &OperatorDialog::onEditOperator);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &OperatorDialog::onRemoveOperator);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &OperatorDialog::onPrint);
|
||||
|
||||
connect(m_ui->widget, &LtsDataView::LtsDataView::signalDoubleClicked, this, &OperatorDialog::onEditOperator);
|
||||
connect(m_ui->widget, &LtsDataView::LtsDataView::signalEnterPressed, this, &OperatorDialog::onEditOperator);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Administrator-Operators"));
|
||||
}
|
||||
|
||||
OperatorDialog::~OperatorDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void OperatorDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Operators"));
|
||||
}
|
||||
|
||||
void OperatorDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->widget->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
bool OperatorDialog::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
m_session = session;
|
||||
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> dtc;
|
||||
if (!m_session->getDtc<OperatorManagement::DataInterface>(dtc))
|
||||
return false;
|
||||
if (!m_session->getFtc<OperatorManagement::DataInterface>(m_ftc))
|
||||
return false;
|
||||
|
||||
m_model = new OperatorManagementDialogModel(this);
|
||||
m_model->initModel(m_session, dtc);
|
||||
m_ui->widget->setModel(m_model, [this]() { return new CustomViewOperator(this); });
|
||||
|
||||
connect(m_ui->widget, &LtsDataView::LtsDataView::signalSelectionChanged,
|
||||
this, &OperatorDialog::enaDisa);
|
||||
connect(m_ui->widget, &LtsDataView::LtsDataView::clicked,
|
||||
this, &OperatorDialog::onTvItemClicked);
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->widget->hideColumn(OperatorManagementDialogModel::Columns::Id);
|
||||
m_ui->widget->hideColumn(OperatorManagementDialogModel::Columns::EffectiveAcls);
|
||||
m_ui->widget->hideColumn(OperatorManagementDialogModel::Columns::PrimaryGroupId);
|
||||
m_ui->widget->hideColumn(OperatorManagementDialogModel::Columns::Image);
|
||||
m_ui->widget->hideColumn(OperatorManagementDialogModel::Columns::Workstation);
|
||||
#endif
|
||||
|
||||
m_ui->widget->setSortIndicator(OperatorManagementDialogModel::Columns::Name, Qt::AscendingOrder);
|
||||
|
||||
enaDisa();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OperatorDialog::enaDisa()
|
||||
{
|
||||
QModelIndexList selectedRows = m_ui->widget->selectedRows();
|
||||
const int cntSelectedRows = selectedRows.size();
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, cntSelectedRows == 1);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, cntSelectedRows == 1);
|
||||
}
|
||||
|
||||
void OperatorDialog::onRemoveOperator()
|
||||
{
|
||||
QModelIndex idx = m_ui->widget->currentIndex();
|
||||
Core::RemoveElementRequest req(m_model->getRowData(idx.row()).id());
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->operatorRemoveRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
void OperatorDialog::onAddOperator()
|
||||
{
|
||||
OperatorEditDialog *dialog = new OperatorEditDialog(-1, m_session, m_menuGroup, this);
|
||||
|
||||
addDialog(dialog, m_menuGroup, QLatin1String("NewOperator"), LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
|
||||
void OperatorDialog::onEditOperator()
|
||||
{
|
||||
const QModelIndex idx = m_ui->widget->currentIndex();
|
||||
const OperatorManagement::User op = m_model->getRowData(idx.row());
|
||||
|
||||
if (op.id() <= 0)
|
||||
return;
|
||||
DEBUG_LOG(m_logger) << "current Operator Id: " << op.id();
|
||||
|
||||
OperatorEditDialog *dialog = new OperatorEditDialog(op.id(), m_session, m_menuGroup, this);
|
||||
const QString identifier = QLatin1String("EditOperator") + QString::number(op.id());
|
||||
|
||||
addDialog(dialog, m_menuGroup, identifier, LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
|
||||
void OperatorDialog::onPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_ui->widget->treeView());
|
||||
}
|
||||
|
||||
void OperatorDialog::onTvItemClicked(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid())
|
||||
return;
|
||||
|
||||
auto user = m_model->getRowData(idx.row());
|
||||
if (user.id() == 99) // Id 99 -> Organisator
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(false);
|
||||
else
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Remove)->setEnabled(true);
|
||||
}
|
||||
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OpeartorManagement - Operator/User Overview Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OperatorManagement/Gui/Common/operator_dialog_model.h>
|
||||
|
||||
#include <OperatorManagement/opm_ftc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <OperatorManagement/logger.h>
|
||||
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class OperatorDialog;
|
||||
}
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
|
||||
class OperatorDialog : public LtsWidgets::LtsDialog
|
||||
, protected OperatorManagement::Interface::Ftc::OperatorRemoveReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OperatorDialog(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~OperatorDialog();
|
||||
bool init(LtsSession::LtsSession *session);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void onOperatorRemoveReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
QString m_menuGroup;
|
||||
OperatorManagementDialogModel *m_model;
|
||||
Ui::OperatorDialog *m_ui;
|
||||
|
||||
LtsSession::LtsSession *m_session;
|
||||
std::shared_ptr<OperatorManagement::Interface::Ftc> m_ftc;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
private slots:
|
||||
void enaDisa();
|
||||
void onRemoveOperator();
|
||||
void onAddOperator();
|
||||
void onEditOperator();
|
||||
void onPrint();
|
||||
void onTvItemClicked(const QModelIndex &idx);
|
||||
};
|
||||
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OperatorDialog</class>
|
||||
<widget class="QWidget" name="OperatorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>674</width>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Operator Edit</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="widget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,514 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManagement - Operator Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "operator_edit_dialog.h"
|
||||
#include "ui_operator_edit_dialog.h"
|
||||
|
||||
#include <OperatorManagement/Gui/Common/operator_change_password.h>
|
||||
#include "operator_edit_visible_parties_model.h"
|
||||
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <LtsUtilsCore/dds_vector_to_pixmap.h>
|
||||
#include <LtsUtilsCore/dds_vector.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
#include <Plugins/ParticipantManagement/Data/ppm_data_plugin.h>
|
||||
#include <Plugins/ExerciseManagement/Data/exm_data_plugin.h>
|
||||
|
||||
#include <QListWidget>
|
||||
#include <QImage>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
#include <QFileDialog>
|
||||
#include <QMenu>
|
||||
|
||||
#include "group_edit_dialog.h"
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
OperatorEditDialog::OperatorEditDialog(const int operatorId,
|
||||
LtsSession::LtsSession *session,
|
||||
const QString &menuGroup,
|
||||
QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_operatorId(operatorId)
|
||||
, m_pictureChanged(false)
|
||||
, m_visiblePartiesChanged(false)
|
||||
, m_projectionPriorityChanged(false)
|
||||
, m_audioChannelPriorityChanged(false)
|
||||
, m_presetGroupId(0)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_visiblePartiesModel(nullptr)
|
||||
, m_session(session)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_ui(new Ui::OperatorEditDialog)
|
||||
, m_logger(getLogger("operatorManangementEditDialog"))
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_effectiveACls.clear();
|
||||
|
||||
// Todo: Init
|
||||
m_session->getDtc<OperatorManagement::DataInterface>(m_dtc);
|
||||
m_session->getFtc<OperatorManagement::DataInterface>(m_ftc);
|
||||
m_session->getDtc<FileManagement::DataInterface>(m_flmDtc);
|
||||
m_session->getFtc<FileManagement::DataInterface>(m_flmFtc);
|
||||
|
||||
OperatorManagement::User op = m_dtc->user(m_operatorId);
|
||||
|
||||
m_effectiveACls = op.effectiveAcls();
|
||||
|
||||
if (m_operatorId < 1)
|
||||
{
|
||||
m_ui->pbChangePassword->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//m_ui->leOperator->setEnabled(false);
|
||||
m_ui->lePassword->setVisible(false);
|
||||
m_ui->lePasswordConfirmation->setVisible(false);
|
||||
m_ui->lblPassword->setVisible(false);
|
||||
m_ui->lblPasswordConfirmation->setVisible(false);
|
||||
m_ui->pbDisplay->setVisible(false);
|
||||
}
|
||||
|
||||
m_ui->leOperator->setText(QString::fromStdString(op.name()));
|
||||
m_ui->leInfo->setText(QString::fromStdString(op.description()));
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc;
|
||||
if (m_session->getDtc<ParticipantManagement::DataInterface>(ppmDtc))
|
||||
{
|
||||
|
||||
m_visiblePartiesModel = new OperatorEditVisiblePartiesModel(m_dtc, ppmDtc, m_operatorId, this);
|
||||
m_ui->tvVisibleParties->setModel(m_visiblePartiesModel);
|
||||
m_ui->tvVisibleParties->resizeColumnsToContent();
|
||||
m_ui->tvVisibleParties->setSortIndicator(OperatorEditVisiblePartiesModel::Columns::ColId, Qt::SortOrder::AscendingOrder);
|
||||
m_ui->tvVisibleParties->setSortingEnabled(false);
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->tvVisibleParties->hideColumn(OperatorEditVisiblePartiesModel::Columns::ColId);
|
||||
#endif
|
||||
|
||||
connect(m_ui->tvVisibleParties, &LtsDataView::LtsDataView::doubleClicked, m_visiblePartiesModel, &OperatorEditVisiblePartiesModel::switchCheckbox);
|
||||
connect(m_visiblePartiesModel, &OperatorEditVisiblePartiesModel::dataChanged, this, [=]() {
|
||||
m_visiblePartiesChanged = true; slotChangesMade();});
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
m_ui->tvVisibleParties->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(m_ui->tvVisibleParties, &LtsDataView::LtsDataView::customContextMenuRequested, this, &OperatorEditDialog::onContextMenuRequested);
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->layParties->setEnabled(false);
|
||||
}
|
||||
getProfilePicture();
|
||||
|
||||
connect(m_ui->profileButton, &LtsWidgets::LtsProfileButton::signalClicked,
|
||||
this, &OperatorEditDialog::slotProfileButtonClicked);
|
||||
|
||||
connect(m_ui->pbACL, &QPushButton::clicked,
|
||||
this, &OperatorEditDialog::showACLs);
|
||||
|
||||
connect(m_ui->pbDisplay, &QPushButton::toggled,
|
||||
this, &OperatorEditDialog::onViewPasswordToggled);
|
||||
|
||||
connect(m_ui->pbFolders, &QPushButton::clicked,
|
||||
this, &OperatorEditDialog::createFolders);
|
||||
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> exmDtc;
|
||||
if (m_session->getDtc<ExerciseManagement::DataInterface>(exmDtc))
|
||||
connect(m_ui->pbExercises, &QPushButton::clicked, this, &OperatorEditDialog::showExercises);
|
||||
else
|
||||
m_ui->pbExercises->hide();
|
||||
|
||||
// new password needs to be minimum 4 chars
|
||||
m_uiRequirements->addRequirement({m_ui->lblPassword, [this]()
|
||||
{
|
||||
return (m_operatorId > 0 || m_ui->lblPassword->text().size() >= 4); }
|
||||
});
|
||||
// new password and confirm password need to be equal
|
||||
m_uiRequirements->addRequirement({m_ui->lblPasswordConfirmation, [this]()
|
||||
{
|
||||
return (m_operatorId > 0 || (m_ui->lePassword->text() == m_ui->lePasswordConfirmation->text())); }
|
||||
});
|
||||
|
||||
connect(m_ui->pbChangePassword, &QPushButton::clicked, this, &OperatorEditDialog::slotPasswordChangedClicked);
|
||||
|
||||
m_uiRequirements->addRequirement({m_ui->lblOperator, [this]() { return (!m_ui->leOperator->text().isEmpty()); }});
|
||||
|
||||
QString priorities = QStringLiteral("1 (%1),2,3,4,5 (%2)").arg(tr("Least"), tr("Highest"));
|
||||
|
||||
m_ui->cbProjectionPriority->addItems(priorities.split(QLatin1Char(',')));
|
||||
m_ui->cbAudioChannelPriority->addItems(priorities.split(QLatin1Char(',')));
|
||||
|
||||
m_ui->cbProjectionPriority->setCurrentIndex(clamp(op.projectionPriority() - 1, 0, 4));
|
||||
m_ui->cbAudioChannelPriority->setCurrentIndex(clamp(op.audioChannelPriority() - 1, 0, 4));
|
||||
|
||||
connect<void(QComboBox::*)(int)>(m_ui->cbProjectionPriority, &QComboBox::currentIndexChanged,
|
||||
this, [this] () { m_projectionPriorityChanged = true; });
|
||||
connect<void(QComboBox::*)(int)>(m_ui->cbAudioChannelPriority, &QComboBox::currentIndexChanged,
|
||||
this, [this] () { m_audioChannelPriorityChanged = true; });
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Administrator-Operators"));
|
||||
}
|
||||
|
||||
int OperatorEditDialog::clamp(int v, int lower, int upper)
|
||||
{
|
||||
return std::min(upper, std::max(v, lower));
|
||||
}
|
||||
|
||||
bool OperatorEditDialog::operatorCreateModify(const OperatorCreateModifyRequest &req)
|
||||
{
|
||||
// If it's an existing Operator, "req.operatorRights().is_set()" is false.
|
||||
// We assume, groups are set.
|
||||
// If it's a new Operator, we need one privilege
|
||||
if (req.operatorRights().is_set() && req.operatorRights().get().size() == 0)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("An operator must have at least one right"));
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "req.name: " << req.name();
|
||||
return m_requestHelper->startSingleRequest([this, req]()
|
||||
{
|
||||
return m_ftc->operatorCreateModifyRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
void OperatorEditDialog::onViewPasswordToggled(bool checked)
|
||||
{
|
||||
m_ui->lePassword->setEchoMode(checked ? QLineEdit::EchoMode::Normal : QLineEdit::EchoMode::Password);
|
||||
m_ui->lePasswordConfirmation->setEchoMode(checked ? QLineEdit::EchoMode::Normal : QLineEdit::EchoMode::Password);
|
||||
}
|
||||
|
||||
void OperatorEditDialog::onNewGroups(const std::vector<int> &groupIds, const int presetGroupId)
|
||||
{
|
||||
m_groups = groupIds;
|
||||
m_presetGroupId = presetGroupId;
|
||||
}
|
||||
|
||||
|
||||
void OperatorEditDialog::getProfilePicture()
|
||||
{
|
||||
OperatorManagement::User op = m_dtc->user(m_operatorId);
|
||||
m_ui->profileButton->setPixmap(LtsUtils::getPixmap(op.image()));
|
||||
}
|
||||
|
||||
void OperatorEditDialog::slotProfileButtonClicked()
|
||||
{
|
||||
if (!m_ui->profileButton->pixmap().isNull())
|
||||
{
|
||||
if (LtsWidgets::LtsMessageDialog::showMessage(this, tr("Yes - overwrite image.<br>"
|
||||
"No - do not overwrite image.<br>"),
|
||||
tr("Do you really want to overwrite the current image?"),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes | LtsWidgets::Button::No) != LtsWidgets::Button::Yes)
|
||||
return; // do nothing if not ack by user
|
||||
}
|
||||
|
||||
const QStringList filter ({
|
||||
tr("Images (*.jpg *.jpeg *.png)")
|
||||
});
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select new image to replace profile picture"),
|
||||
QString(), // last wd
|
||||
filter.join(QStringLiteral(";;")));
|
||||
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
|
||||
QPixmap pixmap;
|
||||
if (!pixmap.load(fileName))
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Cannot load image '%1'").arg(fileName));
|
||||
return;
|
||||
}
|
||||
if (pixmap.width() > 100 || pixmap.height() > 100)
|
||||
pixmap = pixmap.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
m_ui->profileButton->setPixmap(pixmap);
|
||||
|
||||
m_pictureChanged = true;
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
void OperatorEditDialog::slotPasswordChangedClicked()
|
||||
{
|
||||
OperatorChangePassword *dialog = new OperatorChangePassword(this, m_operatorId);
|
||||
if (!dialog->init(m_session))
|
||||
return;
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
OperatorEditDialog::~OperatorEditDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void OperatorEditDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, m_dtc->user(m_operatorId), tr("Operator"));
|
||||
}
|
||||
|
||||
//Private Slots
|
||||
|
||||
void OperatorEditDialog::showACLs()
|
||||
{
|
||||
// Todo: MenuGroup!
|
||||
GroupEditDialog *dlg = new GroupEditDialog(this);
|
||||
if (m_operatorId < 1)
|
||||
{
|
||||
Group grp;
|
||||
grp.id(0);
|
||||
grp.name(m_ui->leOperator->text().toStdString());
|
||||
grp.description(m_ui->leInfo->text().toStdString());
|
||||
grp.type(GroupType_def::OperatorGroup);
|
||||
grp.isMemberOf(m_groups);
|
||||
connect(dlg, &GroupEditDialog::newGroups, this, &OperatorEditDialog::onNewGroups);
|
||||
dlg->init(grp, m_dtc, m_ftc);
|
||||
dlg->setRolePresetId(m_presetGroupId);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto grpInit = m_dtc->group(m_dtc->user(m_operatorId).primaryGroupId());
|
||||
dlg->init(grpInit, m_dtc, m_ftc, m_operatorId);
|
||||
}
|
||||
|
||||
|
||||
addDialog ( dlg, m_menuGroup, QLatin1String("EditGroups") + QString::number(m_operatorId));
|
||||
}
|
||||
|
||||
void OperatorEditDialog::showExercises()
|
||||
{
|
||||
LtsWidgets::LtsFramelessDialog *exercisesPopup = new LtsWidgets::LtsFramelessDialog(this, LtsWidgets::Behaviour::Popup);
|
||||
|
||||
QListWidget *wid = new QListWidget(exercisesPopup);
|
||||
wid->setFrameShape(QFrame::NoFrame);
|
||||
wid->viewport()->setAutoFillBackground(false);
|
||||
|
||||
QLabel *lblTitle = new QLabel(tr("Exercises"),exercisesPopup);
|
||||
|
||||
std::vector<int> exercises = m_dtc->user(m_operatorId).exerciseIds();
|
||||
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> exmDtc;
|
||||
m_session->getDtc<ExerciseManagement::DataInterface>(exmDtc);
|
||||
|
||||
for (int exercise : exercises)
|
||||
{
|
||||
QListWidgetItem *item = new QListWidgetItem(wid);
|
||||
item->setData(Qt::DisplayRole, exmDtc ? QString::fromStdString(exmDtc->exercise(exercise).name()) : tr("Exercise Id: <%1> (name unknown)").arg(exercise));
|
||||
item->setData(Qt::UserRole, exercise);
|
||||
wid->addItem(item);
|
||||
}
|
||||
|
||||
QFrame *line = new QFrame(this);
|
||||
line->setFrameShape(QFrame::HLine);
|
||||
line->setFrameShadow(QFrame::Sunken);
|
||||
|
||||
LtsWidgets::LtsDialogButtonBox *btnBox = new LtsWidgets::LtsDialogButtonBox(exercisesPopup);
|
||||
connect(btnBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, exercisesPopup, &LtsWidgets::LtsFramelessDialog::accept); // TODO: undo workaround !
|
||||
btnBox->getButton(LtsWidgets::DialogButton::Ok)->hide();
|
||||
|
||||
//buildUI
|
||||
QVBoxLayout *lay = new QVBoxLayout(exercisesPopup);
|
||||
lay->addWidget(lblTitle);
|
||||
lay->addWidget(line);
|
||||
lay->addWidget(wid);
|
||||
lay->addWidget(btnBox);
|
||||
exercisesPopup->setLayout(lay);
|
||||
|
||||
//exec
|
||||
exercisesPopup->show();
|
||||
//delete aclPopup; <= not needed, see parenting
|
||||
}
|
||||
|
||||
|
||||
bool OperatorEditDialog::apply()
|
||||
{
|
||||
const std::string name = m_ui->leOperator->text().toStdString();
|
||||
const std::string description = m_ui->leInfo->text().toStdString();
|
||||
const std::string password = m_ui->lePassword->text().toStdString();
|
||||
|
||||
//bool isAdmin = false; // TODO: check if session operator is in admin role - admins can change passwords without entering the old one
|
||||
|
||||
if (m_operatorId > 0) // user exists
|
||||
{
|
||||
OperatorManagement::User op = m_dtc->user(m_operatorId);
|
||||
|
||||
//updateData
|
||||
bool bNeedUpdate = false;
|
||||
OperatorCreateModifyRequest req;
|
||||
req.id(m_operatorId);
|
||||
|
||||
if (m_pictureChanged)
|
||||
{
|
||||
bNeedUpdate = true;
|
||||
req.image(LtsUtils::fromPixmap(m_ui->profileButton->pixmap()));
|
||||
}
|
||||
|
||||
if (name != op.name())
|
||||
{
|
||||
bNeedUpdate = true;
|
||||
req.name(name);
|
||||
}
|
||||
|
||||
if (description != op.description())
|
||||
{
|
||||
bNeedUpdate = true;
|
||||
req.description(description);
|
||||
}
|
||||
|
||||
if (m_visiblePartiesChanged)
|
||||
{
|
||||
bNeedUpdate = true;
|
||||
const QVector<int> visiblePartyIds = m_visiblePartiesModel->getCheckedIds();
|
||||
std::vector<OperatorManagement::PartiesByExercise> vpbe;
|
||||
PartiesByExercise pbe;
|
||||
DEBUG_LOG(m_logger) << "----------------- m_session.exerciseId:" << m_session->exerciseId();
|
||||
pbe.exerciseId(0);
|
||||
pbe.visibleParties().set({});
|
||||
std::copy(visiblePartyIds.begin(), visiblePartyIds.end(), std::back_inserter(pbe.visibleParties().get()));
|
||||
vpbe.push_back(pbe);
|
||||
req.visiblePartiesByExercise() = vpbe;
|
||||
}
|
||||
|
||||
if (m_projectionPriorityChanged)
|
||||
{
|
||||
bNeedUpdate = true;
|
||||
req.projectionPriority(m_ui->cbProjectionPriority->currentIndex() + 1);
|
||||
}
|
||||
|
||||
if (m_audioChannelPriorityChanged)
|
||||
{
|
||||
bNeedUpdate = true;
|
||||
req.audioChannelPriority(m_ui->cbAudioChannelPriority->currentIndex() + 1);
|
||||
}
|
||||
|
||||
return bNeedUpdate && operatorCreateModify(req);
|
||||
}
|
||||
else // create new user
|
||||
{
|
||||
OperatorCreateModifyRequest req;
|
||||
req.name(name);
|
||||
req.description(description);
|
||||
req.password(password);
|
||||
req.projectionPriority(dds::core::optional<int16_t>(m_ui->cbProjectionPriority->currentIndex() + 1));
|
||||
req.audioChannelPriority(m_ui->cbAudioChannelPriority->currentIndex() + 1);
|
||||
if (m_pictureChanged)
|
||||
req.image(LtsUtils::fromPixmap(m_ui->profileButton->pixmap()));
|
||||
if (m_visiblePartiesChanged)
|
||||
{
|
||||
const QVector<int> visiblePartyIds = m_visiblePartiesModel->getCheckedIds();
|
||||
std::vector<OperatorManagement::PartiesByExercise> vpbe;
|
||||
PartiesByExercise pbe;
|
||||
DEBUG_LOG (m_logger) << "----------------- m_session.exerciseId:" << m_session->exerciseId();
|
||||
pbe.exerciseId(0);
|
||||
pbe.visibleParties().set({});
|
||||
std::copy(visiblePartyIds.begin(), visiblePartyIds.end(), std::back_inserter(pbe.visibleParties().get()));
|
||||
vpbe.push_back(pbe);
|
||||
req.visiblePartiesByExercise() = vpbe;
|
||||
}
|
||||
req.operatorRights(m_groups);
|
||||
req.rolePresetId(m_presetGroupId);
|
||||
|
||||
return operatorCreateModify(req);
|
||||
}
|
||||
}
|
||||
|
||||
void OperatorEditDialog::onContextMenuRequested(const QPoint &position)
|
||||
{
|
||||
QMenu menu(m_ui->tvVisibleParties);
|
||||
menu.addAction(tr("Select All"), this, &OperatorEditDialog::onSelectAllParties);
|
||||
menu.addAction(tr("Unselect All"), this, &OperatorEditDialog::onUnselectAllParties);
|
||||
menu.exec(m_ui->tvVisibleParties->mapToGlobal(position));
|
||||
}
|
||||
|
||||
void OperatorEditDialog::onSelectAllParties()
|
||||
{
|
||||
m_visiblePartiesModel->selectAll();
|
||||
m_visiblePartiesModel->update();
|
||||
}
|
||||
|
||||
void OperatorEditDialog::onUnselectAllParties()
|
||||
{
|
||||
m_visiblePartiesModel->unselectAll();
|
||||
m_visiblePartiesModel->update();
|
||||
}
|
||||
|
||||
void OperatorEditDialog::createFolders()
|
||||
{
|
||||
// User folder
|
||||
OperatorManagement::User op = m_dtc->user(m_operatorId);
|
||||
QString folderName = QString::fromStdString(op.name());
|
||||
int userId = op.id();
|
||||
|
||||
// check if folder already exists
|
||||
int folderId = m_flmDtc->findFolder(0,folderName);
|
||||
if (folderId > 0)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("User folders already created"));
|
||||
return;
|
||||
}
|
||||
|
||||
// folder does not exists, we create it
|
||||
folderId = createFolder(FileManagement::MainFolder::UserDocuments, folderName, userId);
|
||||
|
||||
if (folderId <= 0)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Could not create user folders"));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "User Folder created with id = " << folderId;
|
||||
|
||||
#ifdef GUEZ_MODE
|
||||
// Sub-folder z.B. AuswtGrp/LtgDst/AusbDst_<username>
|
||||
folderName = QStringLiteral("AuswtGrp/LtgDst/AusbDst_") + folderName ;
|
||||
int subFolderId = createFolder(folderId, folderName, userId);
|
||||
|
||||
if (subFolderId <= 0)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Could not create user sub-folders"));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "User Subfolder created with id = " << subFolderId;
|
||||
#endif
|
||||
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("User folders successfully created"));
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
int OperatorEditDialog::createFolder(int parentFolderId, const QString &folderName, int userId, bool isHidden)
|
||||
{
|
||||
FileManagement::Folder parentFolder = m_flmDtc->folder(parentFolderId);
|
||||
const std::vector<int32_t> &parentPath = parentFolder.path();
|
||||
|
||||
FileManagement::FolderModifyRequest req;
|
||||
req.name(folderName.toStdString());
|
||||
req.path(parentPath);
|
||||
req.isEditable(true);
|
||||
req.isHidden(isHidden);
|
||||
req.parentId(parentFolderId);
|
||||
req.operatorId(userId);
|
||||
|
||||
m_requestHelper->startSingleRequest([this, req]()
|
||||
{
|
||||
return m_flmFtc->folderModifyRequest(req, this);
|
||||
});
|
||||
|
||||
DEBUG_LOG(m_logger) << "Created folder id = " << m_requestHelper->getRepliedId();
|
||||
|
||||
return m_requestHelper->getRepliedId();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManangement - Operator Edit Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OperatorManagement/opm_ftc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <OperatorManagement/logger.h>
|
||||
|
||||
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class OperatorEditDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession {
|
||||
class LtsSession;
|
||||
}
|
||||
namespace OperatorManagement
|
||||
{
|
||||
class OperatorEditVisiblePartiesModel;
|
||||
// --------------------------------------------------------
|
||||
// OperatorManagementEditDialog
|
||||
// --------------------------------------------------------
|
||||
class OperatorEditDialog : public LtsWidgets::LtsDialog
|
||||
, protected OperatorManagement::Interface::Ftc::OperatorCreateModifyReplyHandler
|
||||
, protected OperatorManagement::Interface::Ftc::GroupChangeMembershipsReplyHandler
|
||||
, protected FileManagement::Interface::Ftc::FolderModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OperatorEditDialog(int operatorId,
|
||||
LtsSession::LtsSession *session,
|
||||
const QString &menuGroup,
|
||||
QWidget *parent = nullptr);
|
||||
~OperatorEditDialog();
|
||||
|
||||
|
||||
void onOperatorCreateModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onGroupChangeMembershipsReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onFolderModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
bool apply() override final;
|
||||
int createFolder(int parentFolderId, const QString &folderName, int userId, bool isHidden = false);
|
||||
|
||||
private slots:
|
||||
void showACLs();
|
||||
void showExercises();
|
||||
void slotPasswordChangedClicked();
|
||||
void slotProfileButtonClicked();
|
||||
void onViewPasswordToggled(bool checked);
|
||||
void onNewGroups(const std::vector<int> &groupIds, const int presetGroupId);
|
||||
void onContextMenuRequested(const QPoint &position);
|
||||
void onSelectAllParties();
|
||||
void onUnselectAllParties();
|
||||
void createFolders();
|
||||
|
||||
signals:
|
||||
void sendData(const OperatorManagement::User &data);
|
||||
|
||||
private:
|
||||
int m_operatorId;
|
||||
bool m_pictureChanged;
|
||||
bool m_visiblePartiesChanged;
|
||||
bool m_projectionPriorityChanged;
|
||||
bool m_audioChannelPriorityChanged;
|
||||
std::vector<int> m_groups;
|
||||
int m_presetGroupId;
|
||||
QString m_menuGroup;
|
||||
|
||||
std::vector<int> m_effectiveACls;
|
||||
OperatorEditVisiblePartiesModel *m_visiblePartiesModel;
|
||||
LtsSession::LtsSession *m_session;
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<OperatorManagement::Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<FileManagement::Interface::Dtc> m_flmDtc;
|
||||
std::shared_ptr<FileManagement::Interface::Ftc> m_flmFtc;
|
||||
//std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
|
||||
Ui::OperatorEditDialog *m_ui;
|
||||
LOGGER_T m_logger;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
void getProfilePicture();
|
||||
int clamp(int v, int lower, int upper);
|
||||
bool operatorCreateModify(const OperatorCreateModifyRequest &req);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OperatorEditDialog</class>
|
||||
<widget class="QWidget" name="OperatorEditDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>687</width>
|
||||
<height>571</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Operator Edit</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblOperator">
|
||||
<property name="text">
|
||||
<string>Operator:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="leOperator">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="lblProjectionPriority">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Projection Priority:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="cbProjectionPriority"/>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QPushButton" name="pbACL">
|
||||
<property name="text">
|
||||
<string>Privileges</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5" rowspan="2">
|
||||
<widget class="LtsWidgets::LtsProfileButton" name="profileButton" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblInfo">
|
||||
<property name="text">
|
||||
<string>Info:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="leInfo">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="lblAudioChannelPriority">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Audio Channel Priority:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QComboBox" name="cbAudioChannelPriority">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QPushButton" name="pbExercises">
|
||||
<property name="text">
|
||||
<string>Exercises</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblPassword">
|
||||
<property name="text">
|
||||
<string>New Password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lePassword">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QPushButton" name="pbChangePassword">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Change Password</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblPasswordConfirmation">
|
||||
<property name="text">
|
||||
<string>Confirm Password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="lePasswordConfirmation">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>400</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="QPushButton" name="pbDisplay">
|
||||
<property name="text">
|
||||
<string>Display</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="pbFolders">
|
||||
<property name="text">
|
||||
<string>Create Folders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QVBoxLayout" name="layParties">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblVisibleParties">
|
||||
<property name="text">
|
||||
<string>Available Parties:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="tvVisibleParties" native="true">
|
||||
<property name="showColumnCount" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsProfileButton</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_profile_button.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>leOperator</tabstop>
|
||||
<tabstop>leInfo</tabstop>
|
||||
<tabstop>lePassword</tabstop>
|
||||
<tabstop>lePasswordConfirmation</tabstop>
|
||||
<tabstop>cbProjectionPriority</tabstop>
|
||||
<tabstop>cbAudioChannelPriority</tabstop>
|
||||
<tabstop>pbACL</tabstop>
|
||||
<tabstop>pbExercises</tabstop>
|
||||
<tabstop>pbChangePassword</tabstop>
|
||||
<tabstop>pbDisplay</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManagement - Operator Edit Visible Parties Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Philipp Dassow, SLST, 2019-09-18
|
||||
*/
|
||||
|
||||
#include "operator_edit_visible_parties_model.h"
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
|
||||
OperatorEditVisiblePartiesModel::OperatorEditVisiblePartiesModel(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
int operatorId,
|
||||
QObject *parent)
|
||||
: LtsWidgets::LtsCheckableTableModel<QPair<bool, ParticipantManagement::Party>>({tr("Id"), tr("Name")}, ColName, parent)
|
||||
, m_dtc (dtc)
|
||||
, m_ppmDtc(ppmDtc)
|
||||
, m_operatorId (operatorId)
|
||||
{
|
||||
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::partyChanged,
|
||||
this, &OperatorEditVisiblePartiesModel::onPartiesChanged, Qt::UniqueConnection);
|
||||
|
||||
auto cb = [this](const ParticipantManagement::Party &party)
|
||||
{
|
||||
onPartiesChanged(party, DataModification::eAdded);
|
||||
};
|
||||
m_ppmDtc->partys(cb);
|
||||
}
|
||||
|
||||
OperatorEditVisiblePartiesModel::~OperatorEditVisiblePartiesModel()
|
||||
{
|
||||
}
|
||||
|
||||
QVariant OperatorEditVisiblePartiesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return LtsCheckableTableModel::data(index, role);
|
||||
|
||||
if (!indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const ParticipantManagement::Party &party = m_vecData.at(index.row()).second;
|
||||
switch (index.column())
|
||||
{
|
||||
case ColId:
|
||||
return party.id();
|
||||
case ColName:
|
||||
return ParticipantManagement::trPartyName(party.name());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void OperatorEditVisiblePartiesModel::onPartiesChanged(const ParticipantManagement::Party &data, DataModification mod)
|
||||
{
|
||||
switch(mod)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
{
|
||||
insertRow(qMakePair(hasParty(data), data));
|
||||
break;
|
||||
}
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
for (int i = 0; i < m_vecData.size(); ++i)
|
||||
{
|
||||
if (m_vecData.at(i).second.id() == data.id())
|
||||
{
|
||||
removeRow(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataModification::eModified:
|
||||
{
|
||||
for (int i = 0; i < m_vecData.size(); ++i)
|
||||
{
|
||||
if (m_vecData.at(i).second.id() == data.id())
|
||||
{
|
||||
m_vecData[i].second = data;
|
||||
const QModelIndex idx(index(i, ColName, QModelIndex()));
|
||||
emit dataChanged(idx, idx, {Qt::DisplayRole});
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OperatorEditVisiblePartiesModel::hasParty(const ParticipantManagement::Party &party) const
|
||||
{
|
||||
const auto visiblePartiesByExercise = m_dtc->user(m_operatorId).visiblePartiesByExercise();
|
||||
|
||||
for (const auto &exerciseParties : visiblePartiesByExercise)
|
||||
{
|
||||
if (exerciseParties.exerciseId() != 0)
|
||||
continue;
|
||||
// Now we are definetelay in exId == 0 --> Template!
|
||||
if (!exerciseParties.visibleParties().is_set()) //has_value not support on windows yet so we need depricated is_set
|
||||
return false;
|
||||
for (const auto &partyId : exerciseParties.visibleParties().get())
|
||||
if (partyId == party.id())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* OperatorManagement - Operator Edit Visible Parties Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Philipp Dassow, SLST, 2019-09-18
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/OperatorManagement/Data/opm_data_plugin.h>
|
||||
#include <Plugins/ParticipantManagement/Data/ppm_data_plugin.h>
|
||||
|
||||
#include <LtsWidgets/lts_checkable_table_model.h>
|
||||
|
||||
#include <QPair>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
class OperatorEditVisiblePartiesModel : public LtsWidgets::LtsCheckableTableModel<QPair<bool, ParticipantManagement::Party>>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
ColId,
|
||||
ColName
|
||||
};
|
||||
|
||||
explicit OperatorEditVisiblePartiesModel(const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
int operatorId = 0,
|
||||
QObject *parent = nullptr);
|
||||
~OperatorEditVisiblePartiesModel();
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
public slots:
|
||||
void onPartiesChanged(const ParticipantManagement::Party &data, DataModification mod);
|
||||
|
||||
private:
|
||||
bool hasParty(const ParticipantManagement::Party &party) const;
|
||||
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
int m_operatorId;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for OperatorManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "opm_edit_gui_plugin.h"
|
||||
|
||||
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
|
||||
#include "operator_dialog.h"
|
||||
#include "acl_dialog.h"
|
||||
#include "preset_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <Services/OperatorManagement/opm_operator_rights.h>
|
||||
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Opm.Edit"))
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<OperatorManagement::DataInterface>(m_dtc))
|
||||
return false;
|
||||
if (!m_session->getFtc<OperatorManagement::DataInterface>(m_ftc))
|
||||
return false;
|
||||
|
||||
// Todo: Check if necessary
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc;
|
||||
if (!m_session->getDtc<ParticipantManagement::DataInterface>(ppmDtc))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
|
||||
LtsWidgets::PluginData plData;
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Operators");
|
||||
plData.identifier = QLatin1String("opmOperatorEdit");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:list-add-user.svg"));
|
||||
plData.operatorRight = OperatorRights::OperatorsEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget *parent)
|
||||
{
|
||||
return onShowOperatorDialog(parent);
|
||||
};
|
||||
ret.append(plData);
|
||||
|
||||
plData.menuText = tr("Presets");
|
||||
plData.identifier = QLatin1String("opmGroupEdit");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:operator_rights.svg"));
|
||||
plData.closable = true;
|
||||
plData.operatorRight = OperatorRights::GroupEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget *parent)
|
||||
{
|
||||
return onShowGroupDialog(parent, false);
|
||||
};
|
||||
ret.append(plData);
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
plData.menuText = tr("Show ACLs");
|
||||
plData.identifier = QLatin1String("openShowAcls");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:access_rights.svg"));
|
||||
plData.closable = true;
|
||||
plData.operatorRight = OperatorRights::GroupShow;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget *parent)
|
||||
{
|
||||
return onShowAclDialog(parent);
|
||||
};
|
||||
// ret.append(plData);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//private
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowOperatorDialog(QWidget *parent)
|
||||
{
|
||||
OperatorDialog *dialog = new OperatorDialog(menuGroup(), parent);
|
||||
dialog->init(m_session);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowGroupDialog(QWidget *parent, bool hideHidden)
|
||||
{
|
||||
PresetDialog *dialog = new PresetDialog(menuGroup(), parent);
|
||||
dialog->init(m_dtc, m_ftc, hideHidden);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowAclDialog(QWidget *parent)
|
||||
{
|
||||
AclDialog *dialog = new AclDialog(parent);
|
||||
dialog->init(m_dtc, m_ftc);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
} //namespace OperatorManagement
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for OperatorManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <OperatorManagement/logger.h>
|
||||
#include <OperatorManagement/opm_ftc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/OperatorManagement/opm_gui_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:opm")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QLatin1String("OperatorManagementGuiPlugin"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return partition == IDL::PartitionType::Global;
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public QObject, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
bool fetchInterfaces() override;
|
||||
QString menuGroup() const override { return tr("Operators"); }
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override { return partition == IDL::PartitionType::Global; } // global only, not in exercise mode
|
||||
|
||||
private:
|
||||
LtsWidgets::LtsDialog *onShowOperatorDialog(QWidget *parent);
|
||||
LtsWidgets::LtsDialog *onShowGroupDialog(QWidget *parent, bool hideHidden = true);
|
||||
LtsWidgets::LtsDialog *onShowAclDialog(QWidget *parent);
|
||||
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<OperatorManagement::Interface::Ftc> m_ftc;
|
||||
};
|
||||
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManangement - Group Overview Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "preset_dialog.h"
|
||||
#include "ui_preset_dialog.h"
|
||||
|
||||
#include "group_edit_dialog.h"
|
||||
#include "CustomViews/opm_group.h"
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
PresetDialog::PresetDialog(const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_model(nullptr)
|
||||
, m_ui(new Ui::PresetDialog)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_logger(getLogger("PresetDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &PresetDialog::onAddGroup);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &PresetDialog::onEditGroup);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &PresetDialog::onRemoveGroup);
|
||||
|
||||
connect(m_ui->widget, &LtsDataView::LtsDataView::signalDoubleClicked, this, &PresetDialog::onEditGroup);
|
||||
connect(m_ui->widget, &LtsDataView::LtsDataView::signalEnterPressed, this, &PresetDialog::onEditGroup);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Administrator-Presets"));
|
||||
}
|
||||
|
||||
PresetDialog::~PresetDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void PresetDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Presets"));
|
||||
}
|
||||
|
||||
void PresetDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->widget->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
bool PresetDialog::init(const std::shared_ptr<OperatorManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Ftc> &ftc,
|
||||
bool hideHidden)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
|
||||
m_model = new GroupModel(this);
|
||||
m_model->initModel(dtc, hideHidden);
|
||||
m_ui->widget->setModel(m_model, [this]() { return new CustomViewGroup(this); });
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->widget->setColumnHidden(GroupModel::Id, true);
|
||||
#endif
|
||||
connect(m_ui->widget, &LtsDataView::LtsDataView::signalSelectionChanged,
|
||||
this, &PresetDialog::enaDisa);
|
||||
|
||||
enaDisa();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PresetDialog::enaDisa()
|
||||
{
|
||||
QModelIndexList selectedRows = m_ui->widget->selectedRows();
|
||||
const int cntSelectedRows = selectedRows.size();
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, cntSelectedRows == 1 );
|
||||
|
||||
bool deletable = cntSelectedRows > 0 &&
|
||||
(m_model->getRowData(selectedRows.at(0).row()).type() == GroupType_def::PresetGroup);
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, deletable );
|
||||
}
|
||||
|
||||
void PresetDialog::onRemoveGroup()
|
||||
{
|
||||
QModelIndex idx = m_ui->widget->currentIndex();
|
||||
Core::RemoveElementRequest req(m_model->getRowData(idx.row()).id());
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->groupRemoveRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
void PresetDialog::onAddGroup()
|
||||
{
|
||||
GroupEditDialog *dialog = new GroupEditDialog(this);
|
||||
Group grp;
|
||||
grp.type(GroupType_def::PresetGroup);
|
||||
dialog->init(grp, m_dtc, m_ftc);
|
||||
|
||||
addDialog(dialog, m_menuGroup, QLatin1String("NewPreset"), LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
|
||||
void PresetDialog::onEditGroup()
|
||||
{
|
||||
const QModelIndex idx = m_ui->widget->currentIndex();
|
||||
const OperatorManagement::Group group = m_model->getRowData(idx.row());
|
||||
|
||||
if (group.id() <= 0)
|
||||
return;
|
||||
|
||||
GroupEditDialog *dialog = new GroupEditDialog(this);
|
||||
dialog->init(group, m_dtc, m_ftc);
|
||||
const QString identifier = QLatin1String("editPreset") + QString::number(group.id());
|
||||
|
||||
addDialog(dialog, m_menuGroup, identifier, LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for OperatorManagement - Group Overview Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "group_model.h"
|
||||
|
||||
#include <OperatorManagement/opm_ftc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <OperatorManagement/logger.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class PresetDialog;
|
||||
}
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
|
||||
class PresetDialog : public LtsWidgets::LtsDialog
|
||||
, protected OperatorManagement::Interface::Ftc::GroupRemoveReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PresetDialog(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~PresetDialog();
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
bool hideHidden = true);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void onGroupRemoveReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
QString m_menuGroup;
|
||||
GroupModel *m_model;
|
||||
Ui::PresetDialog *m_ui;
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<OperatorManagement::Interface::Ftc> m_ftc;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
private slots:
|
||||
void enaDisa();
|
||||
void onRemoveGroup();
|
||||
void onAddGroup();
|
||||
void onEditGroup();
|
||||
};
|
||||
|
||||
} // namespace OperatorManagement
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>PresetDialog</class>
|
||||
<widget class="QWidget" name="PresetDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>674</width>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Group Edit</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="widget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Reference in new issue
Block a user