436 lines
14 KiB
C++
436 lines
14 KiB
C++
#include <QStandardItemModel>
|
||
#include <QMenu>
|
||
#include <QUuid>
|
||
#include "diagramView.h"
|
||
#include "ui_diagramView.h"
|
||
#include "tools.h"
|
||
#include "topologyManager.h"
|
||
#include "projectManager.h"
|
||
#include "dataBase.h"
|
||
#include <QMessageBox>
|
||
|
||
DiagramView::DiagramView(QWidget *parent)
|
||
: QDialog(parent)
|
||
, ui(new Ui::diagramView)
|
||
,_pModel(nullptr)
|
||
{
|
||
ui->setupUi(this);
|
||
_pModel = new QStandardItemModel(this);
|
||
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||
ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
|
||
_count = 0;
|
||
}
|
||
|
||
DiagramView::~DiagramView()
|
||
{
|
||
delete ui;
|
||
}
|
||
|
||
void DiagramView::initial()
|
||
{
|
||
connect(ui->treeView, &QTreeView::customContextMenuRequested, this, &DiagramView::onIndexRbtnClicked);
|
||
connect(ui->treeWidget, &QTreeView::customContextMenuRequested, this, &DiagramView::onEditorRbtnClicked);
|
||
connect(ui->treeView, &QTreeView::clicked, this, &DiagramView::onItemClicked);
|
||
connect(_pModel, &QStandardItemModel::itemChanged, this, &DiagramView::onItemChanged);
|
||
connect(ui->btn_new, &QPushButton::clicked, this, &DiagramView::onNewEditorClicked);
|
||
connect(ui->btn_open, &QPushButton::clicked, this, &DiagramView::onOpenEditorClicked);
|
||
connect(ui->btn_save, &QPushButton::clicked, this, &DiagramView::onSaveEditorClicked);
|
||
connect(&ProjectManager::instance(),&ProjectManager::createNewEditor,this,&DiagramView::onNewEditorCreated);
|
||
connect(&ProjectManager::instance(),&ProjectManager::editorSaved,this,&DiagramView::onEditorSaved);
|
||
connect(ui->treeWidget, &QTreeWidget::itemDoubleClicked, this, &DiagramView::onEditorDBClicked);
|
||
ui->treeView->setHeaderHidden(true);
|
||
ui->treeWidget->setHeaderHidden(true);
|
||
// 设置模型的列数
|
||
_pModel->setColumnCount(1);
|
||
|
||
//QList<QStandardItem*> pageList;
|
||
QList<PageInfo> lst = DataBase::GetInstance()->getAllPage();
|
||
for(auto info:lst)
|
||
{
|
||
QStandardItem* pItem = new QStandardItem(info.name);
|
||
pItem->setData(info.id,Qt::UserRole);
|
||
//pageList.append(pItem);
|
||
_pModel->appendRow(pItem);
|
||
}
|
||
//_pModel->appendRow(pageList);
|
||
|
||
// 创建树视图
|
||
ui->treeView->setModel(_pModel);
|
||
|
||
// 展开所有节点
|
||
ui->treeView->expandAll();
|
||
// 显示树视图
|
||
//ui->treeView->setWindowTitle(QObject::tr("组态图结构"));
|
||
}
|
||
|
||
void DiagramView::loadTopologyFromDB()
|
||
{
|
||
|
||
}
|
||
|
||
void DiagramView::clearProjectTree()
|
||
{
|
||
ui->treeWidget->clear();
|
||
}
|
||
|
||
bool DiagramView::projectExist()
|
||
{
|
||
for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) {
|
||
if (ui->treeWidget->topLevelItem(i)->columnCount() > 0) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void DiagramView::onIndexRbtnClicked(const QPoint &pos)
|
||
{
|
||
// 获取当前点击的位置对应的索引
|
||
QMenu menu;
|
||
QModelIndex index = ui->treeView->indexAt(pos);
|
||
if (!index.isValid()) {
|
||
// 如果点击的是空白区域,创建新组态图菜单
|
||
|
||
/* QAction *addAction = new QAction("添加组态图", this);
|
||
|
||
connect(addAction,&QAction::triggered,this,[&](){
|
||
QVariant id = QUuid::createUuid();
|
||
|
||
QString sName = generateName();
|
||
QStandardItem *item = new QStandardItem(sName);
|
||
item->setData(id,Qt::UserRole+1);
|
||
_pModel->appendRow(item);
|
||
|
||
DiagramInfo info;
|
||
//todo:具体信息
|
||
info.id = id; //新建的组态图随机赋予临时id
|
||
info.sName = sName;
|
||
info.sTag = sName;
|
||
emit diagramCreate(info);
|
||
});
|
||
|
||
menu.addAction(addAction);*/
|
||
}
|
||
else{ //目标组态图下添加子组态图
|
||
QStandardItem* item = _pModel->itemFromIndex(index);
|
||
QVariant parentId = item->data(Qt::UserRole+1);
|
||
|
||
if(item)
|
||
{
|
||
/*QAction *addAction = new QAction("添加子组态图", this);
|
||
|
||
connect(addAction,&QAction::triggered,this,[&](){
|
||
QVariant id = QUuid::createUuid();
|
||
|
||
QString sName = generateName();
|
||
QStandardItem *item = new QStandardItem(sName);
|
||
item->setData(id,Qt::UserRole+1);
|
||
item->appendRow(item);
|
||
|
||
DiagramInfo info;
|
||
//todo:具体信息
|
||
info.id = id; //新建的随机赋予临时id
|
||
info.sName = sName;
|
||
info.sTag = sName;
|
||
info.parentId = parentId;
|
||
emit diagramCreate(info);
|
||
});
|
||
|
||
menu.addAction(addAction);*/
|
||
|
||
|
||
QAction *delAction = new QAction("删除", this);
|
||
connect(delAction,&QAction::triggered,this,[&](){
|
||
QModelIndex currentIndex = ui->treeView->currentIndex();
|
||
if(currentIndex.isValid())
|
||
{
|
||
QStandardItem* pItem = _pModel->itemFromIndex(currentIndex);
|
||
QVariant id = pItem->data(Qt::UserRole+1);
|
||
QString sName = pItem->text();
|
||
if(pItem)
|
||
{
|
||
QString str = item->text();
|
||
DiagramInfo info;
|
||
//todo:具体信息
|
||
info.id = id; //新建的随机赋予临时id
|
||
info.sName = sName;
|
||
info.sTag = sName;
|
||
info.parentId = parentId;
|
||
emit diagramDelete(info);
|
||
|
||
QStandardItem* pParent = item->parent();
|
||
if(pParent)
|
||
{
|
||
pParent->removeRow(currentIndex.row());
|
||
}
|
||
}
|
||
}
|
||
});
|
||
menu.addAction(delAction);
|
||
}
|
||
}
|
||
|
||
// 在点击位置显示菜单
|
||
menu.exec(ui->treeView->mapToGlobal(pos));
|
||
}
|
||
|
||
void DiagramView::onItemChanged(QStandardItem *item)
|
||
{
|
||
int nLevel = getLevel(item);
|
||
QString str = item->text(); //名称可能修改
|
||
DiagramInfo info;
|
||
info.id = item->data(Qt::UserRole).toInt();
|
||
info.sName = str;
|
||
emit diagramChange(info);
|
||
}
|
||
|
||
void DiagramView::onItemClicked(const QModelIndex &index)
|
||
{
|
||
QStandardItem* item = _pModel->itemFromIndex(index);
|
||
QStandardItem* parent = item->parent();
|
||
if(item)
|
||
{
|
||
DiagramInfo info;
|
||
info.id = item->data(Qt::UserRole).toInt();
|
||
info.sName = item->text();
|
||
if(parent)
|
||
info.parentId = parent->data(Qt::UserRole).toInt();
|
||
emit diagramSelected(info);
|
||
}
|
||
}
|
||
|
||
void DiagramView::onPageSaved(const QString sPage,int id)
|
||
{
|
||
for (int row = 0; row < _pModel->rowCount(); ++row) {
|
||
QStandardItem *item = _pModel->item(row, 0);
|
||
if (item && item->data(Qt::DisplayRole) == sPage) {
|
||
QStandardItem* pItem = new QStandardItem(sPage);
|
||
pItem->setData(id,Qt::UserRole);
|
||
_pModel->appendRow(pItem);
|
||
}
|
||
}
|
||
}
|
||
|
||
void DiagramView::onEditorRbtnClicked(const QPoint &pos)
|
||
{
|
||
QTreeWidgetItem *item = ui->treeWidget->itemAt(pos);
|
||
if (!item) return;
|
||
|
||
int level = getItemLevel(item);
|
||
|
||
QMenu menu(this);
|
||
|
||
switch (level) {
|
||
case 1:{ // 顶级节点
|
||
QAction *actUnload = menu.addAction("卸载项目");
|
||
|
||
QAction *act = menu.exec(ui->treeWidget->mapToGlobal(pos));
|
||
if(act == actUnload){
|
||
ProjectManager::instance().unloadEditorProject(item->text(0));
|
||
ui->treeWidget->clear();
|
||
}
|
||
}
|
||
break;
|
||
case 2:{ // 二级节点
|
||
}
|
||
break;
|
||
case 3:{ // 三级节点
|
||
QAction *actOpenSetting = menu.addAction("打开设置");
|
||
QAction *actSaveTop = menu.addAction("保存");
|
||
//QAction *actGenTop = menu.addAction("生成");
|
||
menu.addSeparator();
|
||
QAction *actDelTop = menu.addAction("删除");
|
||
|
||
QAction *act = menu.exec(ui->treeWidget->mapToGlobal(pos));
|
||
if(act == actOpenSetting){
|
||
ProjectManager::instance().openSetting(item->text(0));
|
||
}
|
||
else if(act == actSaveTop){
|
||
ProjectManager::instance().saveEditor(item->text(0));
|
||
}
|
||
/*else if(act == actGenTop){
|
||
|
||
}*/
|
||
else if(act == actDelTop){
|
||
QMessageBox msgBox;
|
||
msgBox.setText(QString::fromWCharArray(L"提示"));
|
||
msgBox.setInformativeText(QString::fromWCharArray(L"确认删除?"));
|
||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||
msgBox.setDefaultButton(QMessageBox::Cancel);
|
||
int ret = msgBox.exec();
|
||
|
||
switch (ret) {
|
||
case QMessageBox::Ok:
|
||
{
|
||
bool res = ProjectManager::instance().deleteEditor(item->text(0),item->data(0,Qt::UserRole).toUuid());
|
||
delete item;
|
||
QString str;
|
||
if(res)
|
||
str = "删除成功";
|
||
else
|
||
str = "删除失败";
|
||
QMessageBox::information(NULL, QString("提示"), str);
|
||
}
|
||
break;
|
||
case QMessageBox::Cancel:
|
||
// Cancel was clicked
|
||
default:
|
||
// should never be reached
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
void DiagramView::onEditorDBClicked(QTreeWidgetItem* item, int column)
|
||
{
|
||
int level = getItemLevel(item);
|
||
if(level == 3){
|
||
auto pAuthor = item->parent();
|
||
auto pProject = pAuthor->parent();
|
||
ProjectManager::instance().loadBaseSetting(item->text(0),item->data(0,Qt::UserRole).toUuid());
|
||
}
|
||
}
|
||
|
||
void DiagramView::onNewEditorCreated(const QString& str,QUuid id)
|
||
{
|
||
ui->treeWidget->clear();
|
||
QTreeWidgetItem *topLevelItem = new QTreeWidgetItem(ui->treeWidget);
|
||
topLevelItem->setText(0, str);
|
||
topLevelItem->setData(0,Qt::UserRole,id);
|
||
}
|
||
|
||
void DiagramView::onEditorLoaded(const QString& str,QUuid id)
|
||
{
|
||
ui->treeWidget->clear();
|
||
QTreeWidgetItem *topLevelItem = new QTreeWidgetItem(ui->treeWidget);
|
||
topLevelItem->setText(0, str);
|
||
topLevelItem->setData(0,Qt::UserRole,id);
|
||
auto lstInfo = ProjectManager::instance().getBaseSettingsByProject(str);
|
||
|
||
for(auto &info:lstInfo){
|
||
bool authorCreated = false;
|
||
for (int j = 0; j < topLevelItem->childCount(); ++j) {
|
||
QTreeWidgetItem* authorItem = topLevelItem->child(j);
|
||
if(authorItem->text(0) == info.autor){ //author存在
|
||
QTreeWidgetItem* settingItem = new QTreeWidgetItem(authorItem);
|
||
settingItem->setText(0,info.ts);
|
||
settingItem->setData(0,Qt::UserRole,info.uuid);
|
||
authorCreated = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(!authorCreated){ //新建author
|
||
QTreeWidgetItem* authorItem = new QTreeWidgetItem(topLevelItem);
|
||
authorItem->setText(0,info.autor);
|
||
|
||
QTreeWidgetItem* settingItem = new QTreeWidgetItem(authorItem);
|
||
settingItem->setText(0,info.ts);
|
||
settingItem->setData(0,Qt::UserRole,info.uuid);
|
||
}
|
||
}
|
||
ui->treeWidget->expandAll();
|
||
}
|
||
|
||
void DiagramView::onEditorSaved(const QString& strPro,const QString& autor,QUuid uid,QString sTime)
|
||
{
|
||
for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i) {
|
||
QTreeWidgetItem* topItem = ui->treeWidget->topLevelItem(i);
|
||
if(topItem->text(0) == strPro){ //在指定项目下添加
|
||
// 遍历子项
|
||
bool exist = false; //名称已存在
|
||
for (int j = 0; j < topItem->childCount(); ++j) {
|
||
QTreeWidgetItem* childItem = topItem->child(j);
|
||
if(childItem->text(0) == autor){
|
||
exist = true;
|
||
QTreeWidgetItem *pItem = new QTreeWidgetItem(childItem);
|
||
pItem->setText(0, sTime);
|
||
pItem->setData(0,Qt::UserRole,uid);
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(!exist){
|
||
QTreeWidgetItem *itemName = new QTreeWidgetItem(topItem);
|
||
itemName->setText(0, autor);
|
||
QTreeWidgetItem *pItem = new QTreeWidgetItem(itemName);
|
||
pItem->setText(0, sTime);
|
||
pItem->setData(0,Qt::UserRole,uid);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void DiagramView::onPanelActive(QString target,int nType)
|
||
{
|
||
if(nType == 0){
|
||
for (int i = 0; i < ui->treeWidget->topLevelItemCount(); ++i)
|
||
{
|
||
QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i);
|
||
searchAndSelect(item, target);
|
||
}
|
||
}
|
||
}
|
||
|
||
void DiagramView::onNewEditorClicked()
|
||
{
|
||
emit createProject();
|
||
}
|
||
|
||
void DiagramView::onOpenEditorClicked()
|
||
{
|
||
emit loadProject();
|
||
}
|
||
|
||
void DiagramView::onSaveEditorClicked()
|
||
{
|
||
ProjectManager::instance().saveEditor("currentPage");
|
||
}
|
||
|
||
QString DiagramView::generateName()
|
||
{
|
||
QString sName = QString::fromWCharArray(L"组态图_")+QString::number(_count);
|
||
QModelIndex Idx = findIndex(_pModel,sName);
|
||
if(Idx.isValid()) //已存在
|
||
{
|
||
_count += 1;
|
||
return generateName();
|
||
}
|
||
else {
|
||
return sName;
|
||
}
|
||
}
|
||
|
||
int DiagramView::getItemLevel(QTreeWidgetItem *item) {
|
||
int level = 0;
|
||
while (item->parent()) {
|
||
level++;
|
||
item = item->parent();
|
||
}
|
||
return level + 1; // 顶级节点为1级
|
||
}
|
||
|
||
// 递归查找并选中
|
||
void DiagramView::searchAndSelect(QTreeWidgetItem *item, const QString &target)
|
||
{
|
||
if (!item)
|
||
return;
|
||
|
||
// 判断当前节点 text(第 0 列)
|
||
if (item->text(0) == target)
|
||
{
|
||
item->setSelected(true); // 选中
|
||
item->setExpanded(true); // 可选:展开父节点
|
||
item->treeWidget()->setCurrentItem(item); // 设为当前项
|
||
}
|
||
|
||
// 递归子节点
|
||
for (int i = 0; i < item->childCount(); ++i)
|
||
{
|
||
searchAndSelect(item->child(i), target);
|
||
}
|
||
}
|